Skip to content

Commit

Permalink
Fix some compatibility issues with C++17 and later
Browse files Browse the repository at this point in the history
  • Loading branch information
lczech committed Sep 17, 2024
1 parent 88a2744 commit 5b34206
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 19 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ else ()
ENDIF()
endif ()

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mbmi2 ${WARN_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARN_FLAGS}")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2 -DDEBUG -g -ggdb3 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG")

Expand Down
11 changes: 9 additions & 2 deletions lib/genesis/placement/simulator/distributions.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Genesis - A toolkit for working with phylogenetic data.
Copyright (C) 2014-2019 Lucas Czech and HITS gGmbH
Copyright (C) 2014-2024 Lucas Czech
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -38,6 +38,7 @@
#include <algorithm>
#include <cassert>
#include <numeric>
#include <random>
#include <stdexcept>

namespace genesis {
Expand Down Expand Up @@ -127,13 +128,19 @@ std::vector<size_t> SimulatorExtraPlacementDistribution::generate( PlacementTree
return result;
}

// Set up a random engine. Proably should use the global seed, but well, good enough for now.
std::random_device rd;
std::default_random_engine rng(rd());

// We make sure that an edge gets at most one placement per pquery by maintaining a list of
// possible candidate edges that do not have a placement (for this pquery) yet.
// For this, get a list of all possible candidates of neighbouring edges of the given edge.
// We shuffle them so that we take different edges for every pquery.
auto edge_prox = edge_proximities_[ edge.index() ];
for( auto& candidates : edge_prox.candidates_per_level ) {
std::random_shuffle( candidates.begin() , candidates.end() );
// Update for C++17 and later:
// std::random_shuffle( candidates.begin() , candidates.end() );
std::shuffle( candidates.begin(), candidates.end(), rng );
}

// We can only place as many placements as there are neighbouring edges.
Expand Down
13 changes: 8 additions & 5 deletions lib/genesis/utils/containers/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/*
Genesis - A toolkit for working with phylogenetic data.
Copyright (C) 2014-2022 Lucas Czech
Copyright (C) 2014-2024 Lucas Czech
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -89,10 +89,13 @@
# define GENESIS_OPTIONAL_HAVE_STD_OPTIONAL 0
#endif

// Use C++17 std::optional if available and requested:
// Currently, we default to using std::optional if it is available.
// Might make this configurable in the future.
#define GENESIS_OPTIONAL_USES_STD_OPTIONAL GENESIS_OPTIONAL_HAVE_STD_OPTIONAL
// We offer a switch to use C++17 std::optional if available and requested.
// However, this currently is not working under MacOS with GCC,
// where somehow our test case Containers.OptionalObservers triggers an assertion
// of std::optional to fail... So we just keep using our implementation for now,
// and decativate to offer using std::optional.
// #define GENESIS_OPTIONAL_USES_STD_OPTIONAL GENESIS_OPTIONAL_HAVE_STD_OPTIONAL
#define GENESIS_OPTIONAL_USES_STD_OPTIONAL 0

// =================================================================================================
// Using std::optional
Expand Down
4 changes: 2 additions & 2 deletions lib/genesis/utils/formats/json/iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/*
Genesis - A toolkit for working with phylogenetic data.
Copyright (C) 2014-2017 Lucas Czech
Copyright (C) 2014-2024 Lucas Czech
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -99,7 +99,7 @@ namespace utils {
* @link supplement_acknowledgements_code_reuse_json_document Acknowledgements@endlink.
*/
template<typename U>
class JsonIterator : public std::iterator<std::random_access_iterator_tag, U>
class JsonIterator // : public std::iterator<std::random_access_iterator_tag, U>
{
// -------------------------------------------------------------------------
// Friends and Asserts
Expand Down
15 changes: 10 additions & 5 deletions lib/genesis/utils/io/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@
#include <stdexcept>

// For C++17, we have a little speedup in the integer parsing part.
// Not avaiable on GCC < 8 though, so we need an additional check here...
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
#if defined( __has_include ) && __has_include(<charconv>)
#define GENESIS_COMPILER_HAS_CHARCONV
#endif
#endif

#ifdef GENESIS_COMPILER_HAS_CHARCONV
#include <charconv>

#endif

namespace genesis {
Expand Down Expand Up @@ -323,8 +328,8 @@ size_t parse_unsigned_integer_from_chars_( utils::InputStream& source )
// parse_unsigned_integer_std_from_chars_
// -------------------------------------------------------------------------

// Only use C++17 code if we are compiled with that version.
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
// Only use C++17 code if we are compiled with that version and charconv support.
#ifdef GENESIS_COMPILER_HAS_CHARCONV

/**
* @brief Another speedup technique using std::from_chars(),
Expand Down Expand Up @@ -389,7 +394,7 @@ size_t parse_unsigned_integer_std_from_chars_( utils::InputStream& source )
return x;
}

#endif // ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
#endif // GENESIS_COMPILER_HAS_CHARCONV

// -------------------------------------------------------------------------
// parse_unsigned_integer_naive_
Expand Down Expand Up @@ -458,7 +463,7 @@ size_t parse_unsigned_integer_size_t( utils::InputStream& source )
// If we have GCC or Clang, use our own handcrafted fast-as-hell implementation.
return parse_unsigned_integer_gcc_intrinsic_( source );

// #elif ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
// #elif GENESIS_COMPILER_HAS_CHARCONV
//
// // Otherwise, if this is C++17, at least use its own fast version,
// // that can use some compiler intrinsics itself.
Expand Down
6 changes: 4 additions & 2 deletions lib/genesis/utils/threading/thread_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,11 @@ class ThreadPool
*/
template<class F, class... Args>
auto enqueue_and_retrieve( F&& f, Args&&... args )
-> ProactiveFuture<typename std::result_of<F(Args...)>::type>
-> ProactiveFuture<typename std::invoke_result<F, Args...>::type>
{
using result_type = typename std::result_of<F(Args...)>::type;
// Updated for C++17 and later:
// using result_type = typename std::result_of<F(Args...)>::type;
using result_type = typename std::invoke_result<F, Args...>::type;

// Make sure that we do not enqueue more tasks than the max size.
run_tasks_until_below_max_queue_size_();
Expand Down
7 changes: 5 additions & 2 deletions tools/cmake/DetectCppVersion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ set(CPP_VERSIONS_AND_FLAGS

# Function to detect the highest available C++ standard
function(detect_highest_cpp_version HIGHEST_SUPPORTED_CXX_VERSION)
# Create a minimal C++ source code snippet for testing
# Create a minimal C++ source code snippet for testing.
# We also include the chrono header here as a super ugly ad-hoc patch for a clang bug,
# which occurs with that header and clang 10 to 14, see
# https://stackoverflow.com/a/63985023/4184258
file(
WRITE "${CMAKE_BINARY_DIR}/test_cpp_version.cpp"
"#include <iostream>\nint main() { std::cout << \"C++ version check\" << std::endl; return 0; }\n"
"#include <iostream>\n#include <chrono>\nint main() { std::cout << \"C++ version check\" << std::endl; return 0; }\n"
)

# Iterate over the list of C++ versions and their corresponding and check if it is supported
Expand Down

0 comments on commit 5b34206

Please sign in to comment.