OSVR-Core
TypeKeyed.h
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 // TypePack is part of OSVR-Core.
13 //
14 // Use, modification and distribution is subject to the
15 // Boost Software License, Version 1.0. (See accompanying
16 // file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
18 
19 #ifndef INCLUDED_TypeKeyed_h_GUID_49539B71_1F6F_4A84_B681_4FD65F87A2A8
20 #define INCLUDED_TypeKeyed_h_GUID_49539B71_1F6F_4A84_B681_4FD65F87A2A8
21 
22 // Internal Includes
23 #include "Contains.h"
24 #include "FindFirst.h"
25 #include "T.h"
26 
27 // Library/third-party includes
28 // - none
29 
30 // Standard includes
31 #include <tuple>
32 #include <type_traits>
33 
34 namespace osvr {
35 namespace typepack {
36  // Forward declaration
37  template <typename Derived> class TypeKeyedBase;
38 
39  namespace typekeyed_detail {
43  template <typename Derived, typename Key>
45 
50  template <typename Derived> struct KeyTypesTraits {
51  using type = typename Derived::key_types;
52  };
53 
56  template <typename Derived>
58 
61  template <typename Derived, typename Key>
63 
66  template <typename Derived, typename Key>
68 
71  template <typename Derived, typename Key>
73 
76  template <typename Derived, typename Key>
77  using ref_type_at_key =
78  std::add_lvalue_reference<value_type_at_key<Derived, Key>>;
79 
82  template <typename Derived, typename Key>
83  using rref_type_at_key =
84  std::add_rvalue_reference<value_type_at_key<Derived, Key>>;
85 
88  template <typename Derived, typename Key>
89  using cref_type_at_key = std::add_lvalue_reference<
91 
102  template <typename Derived, typename Key> struct ValueAccessor {
103  static_assert(valid_key<Derived, Key>::value,
104  "Key type not found in the list!");
105  using reference = typename ref_type_at_key<Derived, Key>::type;
106  using rvalue_reference =
108  using const_reference =
110  using Index = index<Derived, Key>;
111  static reference get_reference(TypeKeyedBase<Derived> &c);
112  static const_reference
113  get_const_reference(TypeKeyedBase<Derived> const &c);
114  static rvalue_reference
115  get_rvalue_reference(TypeKeyedBase<Derived> &&c);
116  };
117 
118  // forward declaration
119  template <typename Key, typename Derived>
121  get(TypeKeyedBase<Derived> &c);
122 
123  // forward declaration
124  template <typename Key, typename Derived>
127 
128  // forward declaration
129  template <typename Key, typename Derived>
131  cget(TypeKeyedBase<Derived> const &c);
132  } // namespace typekeyed_detail
133 
138  template <typename Derived> class TypeKeyedBase {
139  public:
140  using DerivedType = Derived;
141 
144  template <typename Key>
146  get(Key const * = nullptr) {
147  return typekeyed_detail::get<Key>(*this);
148  }
149 
152  template <typename Key>
154  get(Key const * = nullptr) const {
155  return typekeyed_detail::cget<Key>(*this);
156  }
157 
158  private:
160  DerivedType &derived() { return *static_cast<DerivedType *>(this); }
161 
163  DerivedType const &derived() const {
164  return *static_cast<DerivedType const *>(this);
165  }
166 
168  DerivedType const &const_derived() const {
169  return *static_cast<DerivedType const *>(this);
170  }
171 
172  // befriend the only consumer of our `derived()` methods.
173  template <typename, typename>
174  friend struct typekeyed_detail::ValueAccessor;
175  };
176 
177  namespace typekeyed_detail {
178  template <typename Derived, typename Key>
179  inline typename ref_type_at_key<Derived, Key>::type
180  ValueAccessor<Derived, Key>::get_reference(TypeKeyedBase<Derived> &c) {
181  return std::get<Index::value>(c.derived().nested_container());
182  }
183  template <typename Derived, typename Key>
184  inline typename cref_type_at_key<Derived, Key>::type
185  ValueAccessor<Derived, Key>::get_const_reference(
186  TypeKeyedBase<Derived> const &c) {
187  return std::get<Index::value>(c.derived().nested_container());
188  }
189  template <typename Derived, typename Key>
190  inline typename rref_type_at_key<Derived, Key>::type
191  ValueAccessor<Derived, Key>::get_rvalue_reference(
193  return std::forward<rvalue_reference>(
194  std::get<Index::value>(c.derived().nested_container()));
195  }
198  template <typename Key, typename Derived>
199  inline typename ref_type_at_key<Derived, Key>::type
201  static_assert(valid_key<Derived, Key>::value,
202  "Key type not found in the list!");
204  }
207  template <typename Key, typename Derived>
210  static_assert(valid_key<Derived, Key>::value,
211  "Key type not found in the list!");
212  return std::forward<rref_type_at_key<Derived, Key>>(
214  std::forward<TypeKeyedBase<Derived> &&>(c)));
215  }
216 
219  template <typename Key, typename Derived>
222  static_assert(valid_key<Derived, Key>::value,
223  "Key type not found in the list!");
225  }
226 
227  } // namespace typekeyed_detail
228 
233  template <typename Key, typename Derived>
236  return typekeyed_detail::get<Key>(c);
237  }
238 
243  template <typename Key, typename Derived>
246  return std::forward<typekeyed_detail::rref_type_at_key<Derived, Key>>(
247  typekeyed_detail::rget<Key>(c));
248  }
256  template <typename Key, typename Derived>
259  return typekeyed_detail::cget<Key>(c);
260  }
261 } // namespace typepack
262 } // namespace osvr
263 #endif // INCLUDED_TypeKeyed_h_GUID_49539B71_1F6F_4A84_B681_4FD65F87A2A8
apply_list< quote< or_ >, transform< Haystack, detail::is_< Needle >>> contains
Determines if type Needle is in the list Haystack - is an alias for a type that inherits std::true_ty...
Definition: Contains.h:49
Class with static members performing the actual access.
Definition: TypeKeyed.h:102
CRTP base for type-keyed data types, providing a unified interface (compile-time polymorphism) and sh...
Definition: TypeKeyed.h:37
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
typekeyed_detail::cref_type_at_key< Derived, Key >::type cget(TypeKeyedBase< Derived > const &c)
Gets a reference to a constant value in a type-keyed container using the specified key type...
Definition: TypeKeyed.h:258
Header.
traits class that MUST be specialized for each type-keyed container: should contain a using type = de...
Definition: TypeKeyed.h:44
cref_type_at_key< Derived, Key >::type cget(TypeKeyedBase< Derived > const &c)
Gets an lvalue-reference to a constant value in a type-keyed container using the specified key type...
Definition: TypeKeyed.h:221
A class that uses types as an index into a container with uniform-typed contents, somewhat like a map...
Definition: TypeKeyedMap.h:49
std::add_lvalue_reference< t_< std::add_const< value_type_at_key< Derived, Key >>>> cref_type_at_key
Gets the corresponding reference to constant value type in a given type-keyed container for a given k...
Definition: TypeKeyed.h:90
traits class that can be specialized for each type-keyed container: should contain a using type = dec...
Definition: TypeKeyed.h:50
Header.
find_first< key_types< Derived >, Key > index
Gets the index of the key in a key list for a given type-keyed container.
Definition: TypeKeyed.h:67
std::add_rvalue_reference< value_type_at_key< Derived, Key >> rref_type_at_key
Gets the corresponding rvalue-reference to value type in a given type-keyed container for a given key...
Definition: TypeKeyed.h:84
t_< detail::find_first_impl< Needle, 0, List >> find_first
Returns the zero-based index of the first instance of Needle in List.
Definition: FindFirst.h:61
typename T::type t_
A convenience alias template to extract the nested type within the supplied T.
Definition: T.h:52
typekeyed_detail::rref_type_at_key< Derived, Key >::type rget(TypeKeyedBase< Derived > &&c)
Gets an rvalue-reference to a value in a type-keyed container using the specified key type...
Definition: TypeKeyed.h:245
rref_type_at_key< Derived, Key >::type rget(TypeKeyedBase< Derived > &&c)
Gets a rvalue-reference to a value in a type-keyed container using the specified key type...
Definition: TypeKeyed.h:209
std::add_lvalue_reference< value_type_at_key< Derived, Key >> ref_type_at_key
Gets the corresponding reference to value type in a given type-keyed container for a given key type...
Definition: TypeKeyed.h:78
t_< ValueTypeAtKeyTraits< Derived, Key >> value_type_at_key
Gets the corresponding value type in a given type-keyed container for a given key type...
Definition: TypeKeyed.h:72
Header.
t_< KeyTypesTraits< Derived >> key_types
Gets key types list for a given type-keyed container, using the traits class.
Definition: TypeKeyed.h:57
contains< key_types< Derived >, Key > valid_key
Returns an integral_constant for whether a given key is valid for a given type-keyed container...
Definition: TypeKeyed.h:62