1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2009 by Fedor Pikus & Rich Sposato
4 // The copyright on this file is protected under the terms of the MIT license.
5 //
6 // Permission to use, copy, modify, distribute and sell this software for any
7 //     purpose is hereby granted without fee, provided that the above copyright
8 //     notice appear in all copies and that both that copyright notice and this
9 //     permission notice appear in supporting documentation.
10 //
11 // The author makes no claims about the suitability of this software for any
12 //     purpose. It is provided "as is" without express or implied warranty.
13 ////////////////////////////////////////////////////////////////////////////////
14 
15 // $Id$
16 
17 
18 #ifndef LOKI_INCLUDED_SAFE_BIT_FIELDS_H
19 #define LOKI_INCLUDED_SAFE_BIT_FIELDS_H
20 
21 #include <cstdlib>
22 #include <assert.h>
23 #include <loki/static_check.h>
24 
25 
26 namespace Loki
27 {
28 
29 /*
30  ==========================================================================================================================================
31    SafeBitField                    - type-safe class for bit fields.
32    SafeBitConst                    - type-safe class for bit constants.
33    SafeBitField is designed to be a [almost] drop-in replacement for integer flags and bit fields where individual bits are set and checked
34    using symbolic names for flags:
35 
36       typedef unsigned long Labels_t;
37       Labels_t labels;
38       const Labels_t Label_A = 0x00000001;
39       const Labels_t Label_B = 0x00000002;
40       ...
41       labels |= Label_B;
42       if ( labels & Label_A ) { ... }
43 
44    Such code offers no protection against mismatching bit constants and bit fields:
45 
46       typedef unsigned long Kinds_t;
47       Kinds_t kinds;
48       const Kinds_t Kind_A = 0x00000004;
49       ...
50       if ( kinds & Label_A ) { ... } // Error but compiles
51 
52    SafeBitField is a drop-in replacement which generates a unique type for each bit field. Bit fields of different types cannot be applied
53    to each other:
54 
55       LOKI_BIT_FIELD( unsigned long ) Labels_t;
56       Labels_t labels;
57       LOKI_BIT_CONST( Labels_t, Label_A, 1 );                                // 0x0001 - 1st bit is set
58       LOKI_BIT_CONST( Labels_t, Label_B, 2 );                                // 0x0002 - 1st bit is set
59       ...
60       LOKI_BIT_FIELD( unsigned long ) Kinds_t;
61       Kinds_t kinds;
62       LOKI_BIT_CONST( Kinds_t, Kind_A, 3 );                                  // 0x0004 - 1st bit is set
63       ...
64       if ( kinds & Label_A ) { ... } // Does not compile
65 
66    Several other kinds of bit field misuse are caught by safe bit fields:
67 
68       if ( kinds & Kind_A == 0 ) { ... }
69       if ( kinds && Kind_A ) { ... }
70 
71    There are few cases where drop-in replacement does not work:
72 
73    1. Operations involving bit fields and unnamed integers. Usually the integer in question is 0:
74 
75          Labels_t labels = 0;  // No longer compiles
76          if ( ( labels & Label_A ) == 0 ) { ... } // Also does not compile
77 
78       The solution is to use named bit constants, including the one for 0:
79 
80          LOKI_BIT_CONST( Labels_t, Label_None, 0 );                               // 0x0000 - No bit is set
81          Labels_t labels = Label_None; // Or just Labels_t labels; - constructor initializes to 0
82          if ( ( labels & Label_A ) == Label_None ) { ... } // // Or just if ( labels & Label_A ) { ... }
83 
84    2. I/O and other operations which require integer variables and cannot be modified:
85 
86          void write_to_db( unsigned int word );
87          Labels_t labels;
88          write_to_db( labels ); // No longer compiles
89 
90       This problem is solved by reinterpreting the bit fields as an integer, the user is responsible for using the right
91       type of integer:
92 
93          write_to_db( *((Labels_t::bit_word_t*)(&labels)) );
94 
95    ==========================================================================================================================================
96 */
97 
98 /// @par Non-Templated Initialization.
99 /// Not all compilers support template member functions where the template
100 /// arguments are not deduced but explicitly specified.  For these broken
101 /// compilers, a non-template make_bit_const() function is provided instead of
102 /// the template one. The only downside is that instead of compile-time checking
103 /// of the index argument, it does runtime checking.
104 #if defined(__SUNPRO_CC) || ( defined(__GNUC__) && (__GNUC__ < 3) )
105     #define LOKI_BIT_FIELD_NONTEMPLATE_INIT
106 #endif
107 
108 /// @par Forbidding Conversions.
109 /// This incomplete type prevents compilers from instantiating templates for
110 /// type conversions which should not happen. This incomplete type must be a
111 /// template: if the type is incomplete at the point of template definition,
112 /// the  template is illegal (although the standard allows compilers to accept
113 /// or reject such code, §14.6/, so some compilers will not issue diagnostics
114 /// unless template is instantiated). The standard-compliant way is to defer
115 /// binding to the point of instantiation by making the incomplete type itself
116 /// a template.
117 template < typename > struct Forbidden_conversion;  // This struct must not be defined!
118 
119 /// Forward declaration of the field type.
120 template <
121     unsigned int unique_index,
122     typename word_t = unsigned long
123 > class SafeBitField;
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// \class SafeBitConst Bit constants.
127 ///  This class defines a bit-field constant - a collection of unchanging bits
128 ///  used to compare to bit-fields.  Instances of this class are intended to act
129 ///  as labels for bit-fields.
130 ///
131 /// \par Safety
132 ///  - This class provides operations used for comparisons and conversions, but
133 ///    no operations which may modify the value.
134 ///  - As a templated class, it provides type-safety so bit values and constants
135 ///    used for different reasons may not be unknowingly compared to each other.
136 ///  - The unique_index template parameter insures the unique type of each bit
137 ///    bit-field.  It shares the unique_index with a similar SafeBitField.
138 ///  - Its operations only allow comparisons to other bit-constants and
139 ///    bit-fields of the same type.
140 ////////////////////////////////////////////////////////////////////////////////
141 
142 template
143 <
144     unsigned int unique_index,
145     typename word_t = unsigned long
146 >
147 class SafeBitConst
148 {
149 public:
150 
151     /// Type of the bit field is available if needed.
152     typedef word_t bit_word_t;
153     /// Corresponding field type.
154     typedef SafeBitField< unique_index, word_t > field_t;
155     /// Typedef is not allowed in friendship declaration.
156     friend class SafeBitField< unique_index, word_t >;
157 
158     // Static factory constructor, creates a bit constant with one bit set. The position of the bit is given by the template parameter,
159     // bit 1 is the junior bit, i.e. make_bit_const<1>() returns 1. Bit index 0 is a special case and returns 0.
160     // This function should be used only to initialize the static bit constant objects.
161     // This function will not compile if the bit index is outside the vaild range.
162     // There is also a compile-time assert to make sure the size of the class is the same as the size of the underlaying integer type.
163     // This assert could go into the constructor, but aCC does not seem to understand sizeof(SafeBitConst) in the constructor.
164     //
165 #ifndef LOKI_BIT_FIELD_NONTEMPLATE_INIT
make_bit_const()166     template < unsigned int i > static SafeBitConst make_bit_const()
167     {
168         LOKI_STATIC_CHECK( i <= ( 8 * sizeof(word_t) ), Index_is_beyond_size_of_data );
169         LOKI_STATIC_CHECK( sizeof(SafeBitConst) == sizeof(word_t), Object_size_does_not_match_data_size );
170         // Why check for ( i > 0 ) again inside the shift if the shift
171         // can never be evaluated for i == 0? Some compilers see shift by ( i - 1 )
172         // and complain that for i == 0 the number is invalid, without
173         // checking that shift needs evaluating.
174         return SafeBitConst( ( i > 0 ) ? ( word_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0 );
175     }
176 #else
make_bit_const(unsigned int i)177     static SafeBitConst make_bit_const( unsigned int i )
178     {
179         LOKI_STATIC_CHECK( sizeof(SafeBitConst) == sizeof(word_t), Object_size_does_not_match_data_size );
180         assert( i <= ( 8 * sizeof(word_t) ) ); // Index is beyond size of data.
181         // Why check for ( i > 0 ) again inside the shift if the shift
182         // can never be evaluated for i == 0? Some compilers see shift by ( i - 1 )
183         // and complain that for i == 0 the number is invalid, without
184         // checking that shift needs evaluating.
185         return SafeBitConst( ( i > 0 ) ? ( word_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0 );
186     }
187 #endif
188 
189     /// Default constructor allows client code to construct bit fields on the stack.
SafeBitConst()190     SafeBitConst() : word( 0 ) {}
191 
192     /// Copy constructor.
SafeBitConst(const SafeBitConst & rhs)193     SafeBitConst( const SafeBitConst& rhs ) : word( rhs.word ) {}
194 
195     /// Comparison operators which take a constant bit value.
196     bool operator == ( const SafeBitConst & rhs ) const { return word == rhs.word; }
197     bool operator != ( const SafeBitConst & rhs ) const { return word != rhs.word; }
198     bool operator <  ( const SafeBitConst & rhs ) const { return word <  rhs.word; }
199     bool operator >  ( const SafeBitConst & rhs ) const { return word >  rhs.word; }
200     bool operator <= ( const SafeBitConst & rhs ) const { return word <= rhs.word; }
201     bool operator >= ( const SafeBitConst & rhs ) const { return word >= rhs.word; }
202 
203     /// Comparision operators for mutable bit fields.
204     bool operator == ( const field_t & rhs ) const { return word == rhs.word; }
205     bool operator != ( const field_t & rhs ) const { return word != rhs.word; }
206     bool operator <  ( const field_t & rhs ) const { return word <  rhs.word; }
207     bool operator >  ( const field_t & rhs ) const { return word >  rhs.word; }
208     bool operator <= ( const field_t & rhs ) const { return word <= rhs.word; }
209     bool operator >= ( const field_t & rhs ) const { return word >= rhs.word; }
210 
211     /// Bitwise operations.  Operation-assignment operators are not needed,
212     /// since bit constants cannot be changed after they are initialized.
213     const SafeBitConst operator | ( const SafeBitConst & rhs ) const { return SafeBitConst( word | rhs.word ); }
214     const SafeBitConst operator & ( const SafeBitConst & rhs ) const { return SafeBitConst( word & rhs.word ); }
215     const SafeBitConst operator ^ ( const SafeBitConst & rhs ) const { return SafeBitConst( word ^ rhs.word ); }
216     const SafeBitConst operator ~ ( void ) const { return SafeBitConst( ~word ); }
217 
218     /// These bitwise operators return a bit-field instead of a bit-const.
219     field_t operator | ( const field_t & rhs ) const { return field_t( word | rhs.word ); }
220     field_t operator & ( const field_t & rhs ) const { return field_t( word & rhs.word ); }
221     field_t operator ^ ( const field_t & rhs ) const { return field_t( word ^ rhs.word ); }
222 
223     /// The shift operators move bits inside the bit field.  These are useful in
224     /// loops which act over bit fields and increment them.
225     const SafeBitConst operator << ( unsigned int s ) const { return SafeBitConst( word << s ); }
226     const SafeBitConst operator >> ( unsigned int s ) const { return SafeBitConst( word >> s ); }
227 
228     /// Word size is also the maximum number of different bit fields for a given word type.
size()229     static size_t size() { return ( 8 * sizeof( word_t ) ); }
230 
231 private:
232 
233     /// Copy-assignment operator is not implemented since it does not make sense
234     /// for a constant object.
235     SafeBitConst operator = ( const SafeBitConst & rhs );
236 
237     // Private constructor from an integer type.
SafeBitConst(word_t init)238     explicit SafeBitConst( word_t init ) : word( init ) {}
239 
240     /// This data stores a single bit value.  It is declared const to enforce
241     // constness for all functions of this class.
242     const word_t word;
243 
244     // Here comes the interesting stuff: all the operators designed to
245     // trap unintended conversions and make them not compile.
246     // Operators below handle code like this:
247     //    SafeBitField<1> label1;
248     //    SafeBitField<2> label2;
249     //    if ( label1 & label2 ) { ... }
250 
251     // These operators are private, and will not instantiate in any
252     // event because of the incomplete Forbidden_conversion struct.
253     template < typename T > SafeBitConst operator|( T ) const { Forbidden_conversion< T > wrong; return *this; }
254     template < typename T > SafeBitConst operator&( T ) const { Forbidden_conversion< T > wrong; return *this; }
255     template < typename T > SafeBitConst operator^( T ) const { Forbidden_conversion< T > wrong; return *this; }
256     template < typename T > SafeBitConst operator|=( T ) const { Forbidden_conversion< T > wrong; return *this; }
257     template < typename T > SafeBitConst operator&=( T ) const { Forbidden_conversion< T > wrong; return *this; }
258     template < typename T > SafeBitConst operator^=( T ) const { Forbidden_conversion< T > wrong; return *this; }
259 
260     // And the same thing for comparisons: private and unusable.
261     //    if ( label1 == label2 ) { ... }
262     template < typename T > bool operator==( const T ) const { Forbidden_conversion< T > wrong; return true; }
263     template < typename T > bool operator!=( const T ) const { Forbidden_conversion< T > wrong; return true; }
264     template < typename T > bool operator<( const T ) const { Forbidden_conversion< T > wrong; return true; }
265     template < typename T > bool operator>( const T ) const { Forbidden_conversion< T > wrong; return true; }
266     template < typename T > bool operator<=( const T ) const { Forbidden_conversion< T > wrong; return true; }
267     template < typename T > bool operator>=( const T ) const { Forbidden_conversion< T > wrong; return true; }
268 };
269 
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// \class SafeBitConst Bit constants.
273 ///  This class defines a bit-field constant - a collection of unchanging bits
274 ///  used to compare to bit-fields.  Instances of this class are intended to
275 ///  store bit values.
276 ///
277 /// \par Safety
278 ///  - This class provides operations used for comparisons and conversions, and
279 ///    also operations which may safely modify the value.
280 ///  - As a templated class, it provides type-safety so bit values and constants
281 ///    used for different reasons may not be unknowingly compared to each other.
282 ///  - The unique_index template parameter insures the unique type of each bit
283 ///    bit-field.  It shares the unique_index with a similar SafeBitConst.
284 ///  - Its operations only allow comparisons to other bit-constants and
285 ///    bit-fields of the same type.
286 ////////////////////////////////////////////////////////////////////////////////
287 
288 template
289 <
290     unsigned int unique_index,
291     typename word_t
292 >
293 class SafeBitField
294 {
295 public:
296 
297     /// Type of the bit field is available if needed.
298     typedef word_t bit_word_t;
299     /// Corresponding field type.
300     typedef SafeBitConst< unique_index, word_t > const_t;
301     /// Typedef is not allowed in friendship declaration.
302     friend class SafeBitConst<unique_index, word_t>;
303 
304     /// Default constructor allows client code to construct bit fields on the stack.
SafeBitField()305     SafeBitField() : word( 0 ) {}
306 
307     /// Copy constructor and assignment operators.
SafeBitField(const SafeBitField & rhs)308     SafeBitField( const SafeBitField & rhs ) : word( rhs.word ) {}
309     SafeBitField & operator = ( const SafeBitField & rhs ) { word = rhs.word; return *this; }
310 
311     /// Copy constructor and assignment operators from constant bit fields.
SafeBitField(const const_t & rhs)312     SafeBitField( const const_t & rhs ) : word( rhs.word ) {}
313     SafeBitField & operator = ( const const_t & rhs ) { word = rhs.word; return *this; }
314 
315     /// These comparison operators act on bit-fields of the same type.
316     bool operator == ( const SafeBitField & rhs ) const { return word == rhs.word; }
317     bool operator != ( const SafeBitField & rhs ) const { return word != rhs.word; }
318     bool operator <  ( const SafeBitField & rhs ) const { return word <  rhs.word; }
319     bool operator >  ( const SafeBitField & rhs ) const { return word >  rhs.word; }
320     bool operator <= ( const SafeBitField & rhs ) const { return word <= rhs.word; }
321     bool operator >= ( const SafeBitField & rhs ) const { return word >= rhs.word; }
322 
323     /// These comparison operators act on bit-constants of a similar type.
324     bool operator == ( const const_t & rhs ) const { return word == rhs.word; }
325     bool operator != ( const const_t & rhs ) const { return word != rhs.word; }
326     bool operator <  ( const const_t & rhs ) const { return word <  rhs.word; }
327     bool operator >  ( const const_t & rhs ) const { return word >  rhs.word; }
328     bool operator <= ( const const_t & rhs ) const { return word <= rhs.word; }
329     bool operator >= ( const const_t & rhs ) const { return word >= rhs.word; }
330 
331     /// Bitwise operations that use bit-fields.
332     SafeBitField operator |  ( const SafeBitField & rhs ) const { return SafeBitField( word | rhs.word ); }
333     SafeBitField operator &  ( const SafeBitField & rhs ) const { return SafeBitField( word & rhs.word ); }
334     SafeBitField operator ^  ( const SafeBitField & rhs ) const { return SafeBitField( word ^ rhs.word ); }
335     SafeBitField operator ~  ( void ) const { return SafeBitField( ~word ); }
336     SafeBitField operator |= ( const SafeBitField & rhs ) { word |= rhs.word; return SafeBitField( *this ); }
337     SafeBitField operator &= ( const SafeBitField & rhs ) { word &= rhs.word; return SafeBitField( *this ); }
338     SafeBitField operator ^= ( const SafeBitField & rhs ) { word ^= rhs.word; return SafeBitField( *this ); }
339 
340     /// Bitwise operators that use bit-constants.
341     SafeBitField operator |  ( const_t rhs ) const { return SafeBitField( word | rhs.word ); }
342     SafeBitField operator &  ( const_t rhs ) const { return SafeBitField( word & rhs.word ); }
343     SafeBitField operator ^  ( const_t rhs ) const { return SafeBitField( word ^ rhs.word ); }
344     SafeBitField operator |= ( const_t rhs ) { word |= rhs.word; return SafeBitField( *this ); }
345     SafeBitField operator &= ( const_t rhs ) { word &= rhs.word; return SafeBitField( *this ); }
346     SafeBitField operator ^= ( const_t rhs ) { word ^= rhs.word; return SafeBitField( *this ); }
347 
348     // Conversion to bool.
349     // This is a major source of headaches, but it's required to support code like this:
350     //    const static SafeBitConst<1> Label_value = SafeBitConst<1>::make_bit_const<1>();
351     //    SafeBitField<1> label;
352     //    if ( label & Label_value ) { ... } // Nice...
353     //
354     // The downside is that this allows all sorts of nasty conversions. Without additional precautions, bit fields of different types
355     // can be converted to bool and then compared or operated on:
356     //    SafeBitField<1> label1;
357     //    SafeBitField<2> label2;
358     //    if ( label1 == label2 ) { ... } // Yuck!
359     //    if ( label1 & label2 ) { ... } // Blech!
360     //
361     // It is somewhat safer to convert to a pointer, at least pointers to different types cannot be readilly compared, and there are no
362     // bitwise operations on pointers, but the conversion from word_t to a pointer can have run-time cost if they are of different size.
363     //
364     operator const bool() const { return ( 0 != word ); }
365 
366     // Shift operators shift bits inside the bit field. Does not make
367     // sense, most of the time, except perhaps to loop over labels and
368     // increment them.
369     SafeBitField operator <<  ( unsigned int s ) { return SafeBitField( word << s ); }
370     SafeBitField operator >>  ( unsigned int s ) { return SafeBitField( word >> s ); }
371     SafeBitField operator <<= ( unsigned int s ) { word <<= s; return *this; }
372     SafeBitField operator >>= ( unsigned int s ) { word >>= s; return *this; }
373 
374     // Word size is also the maximum number of different bit fields for
375     // a given word type.
size(void)376     static size_t size( void ) { return ( 8 * sizeof( word_t ) ); }
377 
378 private:
379 
380     /// Private constructor from an integer type. Don't put too much stock into
381     /// explicit declaration, it's better than nothing but does not solve all
382     /// problems with undesired conversions because SafeBitField coverts to bool.
SafeBitField(word_t init)383     explicit SafeBitField( word_t init ) : word( init ) {}
384 
385     /// This stores the bits.
386     word_t word;
387 
388     // Here comes the interesting stuff: all the operators designed to
389     // trap unintended conversions and make them not compile.
390     // Operators below handle code like this:
391     //    SafeBitField<1> label1;
392     //    SafeBitField<2> label2;
393     //    if ( label1 & label2 ) { ... }
394 
395     // These operators are private, and will not instantiate in any
396     // event because of the incomplete Forbidden_conversion struct.
397     template < typename T > SafeBitField operator |  ( T ) const { Forbidden_conversion< T > wrong; return *this; }
398     template < typename T > SafeBitField operator &  ( T ) const { Forbidden_conversion< T > wrong; return *this; }
399     template < typename T > SafeBitField operator ^  ( T ) const { Forbidden_conversion< T > wrong; return *this; }
400     template < typename T > SafeBitField operator |= ( T ) const { Forbidden_conversion< T > wrong; return *this; }
401     template < typename T > SafeBitField operator &= ( T ) const { Forbidden_conversion< T > wrong; return *this; }
402     template < typename T > SafeBitField operator ^= ( T ) const { Forbidden_conversion< T > wrong; return *this; }
403 
404     // And the same thing for comparisons:
405     //    if ( label1 == label2 ) { ... }
406     template < typename T > bool operator == ( const T ) const { Forbidden_conversion< T > wrong; return true; }
407     template < typename T > bool operator != ( const T ) const { Forbidden_conversion< T > wrong; return true; }
408     template < typename T > bool operator <  ( const T ) const { Forbidden_conversion< T > wrong; return true; }
409     template < typename T > bool operator >  ( const T ) const { Forbidden_conversion< T > wrong; return true; }
410     template < typename T > bool operator <= ( const T ) const { Forbidden_conversion< T > wrong; return true; }
411     template < typename T > bool operator >= ( const T ) const { Forbidden_conversion< T > wrong; return true; }
412 };
413 
414 // The above template member operators catch errors when the first
415 // argument to a binary operator is a label, but they don't work when
416 // the first argument is an integer and the second one is a label: the
417 // label converts to bool and the operator is performed on two integers.
418 // These operators catch errors like this:
419 //    SafeBitField<1> label1;
420 //    SafeBitField<2> label2;
421 //    if ( !label1 & label2 ) { ... }
422 // where the first label is converted to bool (these errors cannot be
423 // caught by member operators of SafeBitField class because the first
424 // argument is not SafeBitField but bool.
425 //
426 // If used, these operators will not instantiate because of the
427 // incomplete Forbidden_conversion struct.
428 
429 template < unsigned int unique_index, typename word_t >
430 inline SafeBitField< unique_index, word_t > operator & ( bool, SafeBitField< unique_index, word_t > rhs )
431 {
432     Forbidden_conversion<word_t> wrong;
433     return rhs;
434 }
435 
436 template < unsigned int unique_index, typename word_t >
437 inline SafeBitField< unique_index, word_t > operator | ( bool, SafeBitField< unique_index, word_t > rhs )
438 {
439     Forbidden_conversion< word_t > wrong;
440     return rhs;
441 }
442 
443 template < unsigned int unique_index, typename word_t >
444 inline SafeBitField< unique_index, word_t > operator ^ ( bool, SafeBitField< unique_index, word_t > rhs )
445 {
446     Forbidden_conversion< word_t > wrong;
447     return rhs;
448 }
449 
450 template < unsigned int unique_index, typename word_t >
451 inline SafeBitField< unique_index, word_t > operator == ( bool, SafeBitField< unique_index, word_t > rhs )
452 {
453     Forbidden_conversion< word_t > wrong;
454     return rhs;
455 }
456 
457 template < unsigned int unique_index, typename word_t >
458 inline SafeBitField< unique_index, word_t > operator != ( bool, SafeBitField< unique_index, word_t > rhs )
459 {
460     Forbidden_conversion< word_t > wrong;
461     return rhs;
462 }
463 
464 // Finally, few macros. All macros are conditionally defined to use the SafeBitField classes if LOKI_SAFE_BIT_FIELD is defined. Otherwise,
465 // the macros fall back on the use of typedefs and integer constants. This provides no addititonal safety but allows the code to support the
466 // mixture of compilers which are broken to different degrees.
467 #define LOKI_SAFE_BIT_FIELD
468 
469 // The first macro helps to declare new bit field types:
470 // LOKI_BIT_FIELD( ulong ) field_t;
471 // This creates a typedef field_t for SafeBitField<unique_index, ulong> where index is the current line number. Since line numbers __LINE__ are counted
472 // separately for all header files, this ends up being the same type in all files using the header which defines field_t.
473 #ifdef LOKI_SAFE_BIT_FIELD
474     #define LOKI_BIT_FIELD( word_t ) typedef SafeBitField<__LINE__, word_t>
475 #else
476     #define LOKI_BIT_FIELD( word_t ) typedef word_t
477 #endif // LOKI_SAFE_BIT_FIELD
478 
479 // The second macro helps to declare static bit constants:
480 // LOKI_BIT_CONST( field_t, Label_1, 1 );
481 // creates new bit field object named Label_1 of type field_t which represents the field with the 1st (junior) bit set.
482 #ifdef LOKI_SAFE_BIT_FIELD
483     #ifndef LOKI_BIT_FIELD_NONTEMPLATE_INIT
484         #define LOKI_BIT_CONST( field_t, label, bit_index ) \
485             static const field_t::const_t label = field_t::const_t::make_bit_const<bit_index>()
486     #else
487         #define LOKI_BIT_CONST( field_t, label, bit_index ) \
488             static const field_t::const_t label = field_t::const_t::make_bit_const( bit_index )
489     #endif // LOKI_BIT_FIELD_NONTEMPLATE_INIT
490 #else
make_bit_const(size_t i)491     inline size_t make_bit_const( size_t i ) { return ( i > 0 ) ? ( size_t(1) << ( ( i > 0 ) ? ( i - 1 ) : 0 ) ) : 0; }
492     #define LOKI_BIT_CONST( field_t, label, bit_index ) static const field_t label = make_bit_const( bit_index )
493 #endif // LOKI_SAFE_BIT_FIELD
494 
495 // The third macro helps to declare complex bit constants which are combination of several bits:
496 // LOKI_BIT_CONSTS( field_t, Label12 ) = Label_1 | Label_2;
497 #ifdef LOKI_SAFE_BIT_FIELD
498     #define LOKI_BIT_CONSTS( field_t, label ) static const field_t::const_t label
499 #else
500     #define LOKI_BIT_CONSTS( field_t, label ) static const field_t label
501 #endif // LOKI_SAFE_BIT_FIELD
502 
503 // The fourth macro helps to declare the maximum number of bit constants for a given type:
504 // static const size_t count = LOKI_BIT_FIELD_COUNT( field_t );
505 // declared a variable "count" initialized to field_t::size()
506 #ifdef LOKI_SAFE_BIT_FIELD
507     #define LOKI_BIT_FIELD_COUNT( field_t ) field_t::size()
508 #else
509     #define LOKI_BIT_FIELD_COUNT( field_t ) ( 8 * sizeof(field_t) )
510 #endif // LOKI_SAFE_BIT_FIELD
511 
512 } // namespace Loki
513 
514 #endif // LOKI_INCLUDED_SAFE_BIT_FIELDS_H
515