Basic.hpp 3.61 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
#pragma once

#include <cassert>
#include <tuple>
#include <map>
#include <list>

#include "IndexSeq.hpp"

namespace AMDiS
{  
    template <int I>
    using int_ = std::integral_constant<int, I>;

    template <bool B>
    using bool_ = std::integral_constant<bool, B>;

    template <size_t I>
    using index_ = std::integral_constant<size_t, I>;
    
    template <class T>
    using IdxPairList = std::map< std::pair<int, int>, std::list<std::shared_ptr<T> > >;
    
    template <class T>
    using IdxList = std::map< int, std::list<std::shared_ptr<T> > >;
  
  
    namespace Impl
    {
	// add arg to repeated constructor argument list
	template <class Tuple, size_t n, class Arg, class... Args>
	Tuple construct_tuple_aux(int_<n>, Arg&& arg, Args&&... args)
	{
	    return construct_tuple_aux<Tuple>(int_<n-1>(), 
		std::forward<Arg>(arg), std::forward<Arg>(arg), std::forward<Args>(args)...);
	}
	
	template <class Tuple, class... Args>
	Tuple construct_tuple_aux(int_<1>, Args&&... args)
	{
	    static_assert(std::tuple_size<Tuple>::value == sizeof...(args), 
		"Nr. of argument != tuple-size");
	    return Tuple{std::forward<Args>(args)...};
	}
	
	template <class Tuple, class... Args>
	Tuple construct_tuple_aux(int_<0>, Args&&... args)
	{
	    static_assert(std::tuple_size<Tuple>::value == 0, 
		"Construction of empty tuples with empty argument list only!");
	    return {};
	}
    } // end namespace Impl
    
    // construct a tuple with each element constructed by the same argument arg.
    template <class Tuple, class Arg>
    Tuple construct_tuple(Arg&& arg)
    {
	return Impl::construct_tuple_aux<Tuple>(int_<std::tuple_size<Tuple>::value>(), 
	std::forward<Arg>(arg));
    }
    
    // -----------
    
    template <template<class> class Base, class Tuple, class Indices> struct MakeTuple;
    
    template <template<class> class Base, class Tuple, size_t... I> 
    struct MakeTuple<Base, Tuple, Seq<I...>>
    {
	using type = std::tuple<Base<std::tuple_element_t<I, Tuple>>...>;
    };
    
    template <template<class> class Base, class Tuple> 
    using MakeTuple_t = 
	typename MakeTuple<Base, Tuple, MakeSeq_t<std::tuple_size<Tuple>::value>>::type;
    
    // -----------
    
    template <template<class,class> class Base, class Tuple1, class Tuple2, class Indices> struct MakeTuple2;
    
    template <template<class,class> class Base, class Tuple1, class Tuple2, size_t... I> 
    struct MakeTuple2<Base, Tuple1, Tuple2, Seq<I...>>
    {
	using type = std::tuple<Base<std::tuple_element_t<I, Tuple1>, std::tuple_element_t<I, Tuple2>>...>;
    };
    
    template <template<class,class> class Base, class Tuple1, class Tuple2> 
    using MakeTuple2_t = 
	typename MakeTuple2<Base, Tuple1, Tuple2, MakeSeq_t<std::tuple_size<Tuple1>::value>>::type;
    
    // -----------
    
    template <template<class...> class Base, class Tuple, class Indices> struct ExpandTuple;
    
    template <template<class...> class Base, class Tuple, size_t... I> 
    struct ExpandTuple<Base, Tuple, Seq<I...>>
    {
	using type = Base<std::tuple_element_t<I, Tuple>...>;
    };
    
    template <template<class...> class Base, class Tuple> 
    using ExpandTuple_t = 
	typename ExpandTuple<Base, Tuple, MakeSeq_t<std::tuple_size<Tuple>::value>>::type;
    
    
    // -----------
    
    template <class T, class Indices> struct RepeatedTuple;
    
    template <class T, size_t... I> 
    struct RepeatedTuple<T, Seq<I...>>
    {
	template <size_t, class U> using Id = U;	
	using type = std::tuple<Id<I, T>...>;
    };
    
    template <size_t N, class T> 
    using Repeat_t = 
	typename RepeatedTuple<T, MakeSeq_t<N>>::type;
    
  
} // end namespace AMDiS