fixedTuple.h
Engine/source/console/fixedTuple.h
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:
fixed_tuple_offset(const fixed_tuple< Ts... > & t)
fixed_tuple_offset(fixed_tuple< Ts... > & t)
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:
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