Commit 88cfef67 authored by Oliver Sander's avatar Oliver Sander

Merge branch 'feature/introduce-static-indices' into 'master'

Introduce static indices _0, _1, _2 as shortcuts for std::integral_constant<std::size_t,0> etc.

These indices have existed in dune-typetree for a while.  They are already used extensively
in dune-typetree and dune-functions, and they also make working with MultiTypeBlockVector/Matrix
from dune-istl much nicer.  They work very much like std::placeholders:_1, std::placeholders::_2,
etc.  We would have like to use that, but there is no std::placeholders_0.
    
This patch also introduces
    
    template<std::size_t i>
    using index_constant = std::integral_constant<std::size_t, i>;
    
which helps decrease code verbosity a little bit.


See merge request !44
parents 0b5c57f8 9159760f
......@@ -61,6 +61,7 @@ install(FILES
hash.hh
identitymatrix.hh
indent.hh
indices.hh
interfaces.hh
ios_state.hh
iteratorfacades.hh
......
......@@ -54,6 +54,7 @@ commoninclude_HEADERS = \
hash.hh \
identitymatrix.hh \
indent.hh \
indices.hh \
interfaces.hh \
ios_state.hh \
iteratorfacades.hh \
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_COMMON_INDICES_HH
#define DUNE_COMMON_INDICES_HH
#include <cstddef>
#include <type_traits>
namespace Dune
{
/** \addtogroup Common
* \{
*/
/** \brief An index constant with value i
*
* An index constant is a simple type alias for an integral_constant.
* Its main advantages are clarity (it is easier to see that code uses it
* as an index) and the fact that the integral type is fixed, reducing verbosity
* and avoiding the problem of maybe trying to overload / specialize using a different
* integral type.
*/
template<std::size_t i>
using index_constant = std::integral_constant<std::size_t, i>;
/** \brief Namespace with predefined compile time indices for the range [0,19]
*
* The predefined index objects in this namespace are `constexpr`, which allows them to
* be used in situations where a compile time constant is needed, e.g. for a template
* parameter. Apart from that, `constexpr` implies internal linkage, which helps to avoid
* ODR problems.
*
* The constants implicitly convert to their contained value, so you can for example write
*
* \code{.cc}
* std::array<int,_10> a;
* // the above line is equivalent to
* std::array<int,10> b;
* \endcode
*
*/
namespace Indices
{
//! Compile time index with value 0.
constexpr index_constant< 0> _0 = {};
//! Compile time index with value 1.
constexpr index_constant< 1> _1 = {};
//! Compile time index with value 2.
constexpr index_constant< 2> _2 = {};
//! Compile time index with value 3.
constexpr index_constant< 3> _3 = {};
//! Compile time index with value 4.
constexpr index_constant< 4> _4 = {};
//! Compile time index with value 5.
constexpr index_constant< 5> _5 = {};
//! Compile time index with value 6.
constexpr index_constant< 6> _6 = {};
//! Compile time index with value 7.
constexpr index_constant< 7> _7 = {};
//! Compile time index with value 8.
constexpr index_constant< 8> _8 = {};
//! Compile time index with value 9.
constexpr index_constant< 9> _9 = {};
//! Compile time index with value 10.
constexpr index_constant<10> _10 = {};
//! Compile time index with value 11.
constexpr index_constant<11> _11 = {};
//! Compile time index with value 12.
constexpr index_constant<12> _12 = {};
//! Compile time index with value 13.
constexpr index_constant<13> _13 = {};
//! Compile time index with value 14.
constexpr index_constant<14> _14 = {};
//! Compile time index with value 15.
constexpr index_constant<15> _15 = {};
//! Compile time index with value 16.
constexpr index_constant<16> _16 = {};
//! Compile time index with value 17.
constexpr index_constant<17> _17 = {};
//! Compile time index with value 18.
constexpr index_constant<18> _18 = {};
//! Compile time index with value 19.
constexpr index_constant<19> _19 = {};
} // namespace Indices
} //namespace Dune
#endif // DUNE_COMMON_INDICES_HH
dune_add_test(SOURCES indexsettest.cc
LINK_LIBRARIES dunecommon)
dune_add_test(SOURCES indicestest.cc
dune_add_test(SOURCES remoteindicestest.cc
LINK_LIBRARIES dunecommon
SKIP_ON_77)
......
MPITESTS = indicestest \
MPITESTS = remoteindicestest \
indexsettest \
syncertest \
selectiontest \
......@@ -14,12 +14,12 @@ TESTS = $(NORMALTESTS) $(MPITESTS)
check_PROGRAMS = $(NORMALTESTS) $(MPITESTS)
# define the programs
indicestest_SOURCES = indicestest.cc
indicestest_CPPFLAGS = $(AM_CPPFLAGS) \
remoteindicestest_SOURCES = remoteindicestest.cc
remoteindicestest_CPPFLAGS = $(AM_CPPFLAGS) \
$(DUNEMPICPPFLAGS)
indicestest_LDFLAGS = $(AM_LDFLAGS) \
remoteindicestest_LDFLAGS = $(AM_LDFLAGS) \
$(DUNEMPILDFLAGS)
indicestest_LDADD = \
remoteindicestest_LDADD = \
$(DUNEMPILIBS) \
$(LDADD)
......
......@@ -61,6 +61,8 @@ dune_add_test(SOURCES genericiterator_compile_fail.cc
dune_add_test(SOURCES gcdlcmtest.cc)
dune_add_test(SOURCES indicestest.cc)
dune_add_test(SOURCES integersequence.cc)
dune_add_test(SOURCES iteratorfacadetest2.cc)
......
......@@ -16,6 +16,7 @@ TESTPROGS = \
fmatrixtest \
fvectortest \
gcdlcmtest \
indicestest \
integersequence \
iteratorfacadetest \
iteratorfacadetest2 \
......@@ -123,6 +124,8 @@ fvectortest_SOURCES = fvectortest.cc
gcdlcmtest_SOURCES = gcdlcmtest.cc
indicestest_SOURCES = indicestest.cc
genericiterator_compile_fail_SOURCES = genericiterator_compile_fail.cc
integersequence_SOURCES = integersequence.cc
......
// -*- 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 <tuple>
#include <dune/common/indices.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()
{
using namespace Dune::Indices;
// Test whether indices can be used to index a data structure
TupleVector<int,double,float> v;
v[_0] = 42;
v[_1] = 3.14;
v[_2] = 2.7;
// Test whether the indices can be used as numbers
std::get<_0>(v) = 43;
std::get<_1>(v) = 4.14;
std::get<_2>(v) = 3.7;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment