Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
bit_field.h
1 /// @file BitField.h
2 ///
3 /// Defines the BitField construct for Alchemy Message Fields.
4 /// This meta object keeps track of bit-field definitions for a message
5 /// structure.
6 ///
7 /// The MIT License(MIT)
8 /// @copyright 2014 Paul M Watt
9 // ****************************************************************************
10 #ifndef BIT_FIELD_H_INCLUDED
11 #define BIT_FIELD_H_INCLUDED
12 // Includes ******************************************************************
13 #include <Pb/compiler.h>
14 
15 namespace Hg
16 {
17 
18 // ****************************************************************************
19 /// Represents a single entry for a bit field type definition.
20 ///
21 /// In order for BitFields to be packed into a single byte, the BitFields
22 /// must be grouped in a BitSet definition.
23 /// This type must be contained within another class that supports a function
24 /// called value() that returns a value that is convertable to type T.
25 ///
26 /// @note The total number of requested bits must fit within the
27 /// specified data-field type. The default is a 8-bit byte.
28 ///
29 template <class OwnerT,
30  class TagT,
31  size_t OffsetT,
32  size_t CountT,
33  class T = uint8_t>
34 struct BitField
35 {
36  static_assert(CountT <= (sizeof(T)* 8),
37  "The number of bits in the BitField cannot exceed the size of the host type T.");
38 
39  // Typedefs ******************************************************************
41  typedef T value_type;
42 
43  // Constants *****************************************************************
44  enum { k_offset = OffsetT };
45  enum { k_size = CountT };
46 
47  /// The BitField Mask can be described with this formula:
48  ///
49  /// Mask = (2 ^ (number of bits))-1 << shifted to the left by offset bits.
50  ///
51  enum { k_mask = T(((tmp::math::pow<size_t, 2, k_size>::value)-1) << k_offset) };
52 
53  // ****************************************************************************
54  BitField()
55  { }
56 
57  // Operators *****************************************************************
58  operator value_type()
59  {
60  return mask_value();
61  }
62 
63  // ****************************************************************************
64  value_type operator=(const value_type& rhs)
65  {
66  value_type& base_value = value();
67  base_value &= ~k_mask;
68  base_value |= k_mask & (rhs << k_offset);
69 
70  return mask_value();
71  }
72 
73  // ****************************************************************************
74  BitField& operator=(const BitField& rhs)
75  {
76  value_type value = rhs.value() & k_mask;
77  value_type& base_value = value() & ~k_mask;
78  base_value |= value & k_mask;
79 
80  return *this;
81  }
82 
83  value_type mask_value()
84  {
85  return (value() & k_mask) >> k_offset;
86  }
87 private:
88  // Member Functions **********************************************************
89  // ***************************************************************************
90  value_type& value()
91  {
92  return owner()->value();
93  }
94 
95 
96  OwnerT* owner()
97  {
98  return reinterpret_cast<OwnerT*>( reinterpret_cast<char*>(this)
99  - TagT::offset());
100  }
101 };
102 
103 } // namespace Hg
104 
105 
106 #endif