Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dynamic.h
1 /// @file meta/dynamic.h
2 ///
3 /// Provides utility functions for dynamically sized field-types.
4 ///
5 /// The MIT License(MIT)
6 /// @copyright 2014 Paul M Watt
7 // ****************************************************************************
8 #ifndef DYNAMIC_H_INCLUDED
9 #define DYNAMIC_H_INCLUDED
10 // Includes *******************************************************************
11 #include <Pb/meta_fwd.h>
12 #include <Pb/type_list.h>
13 #include <Pb/type_at.h>
14 #include <Pb/integer_sequence.h>
15 
16 namespace Hg
17 {
18 
19 
20 // Forward Declarations *******************************************************
21 template <typename T>
22 struct has_dynamic;
23 
24 namespace detail
25 {
26 
27 // Parameterized implementation of HasDynamic **********************************
28 template <typename T, bool isContainer = false >
29 struct HasDynamic_Impl
30  : std::false_type
31 { };
32 
33 // HasDynamic implementation for type_containers *******************************
34 template <typename T>
35 struct HasDynamic_Impl<T, true>
36  : value_if< vector_value<typename front<T>::type>::value,
37  bool,
38  true,
39  has_dynamic<typename pop_front<T>::type>::value
40  >
41 { };
42 
43 // Explicit HasDynamic implementation for vectors ******************************
44 template< class T,
45  class A,
46  bool isContainerT
47  >
48 struct HasDynamic_Impl<std::vector<T,A>, isContainerT>
49  : std::true_type
50 { };
51 
52 // ****************************************************************************
53 template< typename ListT,
54  typename SeqT,
55  size_t IdxT
56  >
57 struct DynamicFieldSequence
58 {
59  typedef typename
60  std::conditional< vector_value<typename front<ListT>::type>::value,
61  typename IntegralNode<IdxT, SeqT>::type,
62  SeqT
63  >::type NextSeqT;
64 
65  typedef typename
66  DynamicFieldSequence< typename pop_front<ListT>::type,
67  NextSeqT,
68  IdxT+1
69  >::type type;
70 };
71 
72 // ****************************************************************************
73 // Terminating case for an MT typelist simply becomes the specified sequence.
74 // The final list that is received in SeqT will be reveresed. Therefore a
75 // call to reverse is made to correct the order before the result is defined.
76 //
77 template< typename SeqT,
78  size_t IdxT
79  >
80 struct DynamicFieldSequence<MT, SeqT, IdxT>
81  : reverse<SeqT>
82 {
83  typedef SeqT NextSeqT;
84 };
85 
86 
87 // Parameterized implementation of HasDynamic **********************************
88 template <typename T, bool IsHaveDynamicT = false >
89 struct DynamicFields_Impl
90 {
91  typedef MT type;
92 };
93 
94 // HasDynamic implementation for type_containers *******************************
95 template <typename T>
96 struct DynamicFields_Impl<T, true>
97  : DynamicFieldSequence<T, MT, 0>
98 { };
99 
100 } // namespace detail
101 
102 // ****************************************************************************
103 /// Template to determine if a container has any dynamically sized entry types.
104 ///
105 /// This template will test the type T to determine if it is a type_container.
106 /// If so a specialize version of the dynamic type test will be used.
107 ///
108 /// Sequential types that contain dynamically sized elements are considered
109 /// dynamic.
110 ///
111 ///
112 template <typename T>
113 struct has_dynamic
114  : detail::HasDynamic_Impl<T, type_container<T>::value>
115 { };
116 
117 // ****************************************************************************
118 /// Extracts index values of the vector types in a message.
119 ///
120 template <typename T>
122  : detail::DynamicFields_Impl<T, has_dynamic<T>::value>
123 { };
124 
125 } // namespace Hg
126 
127 #endif