Advertisement
Guest User

C++98 compatible binary literal implementation

a guest
Apr 5th, 2017
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.27 KB | None | 0 0
  1. //*****************************************************************************
  2. //
  3. // Author       : Trotzky Vasily
  4. // Date         : Apr 05 2017
  5. // All rights reserved.
  6.  
  7. // This is C++98 compatible binary literal implementation with no runtime overhead.
  8.  
  9. // You should enter exactly 8 digits for each byte, only 1 and 0 are allowed
  10. // otherwise it will not compile and will fall to assert.
  11. //
  12. // Use as follows:
  13. // static const uint8_t BinaryLiteralTest = BinaryLiteral8bit(10100101);
  14. // static const uint16_t BinaryLiteralTest16 = BinaryLiteral16bit(00100000,00010000);
  15. // static const uint32_t BinaryLiteralTest32 = BinaryLiteral32bit(10000000,01000000,00100000,00010000);
  16.  
  17.  
  18. // Redistribution and use in source and binary forms, with or without modification,
  19. // are permitted provided that the following conditions are met:
  20. // Redistributions of source code must retain the above copyright notice,
  21. // this list of conditions and the following disclaimer.
  22.  
  23. // Redistributions in binary form must reproduce the above copyright notice,
  24. // this list of conditions and the following disclaimer in the documentation and/or
  25. // other materials provided with the distribution.
  26.  
  27. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  30. // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  31. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  32. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  34. // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  35. // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  36. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. //*****************************************************************************
  38.  
  39. #include <stdint.h>
  40.  
  41. #ifndef BINARYLITERAL_HPP_
  42. #define BINARYLITERAL_HPP_
  43.  
  44. namespace BINARYLITERAL_HPP_private
  45. {  
  46.     //modified C++98 static assert implementation from Boost library
  47.     #define BINARYLITERALCONCAT2(First, Second) (First ## Second)
  48.     #define BINARYLITERALCONCAT(First, Second) BINARYLITERALCONCAT2(First, Second) 
  49.     namespace boost
  50.     {
  51.         template <bool x> struct STATIC_ASSERTION_FAILURE;
  52.         template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
  53.         template<int x> struct static_assert_test{};
  54.     }
  55.     #define BINARYLITERAL_STATIC_ASSERT_BOOL_CAST(x) (bool)(x)
  56.     #ifdef __GNUC__
  57.     #define BINARYLITERAL_STATIC_ASSERT( B ) \
  58.        typedef boost::static_assert_test<\
  59.           sizeof(boost::STATIC_ASSERTION_FAILURE< BINARYLITERAL_STATIC_ASSERT_BOOL_CAST( B ) >)>\
  60.              (BINARYLITERALCONCAT(boost_static_assert_typedef_, __LINE__)) __attribute__((unused))
  61.     #else
  62.     #define BINARYLITERAL_STATIC_ASSERT( B ) \
  63.        typedef boost::static_assert_test<\
  64.           sizeof(boost::STATIC_ASSERTION_FAILURE< BINARYLITERAL_STATIC_ASSERT_BOOL_CAST( B ) >)>\
  65.              (BINARYLITERALCONCAT(boost_static_assert_typedef_, __LINE__))
  66.     #endif
  67.     //modified C++98 static assert implementation from Boost library END//
  68.  
  69.     template<unsigned EXP> struct PowerOfTen { static const uint32_t value = 10 * PowerOfTen<EXP - 1>::value; };
  70.     template<> struct PowerOfTen<0> { static const uint32_t value = 1; };
  71.        
  72.     template<bool ENABLED, uint32_t DIGIT>
  73.     struct CheckDigit
  74.     {
  75.     };
  76.     template<uint32_t DIGIT>
  77.     struct CheckDigit<true, DIGIT>
  78.     {   //If you get this assert:
  79.         //You probably entered something else than 0 and 1 in your binary literal.
  80.         //Only 1 and 0 are allowed. It should be like this: BinaryLiteral8bit(00000101);
  81.         BINARYLITERAL_STATIC_ASSERT( ((DIGIT == 0) || (DIGIT == 1)) );
  82.     };
  83.  
  84.     template<uint32_t NUMBER, unsigned N, bool CHECK_DIGITS_ENABLED=true>
  85.     struct GetNDigit
  86.     {
  87.         static const uint32_t MOD = PowerOfTen<N+1>::value; static const uint32_t DIV = PowerOfTen<N>::value;
  88.         enum { value = NUMBER % MOD / DIV };
  89.         static const int JustToCheck = sizeof( CheckDigit<CHECK_DIGITS_ENABLED, value> );
  90.     };
  91.     template<uint32_t NUMBER, bool CHECK_DIGITS_ENABLED>
  92.     struct GetNDigit<NUMBER, 0, CHECK_DIGITS_ENABLED>
  93.     {
  94.         enum { value = NUMBER % 10 };
  95.         static const int JustToCheck = sizeof( CheckDigit<CHECK_DIGITS_ENABLED, value> );
  96.     };
  97.  
  98.     template<uint32_t NUMBER, unsigned N>
  99.     struct DigitsIterator
  100.     {
  101.         enum { value = (GetNDigit<NUMBER, N>::value << N) | DigitsIterator<NUMBER, N-1>::value };
  102.     };
  103.     template<uint32_t NUMBER>
  104.     struct DigitsIterator<NUMBER, 0>
  105.     {
  106.         enum { value = GetNDigit<NUMBER, 0>::value };
  107.     };
  108.  
  109.     template<uint32_t BINCONST>
  110.     struct BinaryLiteral8bit
  111.     {
  112.         //If you get this assert:
  113.         //You should enter exactly 8 digits. Only 1 and 0 are allowed! BinaryLiteral8bit(10100101);
  114.         BINARYLITERAL_STATIC_ASSERT( (GetNDigit<BINCONST, 8, false>::value == 2) );
  115.         enum{ value = DigitsIterator<BINCONST, 7>::value };
  116.     };  
  117. }//namespace BL_private
  118.  
  119. // Use as follows:
  120. // BinaryLiteral8bit(10100101);
  121. // You should enter exactly 8 digits. Only 1 and 0 are allowed!
  122. #define BinaryLiteral8bit( L ) (BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## L>::value)
  123.  
  124. // Use as follows:
  125. // BinaryLiteral16bit(00100000,00010000)
  126. // You should enter exactly 8 digits for wach byte. Only 1 and 0 are allowed!
  127. #define BinaryLiteral16bit( B1, B0 ) ( (static_cast<uint16_t>(BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## B1>::value) << 8)\
  128.                                      | BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## B0>::value)
  129.  
  130. // Use as follows:
  131. // BinaryLiteral32bit(10000000,01000000,00100000,00010000)
  132. // You should enter exactly 8 digits for wach byte. Only 1 and 0 are allowed!
  133. #define BinaryLiteral32bit( B3, B2, B1, B0 )    ( (static_cast<uint32_t>(BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## B3>::value) << 24)\
  134.                                                 | (static_cast<uint32_t>(BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## B2>::value) << 16)\
  135.                                                 | (static_cast<uint32_t>(BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## B1>::value) << 8)\
  136.                                                 | (BINARYLITERAL_HPP_private::BinaryLiteral8bit<2 ## B0>::value))
  137.  
  138. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement