Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Components for compile-time parsing of numbers -*- C++ -*-
  2.  
  3. // Copyright (C) 2013-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file bits/parse_numbers.h
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{chrono}
  28.  */
  29.  
  30. #ifndef _GLIBCXX_PARSE_NUMBERS_H
  31. #define _GLIBCXX_PARSE_NUMBERS_H 1
  32.  
  33. #pragma GCC system_header
  34.  
  35. // From n3642.pdf except I added binary literals and digit separator '\''.
  36.  
  37. #if __cplusplus > 201103L
  38.  
  39. #include <limits>
  40.  
  41. namespace std _GLIBCXX_VISIBILITY(default)
  42. {
  43. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  44.  
  45. namespace __parse_int
  46. {
  47.   template<unsigned _Base, char _Dig>
  48.     struct _Digit;
  49.  
  50.   template<unsigned _Base>
  51.     struct _Digit<_Base, '0'> : integral_constant<unsigned, 0>
  52.     {
  53.       using __valid = true_type;
  54.     };
  55.  
  56.   template<unsigned _Base>
  57.     struct _Digit<_Base, '1'> : integral_constant<unsigned, 1>
  58.     {
  59.       using __valid = true_type;
  60.     };
  61.  
  62.   template<unsigned _Base, unsigned _Val>
  63.     struct _Digit_impl : integral_constant<unsigned, _Val>
  64.     {
  65.       static_assert(_Base > _Val, "invalid digit");
  66.       using __valid = true_type;
  67.     };
  68.  
  69.   template<unsigned _Base>
  70.     struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2>
  71.     { };
  72.  
  73.   template<unsigned _Base>
  74.     struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3>
  75.     { };
  76.  
  77.   template<unsigned _Base>
  78.     struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4>
  79.     { };
  80.  
  81.   template<unsigned _Base>
  82.     struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5>
  83.     { };
  84.  
  85.   template<unsigned _Base>
  86.     struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6>
  87.     { };
  88.  
  89.   template<unsigned _Base>
  90.     struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7>
  91.     { };
  92.  
  93.   template<unsigned _Base>
  94.     struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8>
  95.     { };
  96.  
  97.   template<unsigned _Base>
  98.     struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9>
  99.     { };
  100.  
  101.   template<unsigned _Base>
  102.     struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa>
  103.     { };
  104.  
  105.   template<unsigned _Base>
  106.     struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa>
  107.     { };
  108.  
  109.   template<unsigned _Base>
  110.     struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb>
  111.     { };
  112.  
  113.   template<unsigned _Base>
  114.     struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb>
  115.     { };
  116.  
  117.   template<unsigned _Base>
  118.     struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc>
  119.     { };
  120.  
  121.   template<unsigned _Base>
  122.     struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc>
  123.     { };
  124.  
  125.   template<unsigned _Base>
  126.     struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd>
  127.     { };
  128.  
  129.   template<unsigned _Base>
  130.     struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd>
  131.     { };
  132.  
  133.   template<unsigned _Base>
  134.     struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe>
  135.     { };
  136.  
  137.   template<unsigned _Base>
  138.     struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe>
  139.     { };
  140.  
  141.   template<unsigned _Base>
  142.     struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf>
  143.     { };
  144.  
  145.   template<unsigned _Base>
  146.     struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf>
  147.     { };
  148.  
  149.   //  Digit separator
  150.   template<unsigned _Base>
  151.     struct _Digit<_Base, '\''> : integral_constant<unsigned, 0>
  152.     {
  153.       using __valid = false_type;
  154.     };
  155.  
  156. //------------------------------------------------------------------------------
  157.  
  158.   template<unsigned long long _Val>
  159.     using __ull_constant = integral_constant<unsigned long long, _Val>;
  160.  
  161.   template<unsigned _Base, char _Dig, char... _Digs>
  162.     struct _Power_help
  163.     {
  164.       using __next = typename _Power_help<_Base, _Digs...>::type;
  165.       using __valid_digit = typename _Digit<_Base, _Dig>::__valid;
  166.       using type
  167.         = __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>;
  168.     };
  169.  
  170.   template<unsigned _Base, char _Dig>
  171.     struct _Power_help<_Base, _Dig>
  172.     {
  173.       using __valid_digit = typename _Digit<_Base, _Dig>::__valid;
  174.       using type = __ull_constant<__valid_digit::value>;
  175.     };
  176.  
  177.   template<unsigned _Base, char... _Digs>
  178.     struct _Power : _Power_help<_Base, _Digs...>::type
  179.     { };
  180.  
  181.   template<unsigned _Base>
  182.     struct _Power<_Base> : __ull_constant<0>
  183.     { };
  184.  
  185. //------------------------------------------------------------------------------
  186.  
  187.   template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs>
  188.     struct _Number_help
  189.     {
  190.       using __digit = _Digit<_Base, _Dig>;
  191.       using __valid_digit = typename __digit::__valid;
  192.       using __next = _Number_help<_Base,
  193.                                   __valid_digit::value ? _Pow / _Base : _Pow,
  194.                                   _Digs...>;
  195.       using type = __ull_constant<_Pow * __digit::value + __next::type::value>;
  196.       static_assert((type::value / _Pow) == __digit::value,
  197.                     "integer literal does not fit in unsigned long long");
  198.     };
  199.  
  200.   template<unsigned _Base, unsigned long long _Pow, char _Dig>
  201.     struct _Number_help<_Base, _Pow, _Dig>
  202.     {
  203.       //static_assert(_Pow == 1U, "power should be one");
  204.       using type = __ull_constant<_Digit<_Base, _Dig>::value>;
  205.     };
  206.  
  207.   template<unsigned _Base, char... _Digs>
  208.     struct _Number
  209.     : _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type
  210.     { };
  211.  
  212.   template<unsigned _Base>
  213.     struct _Number<_Base>
  214.     : __ull_constant<0>
  215.     { };
  216.  
  217. //------------------------------------------------------------------------------
  218.  
  219.   template<char... _Digs>
  220.     struct _Parse_int;
  221.  
  222.   template<char... _Digs>
  223.     struct _Parse_int<'0', 'b', _Digs...>
  224.     : _Number<2U, _Digs...>::type
  225.     { };
  226.  
  227.   template<char... _Digs>
  228.     struct _Parse_int<'0', 'B', _Digs...>
  229.     : _Number<2U, _Digs...>::type
  230.     { };
  231.  
  232.   template<char... _Digs>
  233.     struct _Parse_int<'0', 'x', _Digs...>
  234.     : _Number<16U, _Digs...>::type
  235.     { };
  236.  
  237.   template<char... _Digs>
  238.     struct _Parse_int<'0', 'X', _Digs...>
  239.     : _Number<16U, _Digs...>::type
  240.     { };
  241.  
  242.   template<char... _Digs>
  243.     struct _Parse_int<'0', _Digs...>
  244.     : _Number<8U, _Digs...>::type
  245.     { };
  246.  
  247.   template<char... _Digs>
  248.     struct _Parse_int
  249.     : _Number<10U, _Digs...>::type
  250.     { };
  251.  
  252. } // namespace __parse_int
  253.  
  254.  
  255. namespace __select_int
  256. {
  257.   template<unsigned long long _Val, typename... _Ints>
  258.     struct _Select_int_base;
  259.  
  260.   template<unsigned long long _Val, typename _IntType, typename... _Ints>
  261.     struct _Select_int_base<_Val, _IntType, _Ints...>
  262.     : conditional_t<(_Val <= std::numeric_limits<_IntType>::max()),
  263.                     integral_constant<_IntType, _Val>,
  264.                     _Select_int_base<_Val, _Ints...>>
  265.     { };
  266.  
  267.   template<unsigned long long _Val>
  268.     struct _Select_int_base<_Val>
  269.     { };
  270.  
  271.   template<char... _Digs>
  272.     using _Select_int = typename _Select_int_base<
  273.         __parse_int::_Parse_int<_Digs...>::value,
  274.         unsigned char,
  275.         unsigned short,
  276.         unsigned int,
  277.         unsigned long,
  278.         unsigned long long
  279.       >::type;
  280.  
  281. } // namespace __select_int
  282.  
  283. _GLIBCXX_END_NAMESPACE_VERSION
  284. } // namespace std
  285.  
  286. #endif // __cplusplus > 201103L
  287.  
  288. #endif // _GLIBCXX_PARSE_NUMBERS_H
  289.