Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
container_size.h
1 /// @file meta/container_size.h
2 ///
3 /// The ContainerSize construct returns the size of a type container.
4 ///
5 /// The ContainerSize type construct will return the size of any
6 /// **type_container** type. A type qualifies as a type_container if it has a
7 /// specialization of the type_container<T> where T evaluates to true.
8 ///
9 /// By default, T is false for all types with no specialization.
10 ///
11 /// If one of these types is used with ContainerSize, a compile-time
12 /// error will be thrown due to the type_check<> below.
13 ///
14 /// The MIT License(MIT)
15 /// @copyright 2014 Paul M Watt
16 // ****************************************************************************
17 #ifndef CONTAINER_SIZE_H_INCLUDED
18 #define CONTAINER_SIZE_H_INCLUDED
19 // Includes *******************************************************************
20 #include <Pb/meta_fwd.h>
21 #include <Pb/length.h>
22 
23 namespace Hg
24 {
25 
26 // This namespace contains specialized versions of the ContainerSize implementation
27 // to help differentiate between type_containers and vector_value types.
28 namespace detail
29 {
30 
31 
32 // ***************************************************************************
33 /// Detect if the specified type has a type member called 'format_type'.
34 ///
35 template < typename T >
37 {
38 private:
39  // Identify by using a pointer to a member
40  template < typename U >
41  static yes_t <typename U::format_type> selector(U);
42  static no_t selector(...);
43 
44  static T* this_t();
45 public:
46  static const bool value =
47  sizeof(selector(*this_t())) != sizeof(no_t);
48 };
49 
50 
51 // Parameterized implementation of ContainerSize *******************************
52 template <typename T, bool use_format_type = has_format_type<T>::value>
53 struct ContainerSize_Impl
54  : std::integral_constant< size_t,
55  OffsetOf< Hg::length<T>::value, T>::value
56  >
57 { };
58 
59 template <typename T>
60 struct ContainerSize_Impl<T, true>
61  : std::integral_constant< size_t,
62  OffsetOf< Hg::length< typename T::format_type>::value,
63  typename T::format_type
64  >::value
65  >
66 { };
67 
68 } // namespace detail
69 
70 // ****************************************************************************
71 /// Calculates the static size of the container passed in.
72 /// This value is equivalent to the offset of the "end" item in the container.
73 ///
74 /// @note type_check: ContainerT must be a type_container
75 /// Intrinsic value types such as char, float, int as well as
76 /// user-defined classes will trigger this assertion.
77 ///
78 template <typename ContainerT>
80  : type_check<type_container<ContainerT>::value>
81  , detail::ContainerSize_Impl< ContainerT>
82 { };
83 
84 } // namespace Hg
85 
86 #endif