diff --git a/dune/common/CMakeLists.txt b/dune/common/CMakeLists.txt index 9c689c6980f6200c335d2fc6affc65f5595c39da..129974b79ea8305d75e54fab3c0687556daf8991 100644 --- a/dune/common/CMakeLists.txt +++ b/dune/common/CMakeLists.txt @@ -97,6 +97,7 @@ install(FILES timer.hh tuples.hh tupleutility.hh + tuplevector.hh typelist.hh typetraits.hh typeutilities.hh diff --git a/dune/common/test/hybridutilitiestest.cc b/dune/common/test/hybridutilitiestest.cc index 8976e0b746b830aa588598e84fc57c4e69055a32..f275296f72e6df95877e56880c11074abe465a9e 100644 --- a/dune/common/test/hybridutilitiestest.cc +++ b/dune/common/test/hybridutilitiestest.cc @@ -9,50 +9,10 @@ #include <vector> #include <dune/common/hybridutilities.hh> +#include <dune/common/tuplevector.hh> #include <dune/common/test/testsuite.hh> -/** \brief A std::tuple that allows access to its element via operator[] - * - * Since there is no heterogeneous container in dune-common that supports - * operator[std::integralconstant<T,i>] we make our own for the test. - */ -template<class... T> -class TupleVector : public std::tuple<T...> -{ - using Base = std::tuple<T...>; -public: - - using Base::Base; - - /** \brief Array-style access to the tuple elements */ - template<std::size_t i> - decltype(auto) operator[](const Dune::index_constant<i>&) - { - return std::get<i>(*this); - } - - template<std::size_t i> - constexpr decltype(auto) operator[](const Dune::index_constant<i>&) const - { - return std::get<i>(*this); - } - - static constexpr auto size() - { - return std::tuple_size<Base>::value; - } -}; - -template<class... T> -constexpr auto makeTupleVector(T&&... t) -{ - // The std::decay_t<T> is is a slight simplification, - // because std::reference_wrapper needs special care. - return TupleVector<std::decay_t<T>...>(std::forward<T>(t)...); -} - - template<class C> auto incrementAll(C&& c) @@ -91,7 +51,7 @@ auto incAndAppendToFirst(C&& c) int main() { auto vector = std::vector<int>{1, 2, 3}; - auto numberTuple = makeTupleVector(0.1, 2, 3); + auto numberTuple = Dune::makeTupleVector(0.1, 2, 3); Dune::TestSuite test; @@ -100,7 +60,7 @@ int main() << "Incrementing vector entries with Hybrid::forEach failed."; incrementAll(numberTuple); - test.check(numberTuple == makeTupleVector(1.1, 3, 4)) + test.check(numberTuple == Dune::makeTupleVector(1.1, 3, 4)) << "Incrementing tuple entries with Hybrid::forEach failed."; addIndex(vector); @@ -108,13 +68,13 @@ int main() << "Adding indices to vector entries with Hybrid::forEach failed."; addIndex(numberTuple); - test.check(numberTuple == makeTupleVector(1.1, 4, 6)) + test.check(numberTuple == Dune::makeTupleVector(1.1, 4, 6)) << "Adding indices to vector entries with Hybrid::forEach failed."; - auto mixedTuple = makeTupleVector(std::string("1"), 2, 3); + auto mixedTuple = Dune::makeTupleVector(std::string("1"), 2, 3); incAndAppendToFirst(mixedTuple); - test.check(mixedTuple == makeTupleVector(std::string("1+1"), 3, 4)) + test.check(mixedTuple == Dune::makeTupleVector(std::string("1+1"), 3, 4)) << "Adding indices to vector entries with Hybrid::forEach failed."; return test.exit(); diff --git a/dune/common/test/indicestest.cc b/dune/common/test/indicestest.cc index 7dc07ab9a7d94e2aa6206faa75d6549feaeffdc0..4906ba2cc1ab360c0fb87cb4d9be7f34fd036943 100644 --- a/dune/common/test/indicestest.cc +++ b/dune/common/test/indicestest.cc @@ -7,25 +7,10 @@ #include <tuple> #include <dune/common/indices.hh> +#include <dune/common/tuplevector.hh> using namespace Dune; -/** \brief A std::tuple that allows access to its element via operator[] - * - * Helper class to test the static indices with - */ -template<class... T> -struct TupleVector : public std::tuple<T...> -{ - /** \brief Array-style access to the tuple elements */ - template<std::size_t i> - auto operator[](const index_constant<i>&) - ->decltype(std::get<i>(*this)) - { - return std::get<i>(*this); - } -}; - int main() @@ -33,7 +18,7 @@ int main() using namespace Dune::Indices; // Test whether indices can be used to index a data structure - TupleVector<int,double,float> v; + Dune::TupleVector<int,double,float> v; v[_0] = 42; v[_1] = 3.14; v[_2] = 2.7; diff --git a/dune/common/tuplevector.hh b/dune/common/tuplevector.hh new file mode 100644 index 0000000000000000000000000000000000000000..b43fee60d878ea7e52911e9c1102d1b781ac6ea8 --- /dev/null +++ b/dune/common/tuplevector.hh @@ -0,0 +1,85 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_COMMON_TUPLEVECTOR_HH +#define DUNE_COMMON_TUPLEVECTOR_HH + +#include <tuple> +#include <utility> + +#include <dune/common/indices.hh> + + + +/** + * \file + * \brief Provides the TupleVector class that augments std::tuple by operator[] + * \author Carsten Gräser + */ + +namespace Dune +{ + + + +/** + * \brief A class augmenting std::tuple by element access via operator[] + * + * \ingroup Utilities + */ +template<class... T> +class TupleVector : public std::tuple<T...> +{ + using Base = std::tuple<T...>; + +public: + + /** \brief Construct from a set of arguments + */ + template<class... TT> + constexpr TupleVector(TT&&... tt) : + Base(std::forward<TT>(tt)...) + {} + + /** \brief Default constructor + */ + constexpr TupleVector() + {} + + /** \brief Const access to the tuple elements + */ + template<std::size_t i> + constexpr decltype(auto) operator[](const Dune::index_constant<i>&) const + { + return std::get<i>(*this); + } + + /** \brief Non-const access to the tuple elements + */ + template<std::size_t i> + decltype(auto) operator[](const Dune::index_constant<i>&) + { + return std::get<i>(*this); + } + + /** \brief Number of elements of the tuple */ + static constexpr std::size_t size() + { + return std::tuple_size<Base>::value; + } +}; + + + +template<class... T> +constexpr auto makeTupleVector(T&&... t) +{ + // The std::decay_t<T> is is a slight simplification, + // because std::reference_wrapper needs special care. + return TupleVector<std::decay_t<T>...>(std::forward<T>(t)...); +} + + + +} // namespace Dune + +#endif // DUNE_COMMON_TUPLEVECTOR_HH