rcolyer.net
RC Lib  Version 202403231100
Tuple.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////
2 //
3 // RC Library, (c) 2011-2015, Ryan A. Colyer
4 // Distributed under the Boost Software License, v1.0. (LICENSE.txt)
5 //
6 /// \file Tuple.h
7 /// Provides a Tuple class which can apply its contents as function
8 /// parameters.
9 /////////////////////////////////////////////////////////////////////
10 
11 #ifndef RC_TUPLE_H
12 #define RC_TUPLE_H
13 
14 #ifdef CPP11
15 
16 #include "RCconfig.h"
17 #include "Types.h"
18 #include "Data1D.h"
19 
20 #include <tuple>
21 
22 namespace RC {
23  /// @cond PROTECTED
24 
25  // Template tool for generating the sequence S... of 0 to one less
26  // than the value passed in as the first parameter of SequenceGenerator
27 
28  template<size_t...> struct TemplateSequence { };
29  template<size_t N, size_t... S> struct SequenceGenerator
30  : SequenceGenerator<N-1, N-1, S...> { };
31  template<size_t... S> struct SequenceGenerator<0, S...> {
32  typedef TemplateSequence<S...> Sequence;
33  };
34 
35  template<size_t N, class... Types>
36  class TupleBucket { };
37 
38  template<size_t N, class Type1, class... Types>
39  class TupleBucket<N, Type1, Types...>
40  : public TupleBucket<N+1, Types...> {
41 
42  public:
43  TupleBucket() { }
44 
45  TupleBucket(Type1& type1, Types&... types)
46  : TupleBucket<N+1, Types...>(types...)
47  , type1(type1) {
48  }
49 
50  inline Type1& Get() { return type1; }
51  inline const Type1& Get() const { return type1; }
52 
53  protected:
54  Type1 type1;
55  };
56 
57  /// @endcond
58 
59  /// An efficient Tuple class with Set, Get, and an Apply function
60  /// to pass the tuple contents on to any function.
61  template<class... Types>
62  class Tuple : public TupleBucket<0, Types...> {
63  public:
64  /// Default constructor, elements use default constructors.
65  Tuple() { }
66 
67  /// Construct by const reference.
68  template<int ResolveAmbiguity=0>
69  Tuple(const typename std::add_lvalue_reference<
70  typename std::remove_reference<Types>::type>::type... types)
71  : TupleBucket<0, Types...>(types...) { }
72 
73  /// Construct by moving elements in.
74  template<bool ResolveAmbiguity=0>
75  Tuple(typename std::add_rvalue_reference<
76  typename std::remove_reference<Types>::type>::type... types)
77  : TupleBucket<0, Types...>(types...) { }
78 
79  /// Returns a std::tuple of the same contents.
80  std::tuple<Types...> GetStdTuple() {
81  return Apply(std::tie<Types...>);
82  }
83 
84  protected:
85  /// @cond PROTECTED
86  template<size_t N, class Type1, class... GTypes>
87  inline Type1& GetHelper(TupleBucket<N, Type1, GTypes...>& tup) {
88  return tup.Get();
89  }
90  template<size_t N, class Type1, class... GTypes>
91  inline const Type1& GetHelper(
92  const TupleBucket<N, Type1, GTypes...>& tup) const {
93  return tup.Get();
94  }
95  /// @endcond
96 
97  public:
98  /// Return element N in the Tuple.
99  template<size_t N>
100  inline auto Get() -> decltype(this->GetHelper<N>(*this)) {
101  return GetHelper<N>(*this);
102  }
103  /// Return element N in the Tuple.
104  template<size_t N>
105  inline auto Get() const -> decltype(this->GetHelper<N>(*this)) {
106  return GetHelper<N>(*this);
107  }
108 
109  /// Set element N in the Tuple.
110  template<size_t N, class Val>
111  inline void Set(Val val) {
112  GetHelper<N>(*this) = val;
113  }
114 
115  protected:
116  /// @cond PROTECTED
117  template<class Func, size_t... Indices>
118  inline auto ApplyHelper(Func f, TemplateSequence<Indices...>)
119  -> decltype(f(this->Get<Indices>()...)) {
120  return f(Get<Indices>()...);
121  }
122 
123  template<class T, size_t... Indices>
124  inline Data1D<T> AsDataHelper(TemplateSequence<Indices...>) const {
125  return Data1D<T>{T(Get<Indices>())...};
126  }
127  /// @endcond
128 
129  public:
130  /// Call function f with each element of the Tuple as an argument.
131  /** @return The return value of function f for the given arguments.
132  */
133  template<class Func>
134  inline auto Apply(Func f)
135  -> decltype(this->ApplyHelper(f,
136  (typename SequenceGenerator<sizeof...(Types)>::Sequence()))) {
137  return ApplyHelper(f,
138  (typename SequenceGenerator<sizeof...(Types)>::Sequence()));
139  }
140 
141  /// Return a Data1D array with each element constructed as type T.
142  template<class T>
143  inline Data1D<T> AsData() const {
144  return AsDataHelper<T>(
145  (typename SequenceGenerator<sizeof...(Types)>::Sequence()));
146  }
147 
148  /// Get all elements at once, by reference.
149  inline void Get(Types&... types) {
150  std::tie(types...) = GetStdTuple();
151  }
152 
153  protected:
154  /// @cond PROTECTED
155  template<class... OtherTypes, size_t... Indices, size_t... OtherIndices>
156  inline Tuple<Types..., OtherTypes...> ConcatHelper
157  (Tuple<OtherTypes...>& other, TemplateSequence<Indices...>,
158  TemplateSequence<OtherIndices...>) {
159  return Tuple<Types..., OtherTypes...>(Get<Indices>()...,
160  other.template Get<OtherIndices>()...);
161  }
162  /// @endcond
163 
164  public:
165  /// Forms a new Tuple by concatenating two Tuples.
166  template<class... OtherTypes>
167  inline Tuple<Types..., OtherTypes...> operator+
168  (Tuple<OtherTypes...>& other) {
169  return ConcatHelper(other,
170  typename SequenceGenerator<sizeof...(Types)>::Sequence(),
171  typename SequenceGenerator<sizeof...(OtherTypes)>::Sequence());
172  }
173  };
174 
175 
176  /// A convenience generator to make a Tuple from the given elements with
177  /// type inference.
178  template<class... Types>
179  Tuple<Types...> MakeTuple(Types... types) {
180  return Tuple<Types...>(types...);
181  }
182 
183 }
184 
185 #endif // CPP11
186 
187 #endif // RC_TUPLE_H
188 
Provides a one-dimensional vector-like structure.
The version information and configuration settings for RC Lib.
Provides typedefs and routines for working with primitives.
A bounds-safe one-dimensional vector-like structure.
Definition: Data1D.h:49
An efficient Tuple class with Set, Get, and an Apply function to pass the tuple contents on to any fu...
Definition: Tuple.h:62
void Get(Types &... types)
Get all elements at once, by reference.
Definition: Tuple.h:149
auto Get() const -> decltype(this->GetHelper< N >(*this))
Return element N in the Tuple.
Definition: Tuple.h:105
Tuple(typename std::add_rvalue_reference< typename std::remove_reference< Types >::type >::type... types)
Construct by moving elements in.
Definition: Tuple.h:75
Tuple()
Default constructor, elements use default constructors.
Definition: Tuple.h:65
auto Get() -> decltype(this->GetHelper< N >(*this))
Return element N in the Tuple.
Definition: Tuple.h:100
Tuple(const typename std::add_lvalue_reference< typename std::remove_reference< Types >::type >::type... types)
Construct by const reference.
Definition: Tuple.h:69
void Set(Val val)
Set element N in the Tuple.
Definition: Tuple.h:111
std::tuple< Types... > GetStdTuple()
Returns a std::tuple of the same contents.
Definition: Tuple.h:80
Data1D< T > AsData() const
Return a Data1D array with each element constructed as type T.
Definition: Tuple.h:143
auto Apply(Func f) -> decltype(this->ApplyHelper(f,(typename SequenceGenerator< sizeof...(Types)>::Sequence())))
Call function f with each element of the Tuple as an argument.
Definition: Tuple.h:134
Definition: APtr.h:25
Tuple< Types... > MakeTuple(Types... types)
A convenience generator to make a Tuple from the given elements with type inference.
Definition: Tuple.h:179
email address
— (c) 2015