Skip to content
Merged

C++20 #186

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,22 +115,31 @@ 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()

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)
Expand All @@ -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 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/${BTAS_INSTALL_INCLUDEDIR}>)
install(TARGETS BTAS EXPORT btas COMPONENT BTAS)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
113 changes: 0 additions & 113 deletions btas/array_adaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,119 +156,6 @@ namespace btas {

}

namespace std {

#if __cplusplus < 201402L // add C++14 components to make transition to C++14 easier
template <typename T, size_t N>
const T* cbegin(const T(&x)[N]) {
return &x[0];
}
template <typename T, size_t N>
const T* cend(const T(&x)[N]) {
return &x[N];
}
template <typename T, size_t N>
const T* rbegin(T(&x)[N]) {
return &x[N-1];
}
template <typename T, size_t N>
const T* rend(T(&x)[N]) {
return &x[0] - 1;
}

template <typename T>
const T* cbegin(const T* x) {
return x;
}
template <typename T>
const T* cbegin(T* x) {
return x;
}
template <typename T>
T* begin(T* x) {
return x;
}

template <typename C>
constexpr auto cbegin(const C& x) -> decltype(std::begin(x)) {
return std::begin(x);
}
template <typename C>
constexpr auto cend(const C& x) -> decltype(std::end(x)) {
return std::end(x);
}
template <typename C>
auto rbegin(C& x) -> decltype(x.rbegin()) {
return x.rbegin();
}
template <typename C>
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 <class C, typename std::enable_if<std::is_pointer<decltype(std::declval<C>().data())>::value>::type* = nullptr>
constexpr auto data(C& c) -> decltype(c.data()) {
return c.data();
}
template <class C, typename std::enable_if<std::is_pointer<decltype(std::declval<C>().data())>::value>::type* = nullptr>
constexpr auto data(const C& c) -> decltype(c.data()) {
return c.data();
}
template <class T, std::size_t N>
constexpr T* data(T (&array)[N]) noexcept
{
return array;
}
template <class E>
constexpr const E* data(const std::initializer_list<E>& il) noexcept
{
return il.begin();
}

template <class C, typename std::enable_if<std::is_integral<decltype(std::declval<C>().size())>::value>::type* = nullptr>
constexpr auto size(const C& c) -> decltype(c.size())
{
return c.size();
}
template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
return N;
}
#endif

template <typename T>
struct make_unsigned<std::vector<T> > {
typedef std::vector<typename make_unsigned<T>::type > type;
};
template <typename T>
struct make_unsigned<std::initializer_list<T> > {
typedef std::initializer_list<typename make_unsigned<T>::type > type;
};
template <typename T, size_t N>
struct make_unsigned<std::array<T, N> > {
typedef std::array<typename make_unsigned<T>::type, N> type;
};
template <typename T>
struct make_unsigned<btas::varray<T> > {
typedef btas::varray<typename make_unsigned<T>::type > type;
};
#ifdef BTAS_HAS_BOOST_CONTAINER
template <typename T, size_t N>
struct make_unsigned<boost::container::small_vector<T,N> > {
typedef boost::container::small_vector<typename make_unsigned<T>::type,N> type;
};
#endif
template <typename T, size_t N>
struct make_unsigned<T[N]> {
typedef typename make_unsigned<T>::type uT;
typedef uT (type)[N];
};

}

namespace btas {
template <typename Array, typename T>
struct replace_value_type;
Expand Down
8 changes: 1 addition & 7 deletions btas/ordinal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
}
Expand Down
2 changes: 1 addition & 1 deletion btas/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<index_type>::type extent_type; ///< Range extent type
typedef typename replace_value_type<index_type, std::make_unsigned_t<typename index_type::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;
Expand Down
11 changes: 7 additions & 4 deletions btas/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <algorithm>
#include <cassert>
#include <functional>
#include <iterator>
#include <type_traits>
#include <vector>

Expand Down Expand Up @@ -133,19 +134,21 @@ namespace btas {
}

/// construct from \c range object, copy elements from \c vec
template <typename Range, typename U>
Tensor(const Range& range, U* vec, typename std::enable_if<btas::is_boxrange<Range>::value>::type* = 0)
template <typename Range, std::input_or_output_iterator U>
Tensor(const Range& range, U input_it, typename std::enable_if<btas::is_boxrange<Range>::value>::type* = 0)
: range_(range.lobound(), range.upbound()) {
const auto size = range_.area();
array_adaptor<storage_type>::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 <typename Range, typename Storage>
Tensor(const Range& range, const Storage& storage,
typename std::enable_if<btas::is_boxrange<Range>::value & not std::is_same<Range, range_type>::value &
not std::is_same<Storage, storage_type>::value>::type* = 0)
btas::is_storage<Storage>::value & not std::is_same<Storage, storage_type>::value>::type* = 0)
: range_(range.lobound(), range.upbound()), storage_(storage) {
using std::size;
if (size(storage_) != range_.area()) array_adaptor<storage_type>::resize(storage_, range_.area());
Expand Down
21 changes: 0 additions & 21 deletions btas/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,6 @@
#include <type_traits>
#include <complex>

// C++20 extensions
#if __cplusplus <= 201703L
namespace std {
template< class T >
struct remove_cvref {
typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};

template< class T>
using remove_cvref_t = typename remove_cvref<T>::type;

template< class T >
struct type_identity {
using type = T;
};

template< class T >
using type_identity_t = typename type_identity<T>::type;
}
#endif

namespace btas {

template <typename... Ts>
Expand Down
33 changes: 0 additions & 33 deletions btas/util/deprecated.h

This file was deleted.

2 changes: 1 addition & 1 deletion external/versions.cmake
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading