diff --git a/dune/subgrid/CMakeLists.txt b/dune/subgrid/CMakeLists.txt index c09b0c42fa656bcabbfd5ae6fc2d9088e1427a0a..5f078aad77f62ec6cb17e1a9db05778c01c5b56a 100644 --- a/dune/subgrid/CMakeLists.txt +++ b/dune/subgrid/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(common) add_subdirectory(facetools) add_subdirectory(subgrid) add_subdirectory(test) diff --git a/dune/subgrid/common/CMakeLists.txt b/dune/subgrid/common/CMakeLists.txt deleted file mode 100644 index a31ec91c4cfb2205d700956f5a1633d72fe8b067..0000000000000000000000000000000000000000 --- a/dune/subgrid/common/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(commonincludedir ${CMAKE_INSTALL_INCLUDEDIR}/dune/subgrid/common) -set(commoninclude_HEADERS variant.hh) -# include not needed for CMake -# include $(top_srcdir)/am/global-rules -install(FILES ${commoninclude_HEADERS} DESTINATION ${commonincludedir}) diff --git a/dune/subgrid/common/variant.hh b/dune/subgrid/common/variant.hh deleted file mode 100644 index 05a6ea4c15ef0ffa4641a71e63e60eefaecdddc8..0000000000000000000000000000000000000000 --- a/dune/subgrid/common/variant.hh +++ /dev/null @@ -1,467 +0,0 @@ -// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// vi: set et ts=4 sw=2 sts=2: -#ifndef DUNE_COMMON_STD_VARIANT_HH -#define DUNE_COMMON_STD_VARIANT_HH -#include <tuple> -#include <memory> -#include <dune/common/hybridutilities.hh> -#include <dune/common/exceptions.hh> - -namespace Dune { -namespace Std { -namespace Impl { - - // indicator value if something's not yet (or not any longer) valid - constexpr const auto invalidIndex = std::numeric_limits<size_t>::max(); - - /* helper constructs to find position of a type T in a pack Ts... */ - template <typename T, typename... Ts> - struct index_in_pack; - - template <typename T, typename... Ts> - struct index_in_pack<T, T, Ts...> : std::integral_constant<std::size_t, 0> {}; - - template <typename T, typename U, typename... Ts> - struct index_in_pack<T, U, Ts...> : std::integral_constant<std::size_t, 1 + index_in_pack<T, Ts...>::value> {}; - - /* end helper constructs to find position of a type T in a pack Ts... */ - - template<typename Tp> - struct Buffer_ : std::aligned_storage<sizeof(Tp)> { - using Storage = std::aligned_storage_t<sizeof(Tp)>; - Storage storage_; - - void* addr() { - return static_cast<void*>(&storage_); - } - - const void* addr() const { - return static_cast<const void*>(&storage_); - } - - Tp* ptr() { - return static_cast<Tp*>(addr()); - } - - const Tp* ptr() const { - return static_cast<const Tp*>(addr()); - } - }; - - template<typename Tp, bool isTrivial> - struct TypeStorage_ { }; - - template<typename Tp> - struct TypeStorage_<Tp, true> { - TypeStorage_(Tp t) : - tp_(t) {} - - template<typename... Args> - TypeStorage_(Args... args) : - tp_(args...) {} - - auto& get() { - return tp_; - } - const auto& get() const { - return tp_; - } - - void reset() {}; - - private: - Tp tp_; - }; - - template<typename Tp> - struct TypeStorage_<Tp, false> { - TypeStorage_(Tp t) { - ::new (&tp_) Tp(t); - } - - template<typename... Args> - TypeStorage_(Args... args) { - ::new (&tp_) Tp(std::forward<Args>(args)...); - } - - TypeStorage_() = delete; - - auto& get() { - return *(tp_.ptr()); - } - const auto& get() const { - return *(tp_.ptr()); - } - - void reset() { - // Properly destruct the member: - tp_.ptr()->~Tp(); - // (the memory itself doesn't need to be free'd. This is done when the Buffer_ member gets destructed) - } - - private: - Buffer_<Tp> tp_; - }; - - template<typename... T> - union variant_union_ { - // dummy (this should never be called) - void resetByIndex(size_t) { - assert(false); - }; - }; - - template<typename Head_, typename... Tail_> - union variant_union_<Head_, Tail_...> { - constexpr variant_union_() : - tail_() {} - - template<typename... Args> - constexpr variant_union_(std::integral_constant<size_t, 0>, Args&&... args) : - head_(std::forward<Args...>(args)...) {} - - template<size_t N, typename... Args> - constexpr variant_union_(std::integral_constant<size_t, N>, Args&&... args) : - tail_(std::integral_constant<size_t, N-1>(), std::forward<Args...>(args)...) {} - - auto& getByIndex(std::integral_constant<size_t, 0>) { - return head_.get(); - } - - const auto& getByIndex(std::integral_constant<size_t, 0>) const { - return head_.get(); - } - - - template<size_t N> - auto& getByIndex(std::integral_constant<size_t, N>) { - return tail_.getByIndex(std::integral_constant<size_t, N-1>()); - } - - template<size_t N> - const auto& getByIndex(std::integral_constant<size_t, N>) const { - return tail_.getByIndex(std::integral_constant<size_t, N-1>()); - } - - void resetByIndex(size_t indexToReset) { - if (indexToReset == 0) { - head_.reset(); - return; - } - else { - tail_.resetByIndex(indexToReset-1); - } - } - - template<typename Tp> - void set(Tp&& obj) { - using T = std::decay_t<Tp>; - Dune::Hybrid::ifElse(std::is_same<T, Head_>(), - [&](auto&& id) { id(head_)=std::forward<Tp>(obj); }, - [&](auto&& id) { return id(tail_).set(std::forward<Tp>(obj)); } - ); - } - - constexpr size_t size() const { - return sizeof...(Tail_)+1; - } - - private: - TypeStorage_<Head_, std::is_trivial<Head_>::value> head_; - variant_union_<Tail_...> tail_; - }; - - template<typename...T> - struct variant_{ - - constexpr variant_() : - unions_(), - index_(invalidIndex) {} - - template<typename Tp> - constexpr variant_(Tp obj) : - unions_(), - index_(index_in_pack<Tp, T...>::value) - { - unions_.set(std::move(obj)); - } - - variant_(variant_&& other) { - unions_ = std::move(other.unions_); - index_ = other.index_; - other.index_ = invalidIndex; - } - - variant_(const variant_& other) { - index_ = other.index_; - - namespace H = Dune::Hybrid; - H::forEach(H::integralRange(std::integral_constant<size_t, size_>()), [&](auto i) { - if(i==index_) - unions_.set(other.template get<i>()); - }); - } - - variant_& operator=(const variant_& other) { - if(index_ != invalidIndex) - unions_.resetByIndex(index_); - - index_ = other.index_; - - namespace H = Dune::Hybrid; - H::forEach(H::integralRange(std::integral_constant<size_t, size_>()), [&](auto i) { - if(i==index_) - unions_.set(other.template get<i>()); - }); - return *this; - } - - variant_& operator=(variant_&& other) { - unions_ = std::move(other.unions_); - index_ = other.index_; - other.index_ = invalidIndex; - - return *this; - } - - - template<typename Tp> - auto& get() { - constexpr size_t idx = index_in_pack<Tp, T...>::value; - if (index_ != idx) - DUNE_THROW(Dune::Exception, "Bad variant access."); - - return get<idx>(); - } - - template<typename Tp> - const auto& get() const { - constexpr size_t idx = index_in_pack<Tp, T...>::value; - if (index_ != idx) - DUNE_THROW(Dune::Exception, "Bad variant access."); - - return get<idx>(); - } - - template<typename Tp> - Tp* get_if() { - if (not holds_alternative<Tp>()) - return (Tp*) nullptr; - else - return &(get<Tp>()); - } - - template<typename Tp> - const Tp* get_if() const { - if (not holds_alternative<Tp>()) - return (Tp*) nullptr; - else - return &(get<Tp>()); - } - - template<size_t N> - auto* get_if() { - using Tp = std::decay_t<decltype(get<N>())>; - if (not holds_alternative<N>()) - return (Tp*) nullptr; - else - return &(get<Tp>()); - } - - template<size_t N> - const auto* get_if() const { - using Tp = std::decay_t<decltype(get<N>())>; - if (not holds_alternative<N>()) - return (Tp*) nullptr; - else - return &(get<Tp>()); - } - - template<size_t N> - auto& get() { - if (index_ != N || index_ == invalidIndex) - DUNE_THROW(Dune::Exception, "Bad variant access."); - return unions_.template getByIndex(std::integral_constant<size_t, N>()); - } - template<size_t N> - const auto& get() const { - if (index_ != N || index_ == invalidIndex) - DUNE_THROW(Dune::Exception, "Bad variant access."); - return unions_.template getByIndex(std::integral_constant<size_t, N>()); - } - - template<typename Tp> - constexpr Tp& operator=(Tp obj) { - constexpr auto index = index_in_pack<Tp, T...>::value; - // before setting a new object into the buffer, we have to destruct the old element - if(not (index_ == index or index_ == invalidIndex)) { - unions_.resetByIndex(index_); - } - unions_.set(std::move(obj)); - index_=index; - return unions_.getByIndex(std::integral_constant<size_t,index>()); - } - - constexpr std::size_t index() const noexcept { - return index_; - } - - constexpr auto size() const { - return sizeof...(T); - } - - ~variant_() { - if (index_ != invalidIndex) { - unions_.resetByIndex(index_); - } - } - - /* \brief Apply visitor to the active variant. - * - * visit assumes that the result of - * func(T) has the same type for all types T - * in this variant. - */ - template<typename F> - auto visit(F&& func) { - using namespace Dune::Hybrid; - - using Result = decltype(func(unions_.getByIndex(std::integral_constant<size_t, 0>()))); - - return ifElse(std::is_same<Result, void>(), [&, this](auto id) { - constexpr auto tsize = size_; - Dune::Hybrid::forEach(Dune::Hybrid::integralRange(std::integral_constant<size_t, tsize>()), [&](auto i) { - if (i==this->index_) - func(id(unions_).getByIndex(std::integral_constant<size_t, i>())); - }); - return;}, - [&func,this](auto id) { - constexpr auto tsize = size_; - - auto result = std::unique_ptr<Result>(); - - Dune::Hybrid::forEach(Dune::Hybrid::integralRange(std::integral_constant<size_t, tsize>()), [&, this](auto i) { - if (i==this->index_) - result = std::make_unique<Result>(func(id(this->unions_).getByIndex(std::integral_constant<size_t, i>()))); - }); - return *result; - }); - } - - template<typename F> - auto visit(F&& func) const { - using namespace Dune::Hybrid; - - using Result = decltype(func(unions_.getByIndex(std::integral_constant<size_t, 0>()))); - - return ifElse(std::is_same<Result, void>(), [&, this](auto id) { - constexpr auto tsize = size_; - Dune::Hybrid::forEach(Dune::Hybrid::integralRange(std::integral_constant<size_t, tsize>()), [&](auto i) { - if (i==this->index_) - func(id(unions_).getByIndex(std::integral_constant<size_t, i>())); - }); - return;}, - [&func,this](auto id) { - constexpr auto tsize = size_; - - auto result = std::unique_ptr<Result>(); - - Dune::Hybrid::forEach(Dune::Hybrid::integralRange(std::integral_constant<size_t, tsize>()), [&, this](auto i) { - if (i==this->index_) - result = std::make_unique<Result>(func(id(this->unions_).getByIndex(std::integral_constant<size_t, i>()))); - }); - return *result; - }); - } - - /** \brief Check if a given type is the one that is currently active in the variant. */ - template<typename Tp> - constexpr bool holds_alternative() const { - // I have no idea how this could be really constexpr, but for STL-conformity, - // I'll leave the modifier there. - return (index_in_pack<Tp, T...>::value == index_); - } - - /** \brief Check if a given type is the one that is currently active in the variant. */ - template<size_t N> - constexpr bool holds_alternative() const { - // I have no idea how this could be really constexpr, but for STL-conformity, - // I'll leave the modifier there. - return (N == index_); - } - - private: - variant_union_<T...> unions_; - std::size_t index_; - constexpr static auto size_ = sizeof...(T); - }; - -} // end namespace Impl - - /** \brief Incomplete re-implementation of C++17's std::variant. */ - template<typename ...T> - using variant = Impl::variant_<T...>; - - template<size_t N, typename... T> - auto& get(variant<T...>& var) { - return var.template get<N>(); - } - - template<size_t N, typename... T> - const auto& get(const variant<T...>& var) { - return var.template get<N>(); - } - - template<typename F, typename... T> - auto visit(F&& visitor, variant<T...>& var) { - return var.visit(std::forward<F>(visitor)); - } - - template<typename F, typename... T> - auto visit(F&& visitor, const variant<T...>& var) { - return var.visit(std::forward<F>(visitor)); - } - - template<typename Tp, typename ...T> - auto& get(variant<T...>& var) { - return var.template get<Tp>(); - } - - template<typename Tp, typename ...T> - const auto& get(const variant<T...>& var) { - return var.template get<Tp>(); - } - - template<typename Tp, typename ...T> - const auto* get_if(const variant<T...>& var) { - return var.template get_if<Tp>(); - } - - template<typename Tp, typename ...T> - auto* get_if(variant<T...>& var) { - return var.template get_if<Tp>(); - } - - template<size_t N, typename ...T> - const auto* get_if(const variant<T...>& var) { - return var.template get_if<N>(); - } - - template<size_t N, typename ...T> - auto* get_if(variant<T...>& var) { - return var.template get_if<N>(); - } - - template<typename Tp, typename ...T> - constexpr bool holds_alternative(const variant<T...>& var) { - return var.template holds_alternative<Tp>(); - } - - template <typename... T> - constexpr auto variant_size_v(const variant<T...>&) { - return std::integral_constant<std::size_t,sizeof...(T)>::value; - } - -} // end namespace Std -} // end namespace Dune -#endif diff --git a/dune/subgrid/subgrid/subgridgeometry.hh b/dune/subgrid/subgrid/subgridgeometry.hh index 578ca06328afd5d4d24e7543e45b28124259296b..c8ff55b65204410574f12b9a5c6c8c610f96f76d 100644 --- a/dune/subgrid/subgrid/subgridgeometry.hh +++ b/dune/subgrid/subgrid/subgridgeometry.hh @@ -5,7 +5,7 @@ * \brief The SubGridGeometry class and its specializations */ #include <type_traits> -#include <dune/subgrid/common/variant.hh> +#include <dune/common/std/variant.hh> #include <dune/common/fmatrix.hh> #include <dune/common/typetraits.hh> diff --git a/dune/subgrid/test/CMakeLists.txt b/dune/subgrid/test/CMakeLists.txt index 735fbd88d618686fdf69086a3f87a445c943cdae..1cb2c78ee5dd68fa6288e0e83b9effc9bfeb25ce 100644 --- a/dune/subgrid/test/CMakeLists.txt +++ b/dune/subgrid/test/CMakeLists.txt @@ -1,5 +1,5 @@ -set(TESTPROGS test-w-onedgrid test-w-yaspgrid test-w-alugrid testvariant) +set(TESTPROGS test-w-onedgrid test-w-yaspgrid test-w-alugrid) if(ALBERTA_FOUND) list(APPEND TESTPROGS test-w-albertagrid2d) diff --git a/dune/subgrid/test/testvariant.cc b/dune/subgrid/test/testvariant.cc deleted file mode 100644 index 82e29c0f6edf06f9ffd5b200cd594a6beb1b7558..0000000000000000000000000000000000000000 --- a/dune/subgrid/test/testvariant.cc +++ /dev/null @@ -1,134 +0,0 @@ -// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// vi: set et ts=4 sw=2 sts=2: - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <iostream> -#include <dune/common/parallel/mpihelper.hh> // An initializer of MPI -#include <dune/common/exceptions.hh> // We use exceptions -#include <dune/common/test/testsuite.hh> - -#include <dune/subgrid/common/variant.hh> - -// some non-default constructible type -struct F { - int i; - F() = delete; - F(int j) : - i(j) {} -}; - -Dune::TestSuite testVariant() { - using namespace Dune; - TestSuite suite; - - int i = 42; - double d = 3.14; - F f(13); - using V = std::vector<int>; - - auto variant = Std::variant<int, double, F, V>(); - - suite.check(Std::variant_size_v(variant) == 4, "Test variant_size_v"); - - - variant = d; - suite.check(Std::holds_alternative<double>(variant), "Test holds_alternative"); - - variant = f; - suite.check(Std::holds_alternative<F>(variant), "Test holds_alternative"); - - variant = i; - suite.check(Std::holds_alternative<int>(variant), "Test holds_alternative"); - - suite.check(Std::get<int>(variant) == i, "Test get<Type>"); - suite.check(Std::get<0>(variant) == i, "Test get<Index>"); - - suite.check(Std::get_if<int>(variant) != nullptr, "Test get_if on right type"); - suite.check(Std::get_if<double>(variant) == nullptr, "Test get_if on wrong type"); - - suite.check(Std::get_if<0>(variant) != nullptr, "Test get_if on right index"); - suite.check(Std::get_if<1>(variant) == nullptr, "Test get_if on wrong index"); - - // test if get<Type> throws if one tries to get the wrong type: - try { - // currently hold type is still int, so double should throw - Std::get<double>(variant); - suite.check(false, "Test get<Type> on wrong type should have thrown"); - } - catch (...) { - suite.check(true, "Test get<Type> on wrong type has thrown"); - } - - - variant = V(1); - suite.check(Std::get<V>(variant).size() == 1, "Test with non-trivial type"); - - variant = f; - - suite.check(variant.index() == 2, "Test index()"); // we're at type F, which has position 2 - - // Demonstrate visit concept and using vector as an example of a non-POD type - using V2 = std::vector<double>; - Std::variant<V, V2> variant2; - variant2 = V(1); - auto size = [](auto&& v) {return v.size();}; - suite.check(Std::visit(size, variant2)== 1, "Test visit"); - variant2 = V2(2); - suite.check(Std::visit(size, variant2)== 2, "Test visit"); - - // try on a const reference: - const auto& constv2 = variant2; - suite.check(Std::visit(size, constv2)== 2, "Test const visit"); - suite.check(Std::get_if<V2>(constv2) != nullptr, "Test const get_if"); - - /// test copy and move construction/assignment - { - auto variant_copy_constructed = variant2; - // test if deep copy happened - auto getPtrToData = [&](const auto& vec) {return static_cast<const void*>(vec.data()); }; - suite.check(Std::visit(getPtrToData, variant_copy_constructed) != Std::visit(getPtrToData, variant2), "Check deep copy") << "Both vector copies point to same data"; - - auto variant_move_constructed = std::move(variant_copy_constructed); - // TODO: Add sensible test condition here. - // Testing if the pointer to the data is the same as before is probably not a good idea, - // as moving does not imply that the data really stays at the same place (though it probably - // does). - // At least if this compiles and runs we can be confident no double frees happened. - // - // First idea: Test if the state looks somewhat valid - suite.check(Std::holds_alternative<V2>(variant_move_constructed), "Check if move constructed variant holds the right type"); - - Std::variant<V, V2> variant_copy_assigned; - variant_copy_assigned = variant2; - // test if deep copy happened - suite.check(Std::visit(getPtrToData, variant_copy_assigned) != Std::visit(getPtrToData, variant2), "Check deep copy at operator=") << "Both vector copies point to same data"; - - Std::variant<V, V2> variant_move_assigned; - variant_move_assigned = std::move(variant_copy_assigned); - // TODO: Again, as above, find a better test for this. - suite.check(Std::holds_alternative<V2>(variant_move_assigned), "Check if move assigned variant holds the right type"); - } - - return suite; -} - -int main(int argc, char** argv) -{ - try{ - // Maybe initialize MPI - Dune::MPIHelper::instance(argc, argv); - - Dune::TestSuite suite; - suite.subTest(testVariant()); - - return suite.exit(); - } - catch (Dune::Exception &e){ - std::cerr << "Dune reported error: " << e << std::endl; - } - catch (...){ - std::cerr << "Unknown exception thrown!" << std::endl; - } -}