diff --git a/CMakeLists.txt b/CMakeLists.txt index bd9ca03b..6da54029 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,15 @@ endif() if(NOT CMAKE_EXE_LINKER_FLAGS OR NOT DEFINED CMAKE_EXE_LINKER_FLAGS) set(CMAKE_EXE_LINKER_FLAGS "$ENV{LDFLAGS}") endif() + +# Detect libc++ linker mismatch (e.g. Homebrew LLVM headers vs system libc++) +include(CheckCXXFeatures) +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + vgkit_check_libcxx_linker_mismatch(MODIFY_GLOBAL_FLAGS) +else() + vgkit_check_libcxx_linker_mismatch() +endif() + if (NOT CMAKE_CXX_COMPILER) message(FATAL_ERROR "C++ compiler not found") endif() @@ -122,15 +131,15 @@ endif() set(CMAKE_SKIP_RPATH FALSE) ########################## -# We use C++17 features +# We use C++20 features ########################## # but insist on strict standard -set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ ISO Standard version") -if (NOT(CMAKE_CXX_STANDARD EQUAL 17 OR CMAKE_CXX_STANDARD EQUAL 20)) - message(FATAL_ERROR "C++ 2017 ISO Standard or higher is required to compile BTAS") +set(CMAKE_CXX_STANDARD 20 CACHE STRING "C++ ISO Standard version") +if (CMAKE_CXX_STANDARD LESS 20) + message(FATAL_ERROR "C++ 2020 ISO Standard or higher is required to compile BTAS") endif() # C++20 is only configurable via compile features with cmake 3.12 and older -if (CMAKE_CXX_STANDARD EQUAL 20 AND CMAKE_VERSION VERSION_LESS 3.12.0) +if (CMAKE_VERSION VERSION_LESS 3.12.0) cmake_minimum_required (VERSION 3.12.0) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -145,7 +154,7 @@ check_type_size("long long" BTAS_HAS_LONG_LONG) # create exportable BTAS library target ####################################### add_library(BTAS INTERFACE) -target_compile_features(BTAS INTERFACE "cxx_std_17") +target_compile_features(BTAS INTERFACE "cxx_std_20") target_include_directories(BTAS INTERFACE $ $) install(TARGETS BTAS EXPORT btas COMPONENT BTAS) diff --git a/README.md b/README.md index e424fab1..d4a92252 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Basic Tensor Algebra Subroutines (BTAS) is a C++ library for tensor algebra. BTA Prerequisites ============= -* C++17 compiler +* C++20 compiler * CMake * Boost C++ libraries - (required) Container, Iterator, Random diff --git a/btas/array_adaptor.h b/btas/array_adaptor.h index fb314e0d..bd48d70f 100644 --- a/btas/array_adaptor.h +++ b/btas/array_adaptor.h @@ -156,119 +156,6 @@ namespace btas { } -namespace std { - -#if __cplusplus < 201402L // add C++14 components to make transition to C++14 easier - template - const T* cbegin(const T(&x)[N]) { - return &x[0]; - } - template - const T* cend(const T(&x)[N]) { - return &x[N]; - } - template - const T* rbegin(T(&x)[N]) { - return &x[N-1]; - } - template - const T* rend(T(&x)[N]) { - return &x[0] - 1; - } - - template - const T* cbegin(const T* x) { - return x; - } - template - const T* cbegin(T* x) { - return x; - } - template - T* begin(T* x) { - return x; - } - - template - constexpr auto cbegin(const C& x) -> decltype(std::begin(x)) { - return std::begin(x); - } - template - constexpr auto cend(const C& x) -> decltype(std::end(x)) { - return std::end(x); - } - template - auto rbegin(C& x) -> decltype(x.rbegin()) { - return x.rbegin(); - } - template - auto rend(C& x) -> decltype(x.rend()) { - return x.rend(); - } -#endif - -#if __cplusplus <= 201402L // add useful bits to make transition to C++17 easier - template ().data())>::value>::type* = nullptr> - constexpr auto data(C& c) -> decltype(c.data()) { - return c.data(); - } - template ().data())>::value>::type* = nullptr> - constexpr auto data(const C& c) -> decltype(c.data()) { - return c.data(); - } - template - constexpr T* data(T (&array)[N]) noexcept - { - return array; - } - template - constexpr const E* data(const std::initializer_list& il) noexcept - { - return il.begin(); - } - - template ().size())>::value>::type* = nullptr> - constexpr auto size(const C& c) -> decltype(c.size()) - { - return c.size(); - } - template - constexpr std::size_t size(const T (&array)[N]) noexcept - { - return N; - } -#endif - - template - struct make_unsigned > { - typedef std::vector::type > type; - }; - template - struct make_unsigned > { - typedef std::initializer_list::type > type; - }; - template - struct make_unsigned > { - typedef std::array::type, N> type; - }; - template - struct make_unsigned > { - typedef btas::varray::type > type; - }; -#ifdef BTAS_HAS_BOOST_CONTAINER - template - struct make_unsigned > { - typedef boost::container::small_vector::type,N> type; - }; -#endif - template - struct make_unsigned { - typedef typename make_unsigned::type uT; - typedef uT (type)[N]; - }; - -} - namespace btas { template struct replace_value_type; diff --git a/btas/ordinal.h b/btas/ordinal.h index 87773806..f7e84a5b 100644 --- a/btas/ordinal.h +++ b/btas/ordinal.h @@ -106,17 +106,11 @@ namespace btas { return stride_; } - // no easy way without C++14 to invoke data(stride) in ADL-capable way -#if __cplusplus < 201402L - auto stride_data() const -> decltype(std::data(this->stride())) { - return std::data(stride_); - } -#else auto stride_data() const { using std::data; return data(stride_); } -#endif + value_type offset() const { return offset_; } diff --git a/btas/range.h b/btas/range.h index 44bd402e..30e11010 100644 --- a/btas/range.h +++ b/btas/range.h @@ -299,7 +299,7 @@ namespace btas { const static blas::Layout order = range_traits<_Derived>::order; typedef typename range_traits<_Derived>::index_type index_type; ///< index type - typedef typename std::make_unsigned::type extent_type; ///< Range extent type + typedef typename replace_value_type>::type extent_type; ///< Range extent type typedef std::size_t size_type; ///< Size type typedef typename index_type::value_type index_element_type; diff --git a/btas/tensor.h b/btas/tensor.h index 85eb50e8..3195f2fe 100644 --- a/btas/tensor.h +++ b/btas/tensor.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -133,19 +134,21 @@ namespace btas { } /// construct from \c range object, copy elements from \c vec - template - Tensor(const Range& range, U* vec, typename std::enable_if::value>::type* = 0) + template + Tensor(const Range& range, U input_it, typename std::enable_if::value>::type* = 0) : range_(range.lobound(), range.upbound()) { const auto size = range_.area(); array_adaptor::resize(storage_, size); - std::copy(vec, vec + size, begin()); + for (auto output_it = begin(); output_it != end(); ++output_it, ++input_it) { + *output_it = *input_it; + } } /// construct from \c range and \c storage template Tensor(const Range& range, const Storage& storage, typename std::enable_if::value & not std::is_same::value & - not std::is_same::value>::type* = 0) + btas::is_storage::value & not std::is_same::value>::type* = 0) : range_(range.lobound(), range.upbound()), storage_(storage) { using std::size; if (size(storage_) != range_.area()) array_adaptor::resize(storage_, range_.area()); diff --git a/btas/type_traits.h b/btas/type_traits.h index 1d859a4b..59f22df5 100644 --- a/btas/type_traits.h +++ b/btas/type_traits.h @@ -4,27 +4,6 @@ #include #include -// C++20 extensions -#if __cplusplus <= 201703L -namespace std { - template< class T > - struct remove_cvref { - typedef std::remove_cv_t> type; - }; - - template< class T> - using remove_cvref_t = typename remove_cvref::type; - - template< class T > - struct type_identity { - using type = T; - }; - - template< class T > - using type_identity_t = typename type_identity::type; -} -#endif - namespace btas { template diff --git a/btas/util/deprecated.h b/btas/util/deprecated.h deleted file mode 100644 index 19fab925..00000000 --- a/btas/util/deprecated.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * deprecated.h - * - * Created on: Jul 9, 2017 - * Author: evaleev - */ - -#ifndef BTAS_UTIL_DEPRECATED_H_ -#define BTAS_UTIL_DEPRECATED_H_ - -// mark functions as deprecated using this macro -// will result in a warning -#if __cplusplus >= 201402L -#define DEPRECATED [[deprecated]] -#elif defined(__GNUC__) -#define DEPRECATED __attribute__((deprecated)) -#else -#pragma message("WARNING: You need to implement DEPRECATED for this compiler") -#define DEPRECATED -#endif - -// same as DEPRECATED, but annotated with a message -// will result in a warning -#if __cplusplus >= 201402L -#define DEPRECATEDMSG(msg) [[deprecated(msg)]] -#elif defined(__GNUC__) -#define DEPRECATEDMSG(msg) __attribute__((deprecated(msg))) -#else -#pragma message("WARNING: You need to implement DEPRECATEDMSG for this compiler") -#define DEPRECATEDMSG(msg) -#endif - -#endif /* BTAS_UTIL_DEPRECATED_H_ */ diff --git a/external/versions.cmake b/external/versions.cmake index f3ca49e2..99309658 100644 --- a/external/versions.cmake +++ b/external/versions.cmake @@ -1,4 +1,4 @@ -set(BTAS_TRACKED_VGCMAKEKIT_TAG d5c0a6f9ff6dc97cbb5132912733e1eb1cf73f1e) +set(BTAS_TRACKED_VGCMAKEKIT_TAG 256d9462bb765787f5acb69be154b26d6efba8b6) # oldest Boost we can tolerate ... likely can use an earlier version, but: # - as of oct 2023 tested with 1.71 and up only