Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:27

0001 // Copyright (c) 2009-2020 Vladimir Batov.
0002 // Use, modification and distribution are subject to the Boost Software License,
0003 // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
0004 
0005 #ifndef BOOST_CONVERT_BASE_HPP
0006 #define BOOST_CONVERT_BASE_HPP
0007 
0008 #include <boost/convert/parameters.hpp>
0009 #include <boost/convert/detail/is_string.hpp>
0010 #include <algorithm>
0011 #include <cstring>
0012 
0013 namespace boost { namespace cnv { template<typename> struct cnvbase; }}
0014 
0015 #define BOOST_CNV_TO_STRING                                                 \
0016     template<typename string_type>                                          \
0017     typename std::enable_if<cnv::is_string<string_type>::value, void>::type \
0018     operator()
0019 
0020 #define BOOST_CNV_STRING_TO                                                 \
0021     template<typename string_type>                                          \
0022     typename std::enable_if<cnv::is_string<string_type>::value, void>::type \
0023     operator()
0024 
0025 #define BOOST_CNV_PARAM_SET(param_name)   \
0026     template <typename argument_pack>     \
0027     void set_(                            \
0028         argument_pack const& arg,         \
0029         cnv::parameter::type::param_name, \
0030         mpl::true_)
0031 
0032 #define BOOST_CNV_PARAM_TRY(param_name)     \
0033     this->set_(                             \
0034         arg,                                \
0035         cnv::parameter::type::param_name(), \
0036         typename mpl::has_key<              \
0037             argument_pack, cnv::parameter::type::param_name>::type());
0038 
0039 template<typename derived_type>
0040 struct boost::cnv::cnvbase
0041 {
0042     using   this_type = cnvbase;
0043     using    int_type = int;
0044     using   uint_type = unsigned int;
0045     using   lint_type = long int;
0046     using  ulint_type = unsigned long int;
0047     using   sint_type = short int;
0048     using  usint_type = unsigned short int;
0049     using  llint_type = long long int;
0050     using ullint_type = unsigned long long int;
0051     using    flt_type = float;
0052     using    dbl_type = double;
0053     using   ldbl_type = long double;
0054 
0055     // Integration of user-types via operator>>()
0056     template<typename type_in, typename type_out>
0057     void
0058     operator()(type_in const& in, boost::optional<type_out>& out) const
0059     {
0060         in >> out;
0061     }
0062 
0063     // Basic type to string
0064     BOOST_CNV_TO_STRING (   int_type v, optional<string_type>& r) const { to_str_(v, r); }
0065     BOOST_CNV_TO_STRING (  uint_type v, optional<string_type>& r) const { to_str_(v, r); }
0066     BOOST_CNV_TO_STRING (  lint_type v, optional<string_type>& r) const { to_str_(v, r); }
0067     BOOST_CNV_TO_STRING ( llint_type v, optional<string_type>& r) const { to_str_(v, r); }
0068     BOOST_CNV_TO_STRING ( ulint_type v, optional<string_type>& r) const { to_str_(v, r); }
0069     BOOST_CNV_TO_STRING (ullint_type v, optional<string_type>& r) const { to_str_(v, r); }
0070     BOOST_CNV_TO_STRING (  sint_type v, optional<string_type>& r) const { to_str_(v, r); }
0071     BOOST_CNV_TO_STRING ( usint_type v, optional<string_type>& r) const { to_str_(v, r); }
0072     BOOST_CNV_TO_STRING (   flt_type v, optional<string_type>& r) const { to_str_(v, r); }
0073     BOOST_CNV_TO_STRING (   dbl_type v, optional<string_type>& r) const { to_str_(v, r); }
0074     BOOST_CNV_TO_STRING (  ldbl_type v, optional<string_type>& r) const { to_str_(v, r); }
0075     // String to basic type
0076     BOOST_CNV_STRING_TO (string_type const& s, optional<   int_type>& r) const { str_to_(s, r); }
0077     BOOST_CNV_STRING_TO (string_type const& s, optional<  uint_type>& r) const { str_to_(s, r); }
0078     BOOST_CNV_STRING_TO (string_type const& s, optional<  lint_type>& r) const { str_to_(s, r); }
0079     BOOST_CNV_STRING_TO (string_type const& s, optional< llint_type>& r) const { str_to_(s, r); }
0080     BOOST_CNV_STRING_TO (string_type const& s, optional< ulint_type>& r) const { str_to_(s, r); }
0081     BOOST_CNV_STRING_TO (string_type const& s, optional<ullint_type>& r) const { str_to_(s, r); }
0082     BOOST_CNV_STRING_TO (string_type const& s, optional<  sint_type>& r) const { str_to_(s, r); }
0083     BOOST_CNV_STRING_TO (string_type const& s, optional< usint_type>& r) const { str_to_(s, r); }
0084     BOOST_CNV_STRING_TO (string_type const& s, optional<   flt_type>& r) const { str_to_(s, r); }
0085     BOOST_CNV_STRING_TO (string_type const& s, optional<   dbl_type>& r) const { str_to_(s, r); }
0086     BOOST_CNV_STRING_TO (string_type const& s, optional<  ldbl_type>& r) const { str_to_(s, r); }
0087 
0088     template<typename argument_pack>
0089     typename std::enable_if<boost::parameter::is_argument_pack<argument_pack>::value, derived_type&>::type
0090     operator()(argument_pack const& arg)
0091     {
0092         BOOST_CNV_PARAM_TRY(base);
0093         BOOST_CNV_PARAM_TRY(adjust);
0094         BOOST_CNV_PARAM_TRY(precision);
0095         BOOST_CNV_PARAM_TRY(uppercase);
0096         BOOST_CNV_PARAM_TRY(skipws);
0097         BOOST_CNV_PARAM_TRY(width);
0098         BOOST_CNV_PARAM_TRY(fill);
0099         BOOST_CNV_PARAM_TRY(notation);
0100 //      BOOST_CNV_PARAM_TRY(locale);
0101 
0102         return this->dncast();
0103     }
0104 
0105     protected:
0106 
0107     cnvbase() = default;
0108 
0109     template<typename string_type, typename out_type>
0110     void
0111     str_to_(string_type const& str, optional<out_type>& result_out) const
0112     {
0113         cnv::range<string_type const> range (str);
0114 
0115         if (skipws_)
0116             for (; !range.empty() && cnv::is_space(*range.begin()); ++range);
0117 
0118         if (range.empty())                 return;
0119         if (cnv::is_space(*range.begin())) return;
0120 
0121         dncast().str_to(range, result_out);
0122     }
0123     template<typename in_type, typename string_type>
0124     void
0125     to_str_(in_type value_in, optional<string_type>& result_out) const
0126     {
0127         using  char_type = typename cnv::range<string_type>::value_type;
0128         using range_type = cnv::range<char_type*>;
0129         using   buf_type = char_type[bufsize_];
0130 
0131         buf_type     buf;
0132         range_type range = dncast().to_str(value_in, buf);
0133         char_type*   beg = range.begin();
0134         char_type*   end = range.end();
0135         int     str_size = end - beg;
0136 
0137         if (str_size <= 0)
0138             return;
0139 
0140         if (uppercase_)
0141             for (char_type* p = beg; p < end; ++p) *p = cnv::to_upper(*p);
0142 
0143         if (width_)
0144         {
0145             int  num_fill = (std::max)(0, int(width_ - (end - beg)));
0146             int  num_left = adjust_ == cnv::adjust::left ? 0
0147                           : adjust_ == cnv::adjust::right ? num_fill
0148                           : (num_fill / 2);
0149             int num_right = num_fill - num_left;
0150             bool     move = (beg < buf + num_left) // No room for left fillers
0151                          || (buf + bufsize_ < end + num_right); // No room for right fillers
0152             if (move)
0153             {
0154                 std::memmove(buf + num_left, beg, str_size * sizeof(char_type));
0155                 beg = buf + num_left;
0156                 end = beg + str_size;
0157             }
0158             for (int k = 0; k <  num_left; *(--beg) = fill_, ++k);
0159             for (int k = 0; k < num_right; *(end++) = fill_, ++k);
0160         }
0161         result_out = string_type(beg, end);
0162     }
0163 
0164     derived_type const& dncast () const { return *static_cast<derived_type const*>(this); }
0165     derived_type&       dncast ()       { return *static_cast<derived_type*>(this); }
0166 
0167     template<typename argument_pack, typename keyword_tag>
0168     void set_(argument_pack const&, keyword_tag, mpl::false_) {}
0169 
0170     // Formatters
0171     BOOST_CNV_PARAM_SET(base)      { base_      = arg[cnv::parameter::     base]; }
0172     BOOST_CNV_PARAM_SET(adjust)    { adjust_    = arg[cnv::parameter::   adjust]; }
0173     BOOST_CNV_PARAM_SET(precision) { precision_ = arg[cnv::parameter::precision]; }
0174     BOOST_CNV_PARAM_SET(uppercase) { uppercase_ = arg[cnv::parameter::uppercase]; }
0175     BOOST_CNV_PARAM_SET(skipws)    { skipws_    = arg[cnv::parameter::   skipws]; }
0176     BOOST_CNV_PARAM_SET(width)     { width_     = arg[cnv::parameter::    width]; }
0177     BOOST_CNV_PARAM_SET(fill)      { fill_      = arg[cnv::parameter::     fill]; }
0178     BOOST_CNV_PARAM_SET(notation)  { notation_  = arg[cnv::parameter:: notation]; }
0179 //  BOOST_CNV_PARAM_SET(locale)    { locale_    = arg[cnv::parameter::   locale]; }
0180 
0181     // ULONG_MAX(8 bytes) = 18446744073709551615 (20(10) or 32(2) characters)
0182     // double (8 bytes) max is 316 chars
0183     static int BOOST_CONSTEXPR_OR_CONST bufsize_ = 512;
0184 
0185     bool            skipws_ = false;
0186     int          precision_ = 0;
0187     bool         uppercase_ = false;
0188     int              width_ = 0;
0189     int               fill_ = ' ';
0190     cnv::base         base_ = boost::cnv::base::dec;
0191     cnv::adjust     adjust_ = boost::cnv::adjust::right;
0192     cnv::notation notation_ = boost::cnv::notation::fixed;
0193 //  std::locale     locale_;
0194 };
0195 
0196 #undef BOOST_CNV_TO_STRING
0197 #undef BOOST_CNV_STRING_TO
0198 #undef BOOST_CNV_PARAM_SET
0199 #undef BOOST_CNV_PARAM_TRY
0200 
0201 #endif // BOOST_CONVERT_BASE_HPP