fixedTuple.h

Engine/source/console/fixedTuple.h

More...

Classes:

Fixed-layout tuple definition

These structs and templates serve as a way to pass arguments from external applications and into the T3D console system.

They work as std::tuple, but they ensure a standardized fixed memory layout. Allowing for unmanaged calls with these tuples as the parameter lists.

The implementation is from a SO solution: https://codereview.stackexchange.com/a/52279 As out use-case is pretty simple, this code could probably be simplified by stripping out a lot of extra functionality. But eh.

Detailed Description

Fixed-layout tuple definition

These structs and templates serve as a way to pass arguments from external applications and into the T3D console system.

They work as std::tuple, but they ensure a standardized fixed memory layout. Allowing for unmanaged calls with these tuples as the parameter lists.

The implementation is from a SO solution: https://codereview.stackexchange.com/a/52279 As out use-case is pretty simple, this code could probably be simplified by stripping out a lot of extra functionality. But eh.

fixed_tuple_offset(const fixed_tuple< Ts... > & t)

fixed_tuple_offset(fixed_tuple< Ts... > & t)

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _FIXEDTUPLE_H_
 25#define _FIXEDTUPLE_H_
 26
 27#include "engineTypes.h"
 28
 29/// @name Fixed-layout tuple definition
 30/// These structs and templates serve as a way to pass arguments from external 
 31/// applications and into the T3D console system.
 32/// They work as std::tuple, but they ensure a standardized fixed memory 
 33/// layout. Allowing for unmanaged calls with these tuples as the parameter 
 34/// lists.
 35///
 36/// The implementation is from a SO solution:
 37/// https://codereview.stackexchange.com/a/52279
 38/// As out use-case is pretty simple, this code could probably be simplified by 
 39/// stripping out a lot of extra functionality. But eh.
 40///
 41/// @{
 42
 43template <typename ...Ts>
 44struct fixed_tuple;
 45
 46template <typename T, typename ...Ts>
 47struct fixed_tuple<T, Ts...>
 48{
 49   T first;
 50   fixed_tuple<Ts...> rest;
 51
 52   fixed_tuple() = default;
 53   template <class U, class...Us, class = typename ::std::enable_if<!::std::is_base_of<fixed_tuple, typename ::std::decay<U>::type>::value>::type>
 54   fixed_tuple(U&& u, Us&&...tail) :
 55      first(::std::forward<U>(u)),
 56      rest(::std::forward<Us>(tail)...) {}
 57};
 58
 59template <typename T>
 60struct fixed_tuple<T>
 61{
 62   T first;
 63
 64   fixed_tuple() = default;
 65   template <class U, class = typename ::std::enable_if<!::std::is_base_of<fixed_tuple, typename ::std::decay<U>::type>::value>::type>
 66   fixed_tuple(U&& u) :
 67      first(::std::forward<U>(u)) {}
 68};
 69
 70template <>
 71struct fixed_tuple<> {};
 72
 73
 74template < ::std::size_t i, class T>
 75struct fixed_tuple_element;
 76
 77template < ::std::size_t i, class T, class... Ts>
 78struct fixed_tuple_element<i, fixed_tuple<T, Ts...> >
 79   : fixed_tuple_element<i - 1, fixed_tuple<Ts...> >
 80{};
 81
 82template <class T, class... Ts>
 83struct fixed_tuple_element<0, fixed_tuple<T, Ts...> >
 84{
 85   using type = T;
 86};
 87
 88template < ::std::size_t i>
 89struct fixed_tuple_accessor
 90{
 91   template <class... Ts>
 92   static inline typename fixed_tuple_element<i, fixed_tuple<Ts...> >::type & get(fixed_tuple<Ts...> & t)
 93   {
 94      return fixed_tuple_accessor<i - 1>::get(t.rest);
 95   }
 96
 97   template <class... Ts>
 98   static inline const typename fixed_tuple_element<i, fixed_tuple<Ts...> >::type & get(const fixed_tuple<Ts...> & t)
 99   {
100      return fixed_tuple_accessor<i - 1>::get(t.rest);
101   }
102};
103
104template <>
105struct fixed_tuple_accessor<0>
106{
107   template <class... Ts>
108   static inline typename fixed_tuple_element<0, fixed_tuple<Ts...> >::type & get(fixed_tuple<Ts...> & t)
109   {
110      return t.first;
111   }
112
113   template <class... Ts>
114   static inline const typename fixed_tuple_element<0, fixed_tuple<Ts...> >::type & get(const fixed_tuple<Ts...> & t)
115   {
116      return t.first;
117   }
118};
119
120#pragma warning( push )
121#pragma warning( disable : 4267 )
122template <size_t I, class... Ts>
123static U32 fixed_tuple_offset(fixed_tuple<Ts...>& t)
124{
125   return (U32)((size_t)& fixed_tuple_accessor<I>::get(t)) - ((size_t)& t);
126}
127
128template <size_t I, class... Ts>
129static U32 fixed_tuple_offset(const fixed_tuple<Ts...>& t)
130{
131   return (U32)((size_t)& fixed_tuple_accessor<I>::get(t)) - ((size_t)& t);
132}
133#pragma warning(pop)
134
135template< typename T1, typename T2 >
136struct fixed_tuple_mutator {};
137
138template<typename... Tdest, typename... Tsrc>
139struct fixed_tuple_mutator<void(Tdest...), void(Tsrc...)>
140{
141   template<std::size_t I = 0>
142   static inline typename std::enable_if<I == sizeof...(Tsrc), void>::type
143      copy_r_t_l(fixed_tuple<Tsrc...>& src, fixed_tuple<Tdest...>& dest)
144   { }
145
146   template<std::size_t I = 0>
147   static inline typename std::enable_if<I < sizeof...(Tsrc), void>::type
148      copy_r_t_l(fixed_tuple<Tsrc...>& src, fixed_tuple<Tdest...>& dest)
149   {
150      fixed_tuple_accessor<I + (sizeof...(Tdest)-sizeof...(Tsrc))>::get(dest) = fixed_tuple_accessor<I>::get(src);
151      copy_r_t_l<I + 1>(src, dest);
152   }
153
154   template<std::size_t I = 0>
155   static inline typename std::enable_if<I == sizeof...(Tsrc), void>::type
156      copy(std::tuple<Tsrc...>& src, fixed_tuple<Tdest...>& dest)
157   { }
158
159   template<std::size_t I = 0>
160   static inline typename std::enable_if<I < sizeof...(Tsrc), void>::type
161      copy(std::tuple<Tsrc...>& src, fixed_tuple<Tdest...>& dest)
162   {
163      fixed_tuple_accessor<I>::get(dest) = std::get<I>(src);
164      copy<I + 1>(src, dest);
165   }
166};
167
168
169/// @}
170
171
172#endif // !_FIXEDTUPLE_H_
173