Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
size_of.h
1 /// @file meta/size_of.h
2 ///
3 /// Calculates the size in bytes of the type at the specified index in the
4 /// Type Container.
5 ///
6 /// The MIT License(MIT)
7 /// @copyright 2014 Paul M Watt
8 // ****************************************************************************
9 #ifndef SIZE_OF_H_INCLUDED
10 #define SIZE_OF_H_INCLUDED
11 // Includes ********************************************************************
12 #include <Pb/meta_fwd.h>
13 #include <Pb/container_size.h>
14 #include <Pb/dynamic.h>
15 
16 namespace Hg
17 {
18 
19 // Forward Declaraions ********************************************************
20 template <typename T>
21 struct SizeOf;
22 
23 template< class T,
24  size_t N
25  >
26 struct BitFieldArray;
27 
28 template< class T,
29  class A
30  >
31 struct BitFieldVector;
32 
33 
34 // This namespace contains specialized versions of the SizeOf implementation
35 // to help differentiate between type_containers and intrinsic types.
36 namespace detail
37 {
38 
39 // ****************************************************************************
40 // Parameterized implementation of SizeOf
41 //
42 template <typename T, bool isContainer = false >
43 struct SizeOf_Impl
44  : std::integral_constant<size_t, sizeof(T)>
45 { };
46 
47 // ****************************************************************************
48 // Arrays size should only include the elements in the array.
49 // However, if the array contains a dynamically sized field, the size cannot
50 // be determined at compile-time and must be performed at runtime.
51 //
52 template< typename T,
53  size_t N
54  >
55 struct SizeOf_Impl<Hg::BitFieldArray<T,N>, true>
56  : std::integral_constant< size_t, Hg::SizeOf<T>::value * N>
57 { };
58 
59 
60 // ****************************************************************************
61 // Calculates the size of an array of types.
62 //
63 template< typename T,
64  size_t N,
65  bool IsNestedT
66  >
67 struct SizeOf_Array
68  : std::integral_constant< size_t, Hg::SizeOf<T>::value * N>
69 { };
70 
71 // ****************************************************************************
72 // Calculates the size of an array of nested_types.
73 //
74 template< typename T,
75  size_t N
76  >
77 struct SizeOf_Array<T,N,true>
78  : std::integral_constant< size_t, Hg::SizeOf<typename T::format_type>::value * N>
79 { };
80 
81 // ****************************************************************************
82 // Arrays size should only include the elements in the array.
83 //
84 template< typename T,
85  size_t N
86  >
87 struct SizeOf_Impl<std::array<T,N>, false>
88  : SizeOf_Array<T, N, std::is_base_of<nested_trait, T>::value>
89 { };
90 
91 // ****************************************************************************
92 // The size of BitFieldVectors must be determined at runtime.
93 //
94 template< class T,
95  class A
96  >
97 struct SizeOf_Impl<Hg::BitFieldVector<T,A>, false>
98  : std::integral_constant< size_t, 0>
99 { };
100 
101 // ****************************************************************************
102 // Vectors size is dynamically determined at runtime.
103 //
104 template< class T,
105  class A
106  >
107 struct SizeOf_Impl<std::vector<T,A>, false>
108  : std::integral_constant< size_t, 0>
109 { };
110 
111 // ****************************************************************************
112 // SizeOf implementation for type_containers
113 //
114 template <typename T>
115 struct SizeOf_Impl<T, true>
116  : std::integral_constant< size_t,
117  ContainerSize<T>::value
118  >
119 { };
120 
121 } // namespace detail
122 
123 
124 // ****************************************************************************
125 /// Template to determine the size of a type or type container.
126 ///
127 /// This template will test the type T to determine if it is a type_container.
128 /// If so a specialize version of the size calculator will be used.
129 ///
130 /// The default implementation uses the sizeof operator on type T.
131 ///
132 template <typename T>
133 struct SizeOf
134  : detail::SizeOf_Impl<T, type_container<T>::value>
135 { };
136 
137 } // namespace Hg
138 
139 #endif