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