Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:11

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_PRINTF_HPP
0006 #define BOOST_CONVERT_PRINTF_HPP
0007 
0008 #include <boost/convert/base.hpp>
0009 #include <boost/make_default.hpp>
0010 #include <boost/mpl/vector.hpp>
0011 #include <boost/mpl/find.hpp>
0012 #include <string>
0013 #include <cstdio>
0014 
0015 namespace boost { namespace cnv { struct printf; }}
0016 
0017 struct boost::cnv::printf : boost::cnv::cnvbase<boost::cnv::printf>
0018 {
0019     using this_type = boost::cnv::printf;
0020     using base_type = boost::cnv::cnvbase<this_type>;
0021 
0022     using base_type::operator();
0023 
0024     template<typename in_type>
0025     cnv::range<char*>
0026     to_str(in_type value_in, char* buf) const
0027     {
0028         char_cptr fmt = printf_format(pos<in_type>());
0029         int num_chars = snprintf(buf, bufsize_, fmt, precision_, value_in);
0030         bool  success = num_chars < bufsize_;
0031 
0032         return cnv::range<char*>(buf, success ? (buf + num_chars) : buf);
0033     }
0034     template<typename string_type, typename out_type>
0035     void
0036     str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
0037     {
0038         out_type result = boost::make_default<out_type>();
0039         char_cptr   fmt = sscanf_format(pos<out_type>());
0040         int    num_read = sscanf(&*range.begin(), fmt, &result);
0041 
0042         if (num_read == 1)
0043             result_out = result;
0044     }
0045 
0046     private:
0047 
0048     template<typename Type> int pos() const
0049     {
0050         // C1. The orders of types and formats must match.
0051 
0052         using types = boost::mpl::vector<
0053                           double, float, int, unsigned int, short int,
0054                           unsigned short int, long int, unsigned long int>;
0055         using found = typename boost::mpl::find<types, Type>::type;
0056         using   pos = typename found::pos;
0057 
0058         return pos::value;
0059     }
0060     char_cptr printf_format(int type_pos) const
0061     {
0062         char_cptr BOOST_CONSTEXPR_OR_CONST d_fmt[3][8] =
0063         {
0064             { "%.*f", "%.*f", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }, //C1. fxd
0065             { "%.*e", "%.*e", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }, //C1. sci
0066             { "%.*a", "%.*a", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }  //C1. hex
0067         };
0068         char_cptr BOOST_CONSTEXPR_OR_CONST x_fmt[3][8] =
0069         {
0070             { "%.*f", "%.*f", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }, //C1. fxd
0071             { "%.*e", "%.*e", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }, //C1. sci
0072             { "%.*a", "%.*a", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }  //C1. hex
0073         };
0074         char_cptr BOOST_CONSTEXPR_OR_CONST o_fmt[3][8] =
0075         {
0076             { "%.*f", "%.*f", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }, //C1. fxd
0077             { "%.*e", "%.*e", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }, //C1. sci
0078             { "%.*a", "%.*a", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }  //C1. hex
0079         };
0080         return base_ == base::dec ? d_fmt[int(notation_)][type_pos]
0081              : base_ == base::hex ? x_fmt[int(notation_)][type_pos]
0082              : base_ == base::oct ? o_fmt[int(notation_)][type_pos]
0083              : (BOOST_ASSERT(0), nullptr);
0084     }
0085     char_cptr sscanf_format(int type_pos) const
0086     {
0087         char_cptr BOOST_CONSTEXPR_OR_CONST d_fmt[3][8] =
0088         {
0089             { "%lf", "%f", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }, //C1. fxd
0090             { "%le", "%e", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }, //C1. sci
0091             { "%la", "%a", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }  //C1. hex
0092         };
0093         char_cptr BOOST_CONSTEXPR_OR_CONST x_fmt[3][8] =
0094         {
0095             { "%lf", "%f", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }, //C1. fxd
0096             { "%le", "%e", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }, //C1. sci
0097             { "%la", "%a", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }  //C1. hex
0098         };
0099         char_cptr BOOST_CONSTEXPR_OR_CONST o_fmt[3][8] =
0100         {
0101             { "%lf", "%f", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }, //C1. fxd
0102             { "%le", "%e", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }, //C1. sci
0103             { "%la", "%a", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }  //C1. hex
0104         };
0105         return base_ == base::dec ? d_fmt[int(notation_)][type_pos]
0106              : base_ == base::hex ? x_fmt[int(notation_)][type_pos]
0107              : base_ == base::oct ? o_fmt[int(notation_)][type_pos]
0108              : (BOOST_ASSERT(0), nullptr);
0109     }
0110 };
0111 
0112 #endif // BOOST_CONVERT_PRINTF_HPP