update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -1,33 +1,40 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
#ifndef BOOST_CONVERT_CONVERTER_BASE_HPP
#define BOOST_CONVERT_CONVERTER_BASE_HPP
#ifndef BOOST_CONVERT_BASE_HPP
#define BOOST_CONVERT_BASE_HPP
#include <boost/convert/parameters.hpp>
#include <boost/convert/detail/is_string.hpp>
#include <algorithm>
#include <cstring>
namespace boost { namespace cnv
{
namespace ARG = boost::cnv::parameter;
namespace boost { namespace cnv { template<typename> struct cnvbase; }}
template<typename> struct cnvbase;
}}
#define BOOST_CNV_TO_STRING \
template<typename string_type> \
typename boost::enable_if<cnv::is_string<string_type>, void>::type \
#define BOOST_CNV_TO_STRING \
template<typename string_type> \
typename std::enable_if<cnv::is_string<string_type>::value, void>::type \
operator()
#define BOOST_CNV_STRING_TO \
template<typename string_type> \
typename boost::enable_if<cnv::is_string<string_type>, void>::type \
#define BOOST_CNV_STRING_TO \
template<typename string_type> \
typename std::enable_if<cnv::is_string<string_type>::value, void>::type \
operator()
#define BOOST_CNV_PARAM(param_name, param_type) \
derived_type& operator()(boost::parameter::aux::tag<ARG::type::param_name, param_type>::type const& arg)
#define BOOST_CNV_PARAM_SET(param_name) \
template <typename argument_pack> \
void set_( \
argument_pack const& arg, \
cnv::parameter::type::param_name, \
mpl::true_)
#define BOOST_CNV_PARAM_TRY(param_name) \
this->set_( \
arg, \
cnv::parameter::type::param_name(), \
typename mpl::has_key< \
argument_pack, cnv::parameter::type::param_name>::type());
template<typename derived_type>
struct boost::cnv::cnvbase
@@ -77,29 +84,27 @@ struct boost::cnv::cnvbase
BOOST_CNV_STRING_TO (string_type const& s, optional< flt_type>& r) const { str_to_(s, r); }
BOOST_CNV_STRING_TO (string_type const& s, optional< dbl_type>& r) const { str_to_(s, r); }
BOOST_CNV_STRING_TO (string_type const& s, optional< ldbl_type>& r) const { str_to_(s, r); }
// Formatters
// BOOST_CNV_PARAM (locale, std::locale const) { locale_ = arg[ARG:: locale]; return dncast(); }
BOOST_CNV_PARAM (base, cnv::base const) { base_ = arg[ARG:: base]; return dncast(); }
BOOST_CNV_PARAM (adjust, cnv::adjust const) { adjust_ = arg[ARG:: adjust]; return dncast(); }
BOOST_CNV_PARAM (precision, int const) { precision_ = arg[ARG::precision]; return dncast(); }
BOOST_CNV_PARAM (precision, int) { precision_ = arg[ARG::precision]; return dncast(); }
BOOST_CNV_PARAM (uppercase, bool const) { uppercase_ = arg[ARG::uppercase]; return dncast(); }
BOOST_CNV_PARAM (skipws, bool const) { skipws_ = arg[ARG:: skipws]; return dncast(); }
BOOST_CNV_PARAM (width, int const) { width_ = arg[ARG:: width]; return dncast(); }
BOOST_CNV_PARAM (fill, char const) { fill_ = arg[ARG:: fill]; return dncast(); }
template<typename argument_pack>
typename std::enable_if<boost::parameter::is_argument_pack<argument_pack>::value, derived_type&>::type
operator()(argument_pack const& arg)
{
BOOST_CNV_PARAM_TRY(base);
BOOST_CNV_PARAM_TRY(adjust);
BOOST_CNV_PARAM_TRY(precision);
BOOST_CNV_PARAM_TRY(uppercase);
BOOST_CNV_PARAM_TRY(skipws);
BOOST_CNV_PARAM_TRY(width);
BOOST_CNV_PARAM_TRY(fill);
BOOST_CNV_PARAM_TRY(notation);
// BOOST_CNV_PARAM_TRY(locale);
return this->dncast();
}
protected:
cnvbase()
:
skipws_ (false),
precision_ (0),
uppercase_ (false),
width_ (0),
fill_ (' '),
base_ (boost::cnv::base::dec),
adjust_ (boost::cnv::adjust::right)
{}
cnvbase() = default;
template<typename string_type, typename out_type>
void
@@ -159,21 +164,38 @@ struct boost::cnv::cnvbase
derived_type const& dncast () const { return *static_cast<derived_type const*>(this); }
derived_type& dncast () { return *static_cast<derived_type*>(this); }
template<typename argument_pack, typename keyword_tag>
void set_(argument_pack const&, keyword_tag, mpl::false_) {}
// Formatters
BOOST_CNV_PARAM_SET(base) { base_ = arg[cnv::parameter:: base]; }
BOOST_CNV_PARAM_SET(adjust) { adjust_ = arg[cnv::parameter:: adjust]; }
BOOST_CNV_PARAM_SET(precision) { precision_ = arg[cnv::parameter::precision]; }
BOOST_CNV_PARAM_SET(uppercase) { uppercase_ = arg[cnv::parameter::uppercase]; }
BOOST_CNV_PARAM_SET(skipws) { skipws_ = arg[cnv::parameter:: skipws]; }
BOOST_CNV_PARAM_SET(width) { width_ = arg[cnv::parameter:: width]; }
BOOST_CNV_PARAM_SET(fill) { fill_ = arg[cnv::parameter:: fill]; }
BOOST_CNV_PARAM_SET(notation) { notation_ = arg[cnv::parameter:: notation]; }
// BOOST_CNV_PARAM_SET(locale) { locale_ = arg[cnv::parameter:: locale]; }
// ULONG_MAX(8 bytes) = 18446744073709551615 (20(10) or 32(2) characters)
// double (8 bytes) max is 316 chars
static int const bufsize_ = 512;
bool skipws_;
int precision_;
bool uppercase_;
int width_;
int fill_;
cnv::base base_;
cnv::adjust adjust_;
// std::locale locale_;
static int BOOST_CONSTEXPR_OR_CONST bufsize_ = 512;
bool skipws_ = false;
int precision_ = 0;
bool uppercase_ = false;
int width_ = 0;
int fill_ = ' ';
cnv::base base_ = boost::cnv::base::dec;
cnv::adjust adjust_ = boost::cnv::adjust::right;
cnv::notation notation_ = boost::cnv::notation::fixed;
// std::locale locale_;
};
#undef BOOST_CNV_TO_STRING
#undef BOOST_CNV_STRING_TO
#undef BOOST_CNV_PARAM
#undef BOOST_CNV_PARAM_SET
#undef BOOST_CNV_PARAM_TRY
#endif // BOOST_CONVERT_CONVERTER_BASE_HPP
#endif // BOOST_CONVERT_BASE_HPP

View File

@@ -0,0 +1,85 @@
// Copyright (c) 2022 Dvir Yitzchaki.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
#ifndef BOOST_CONVERT_CHARCONV_BASED_CONVERTER_HPP
#define BOOST_CONVERT_CHARCONV_BASED_CONVERTER_HPP
#ifdef BOOST_NO_CXX17_HDR_CHARCONV
#error "This header requires <charconv> which is unavailable"
#endif // BOOST_NO_CXX17_HDR_CHARCONV
#ifdef BOOST_NO_CXX17_STRUCTURED_BINDINGS
#error "This header requires structured bindings which is unavailable"
#endif // BOOST_NO_CXX17_STRUCTURED_BINDINGS
#ifdef BOOST_NO_CXX17_IF_CONSTEXPR
#error "This header requires constexpr if which is unavailable"
#endif // BOOST_NO_CXX17_IF_CONSTEXPR
#include <boost/convert/base.hpp>
#include <charconv>
#include <type_traits>
namespace boost { namespace cnv { struct charconv; }}
/// @brief std::to/from_chars-based extended converter
/// @details The converter offers good overall performance and moderate formatting facilities.
struct boost::cnv::charconv : boost::cnv::cnvbase<boost::cnv::charconv>
{
using this_type = boost::cnv::charconv;
using base_type = boost::cnv::cnvbase<this_type>;
private:
friend struct boost::cnv::cnvbase<this_type>;
template<typename in_type>
cnv::range<char*>
to_str(in_type value_in, char* buf) const
{
const auto [ptr, ec] = [&]{
if constexpr (std::is_integral_v<in_type>) {
return std::to_chars(buf, buf + bufsize_, value_in, static_cast<int>(base_));
} else {
return std::to_chars(buf, buf + bufsize_, value_in, chars_format(), precision_);
}
}();
bool success = ec == std::errc{};
return cnv::range<char*>(buf, success ? ptr : buf);
}
template<typename string_type, typename out_type>
void
str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
{
out_type result = boost::make_default<out_type>();
const auto [ptr, ec] = [&]{
if constexpr (std::is_integral_v<out_type>) {
return std::from_chars(&*range.begin(), &*range.end(), result, static_cast<int>(base_));
} else {
return std::from_chars(&*range.begin(), &*range.end(), result, chars_format());
}
}();
if (ec == std::errc{})
result_out = result;
}
std::chars_format chars_format() const
{
static constexpr std::chars_format format[] =
{
std::chars_format::fixed,
std::chars_format::scientific,
std::chars_format::hex
};
return format[int(notation_)];
}
std::chars_format fmt_ = std::chars_format::fixed;
};
#endif // BOOST_CONVERT_CHARCONV_BASED_CONVERTER_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -6,7 +6,6 @@
#define BOOST_CONVERT_DETAIL_IS_CHAR_HPP
#include <boost/convert/detail/config.hpp>
#include <type_traits>
#include <cctype>
#include <cwctype>
@@ -15,6 +14,7 @@ namespace boost { namespace cnv
using char_type = char;
using uchar_type = unsigned char;
using wchar_type = wchar_t;
using char_cptr = char const*;
namespace detail
{

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -8,26 +8,27 @@
#include <boost/config.hpp>
#include <boost/version.hpp>
#include <boost/optional.hpp>
#include <type_traits>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#undef BOOST_CONVERT_CXX11
#if defined(BOOST_NO_CXX14)
#undef BOOST_CONVERT_CXX14
#else
#define BOOST_CONVERT_CXX11
#define BOOST_CONVERT_CXX14
#endif
// Intel 12.0 and lower have broken SFINAE
#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1200)
# define BOOST_CONVERT_IS_NOT_SUPPORTED
#undef BOOST_CONVERT_CXX14
#endif
// No C++11 support
#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION <= 40600)
# define BOOST_CONVERT_IS_NOT_SUPPORTED
#if defined(__GNUC__) && (__GNUC__ < 6)
#undef BOOST_CONVERT_CXX14
#endif
// MSVC-11 and lower have broken SFINAE
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1800)
# define BOOST_CONVERT_IS_NOT_SUPPORTED
#if defined(_MSVC_VER) && (_MSVC_VER < 1800)
#undef BOOST_CONVERT_CXX14
#endif
#if defined(_MSC_VER)
@@ -42,12 +43,13 @@
//MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
//MSVC++ 15.0 _MSC_VER == 1910 (Visual Studio 2017)
# pragma warning(disable: 4244)
# pragma warning(disable: 4224)
# pragma warning(disable: 4996)
# pragma warning(disable: 4180) // qualifier applied to function type has no meaning
# pragma warning(disable: 4100) // unreferenced formal parameter
# pragma warning(disable: 4146) // unary minus operator applied to unsigned type
# pragma warning(disable: 4180) // qualifier applied to function type has no meaning
# pragma warning(disable: 4224)
# pragma warning(disable: 4244)
# pragma warning(disable: 4800) // forcing value to bool
# pragma warning(disable: 4996)
#if _MSC_VER < 1900 /* MSVC-14 defines real snprintf()... just about time! */
# define snprintf _snprintf

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -40,9 +40,9 @@
template <typename __boost_has_member_T__> /*C4*/ \
class __trait_name__ \
{ \
typedef typename boost::remove_const<__boost_has_member_T__>::type check_type; \
typedef ::boost::type_traits::yes_type yes_type; \
typedef ::boost::type_traits:: no_type no_type; \
using check_type = typename boost::remove_const<__boost_has_member_T__>::type; \
using yes_type = ::boost::type_traits::yes_type; \
using no_type = ::boost::type_traits:: no_type; \
\
struct base { void __member_name__(/*C2*/) {}}; \
struct mixin : public base, public check_type {}; \

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -9,8 +9,8 @@
namespace boost { namespace cnv { namespace detail
{
typedef ::boost::type_traits::yes_type yes_type;
typedef ::boost::type_traits:: no_type no_type;
using yes_type = ::boost::type_traits::yes_type;
using no_type = ::boost::type_traits:: no_type;
struct not_found {};
struct void_return_substitute {};
@@ -21,8 +21,8 @@ namespace boost { namespace cnv { namespace detail
template<typename U> U const& operator, (U const&, void_return_substitute);
template<typename U> U& operator, (U&, void_return_substitute);
template <typename src, typename dst> struct match_const { typedef dst type; };
template <typename src, typename dst> struct match_const<src const, dst> { typedef dst const type; };
template <typename src, typename dst> struct match_const { using type = dst; };
template <typename src, typename dst> struct match_const<src const, dst> { using type = dst const; };
template<typename T, typename return_type>
struct redirect
@@ -53,48 +53,49 @@ namespace boost { namespace cnv { namespace detail
template <typename __boost_is_callable_T__, typename __boost_is_callable_signature__> \
class __trait_name__ \
{ \
typedef __boost_is_callable_T__ class_type; /*C1*/ \
typedef __boost_is_callable_signature__ signature; /*C1*/ \
typedef boost::cnv::detail::not_found not_found; \
using class_type = __boost_is_callable_T__; /*C1*/ \
using signature = __boost_is_callable_signature__; /*C1*/ \
using not_found = boost::cnv::detail::not_found; \
\
BOOST_DECLARE_HAS_MEMBER(has_member, __member_name__); \
\
struct mixin : public class_type \
struct mixin : class_type \
{ \
using class_type::__member_name__; \
not_found __member_name__(...) const { return not_found(); /*C2*/} \
}; \
\
typedef typename boost::cnv::detail::match_const<class_type, mixin>::type* mixin_ptr; \
using mixin_ptr = typename boost::cnv::detail::match_const<class_type, mixin>::type*; \
\
template <bool has, typename F> struct check { static bool const value = false; }; \
\
template <typename Arg1, typename R> \
struct check<true, R (Arg1)> \
{ \
typedef typename boost::decay<Arg1>::type* a1; \
using a1 = typename boost::decay<Arg1>::type*; \
\
static bool const value = sizeof(boost::type_traits::yes_type) \
== sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
(mixin_ptr(0)->__member_name__(*a1(0)), \
boost::cnv::detail::void_return_substitute()))); \
static bool BOOST_CONSTEXPR_OR_CONST value = \
sizeof(boost::type_traits::yes_type) == \
sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
(mixin_ptr(0)->__member_name__(*a1(0)), \
boost::cnv::detail::void_return_substitute()))); \
}; \
template <typename Arg1, typename Arg2, typename R> \
struct check<true, R (Arg1, Arg2)> \
{ \
typedef typename boost::decay<Arg1>::type* a1; \
typedef typename boost::decay<Arg2>::type* a2; \
using a1 = typename boost::decay<Arg1>::type*; \
using a2 = typename boost::decay<Arg2>::type*; \
\
static bool const value = sizeof(boost::type_traits::yes_type) \
== sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
(mixin_ptr(0)->__member_name__(*a1(0), *a2(0)), \
boost::cnv::detail::void_return_substitute()))); \
static bool BOOST_CONSTEXPR_OR_CONST value = \
sizeof(boost::type_traits::yes_type) == \
sizeof(boost::cnv::detail::redirect<class_type, R>::test( \
(mixin_ptr(0)->__member_name__(*a1(0), *a2(0)), \
boost::cnv::detail::void_return_substitute()))); \
}; \
\
public: \
\
/* Check the existence of __member_name__ first, then the signature. */ \
static bool const value = check<has_member<class_type>::value, signature>::value; \
static bool BOOST_CONSTEXPR_OR_CONST value = check<has_member<class_type>::value, signature>::value; \
}
#endif // BOOST_CONVERT_IS_CALLABLE_HPP

View File

@@ -1,47 +0,0 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
#ifndef BOOST_CONVERT_IS_CONVERTER_HPP
#define BOOST_CONVERT_IS_CONVERTER_HPP
#include <boost/convert/detail/config.hpp>
#include <boost/convert/detail/is_callable.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/ref.hpp>
namespace boost { namespace cnv
{
template<typename, typename, typename, typename =void>
struct is_cnv { BOOST_STATIC_CONSTANT(bool, value = false); };
template<typename Class, typename TypeIn, typename TypeOut>
struct is_cnv<Class, TypeIn, TypeOut, typename enable_if<is_class<Class>, void>::type>
{
typedef typename ::boost::unwrap_reference<Class>::type class_type;
typedef void signature_type(TypeIn const&, optional<TypeOut>&);
BOOST_DECLARE_IS_CALLABLE(is_callable, operator());
BOOST_STATIC_CONSTANT(bool, value = (is_callable<class_type, signature_type>::value));
};
template<typename Function, typename TypeIn, typename TypeOut>
struct is_cnv<Function, TypeIn, TypeOut,
typename enable_if_c<is_function<Function>::value && function_types::function_arity<Function>::value == 2,
void>::type>
{
typedef TypeIn in_type;
typedef optional<TypeOut>& out_type;
typedef typename function_traits<Function>::arg1_type func_in_type;
typedef typename function_traits<Function>::arg2_type func_out_type;
BOOST_STATIC_CONSTANT(bool, in_good = (is_convertible<in_type, func_in_type>::value));
BOOST_STATIC_CONSTANT(bool, out_good = (is_same<out_type, func_out_type>::value));
BOOST_STATIC_CONSTANT(bool, value = (in_good && out_good));
};
}}
#endif // BOOST_CONVERT_IS_CONVERTER_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -7,21 +7,19 @@
#include <boost/convert/detail/config.hpp>
#include <boost/convert/detail/has_member.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/result_type.hpp>
namespace boost { namespace cnv
{
typedef ::boost::type_traits::yes_type yes_type;
typedef ::boost::type_traits:: no_type no_type;
using yes_type = ::boost::type_traits::yes_type;
using no_type = ::boost::type_traits:: no_type;
template <bool has_operator, typename Functor, typename TypeOut>
struct check_functor { BOOST_STATIC_CONSTANT(bool, value = false); };
template<typename Func, typename TypeOut, class Enable =void>
template<typename Func, typename TypeOut, typename Enable = void>
struct is_fun { BOOST_STATIC_CONSTANT(bool, value = false); };
template <typename Functor, typename TypeOut>
@@ -30,18 +28,16 @@ namespace boost { namespace cnv
static yes_type test (TypeOut const&);
static no_type test (...);
static const bool value = sizeof(yes_type) == sizeof(test(((Functor*) 0)->operator()()));
static bool BOOST_CONSTEXPR_OR_CONST value = sizeof(yes_type) == sizeof(test(((Functor*) 0)->operator()()));
};
template<typename Functor, typename TypeOut>
struct is_fun<Functor, TypeOut,
typename enable_if_c<is_class<Functor>::value && !is_convertible<Functor, TypeOut>::value, void>::type>
typename enable_if_c<std::is_class<Functor>::value && !is_convertible<Functor, TypeOut>::value, void>::type>
{
BOOST_DECLARE_HAS_MEMBER(has_funop, operator());
BOOST_STATIC_CONSTANT(bool, value = (check_functor<has_funop<Functor>::value, Functor, TypeOut>::value));
};
template<typename Function, typename TypeOut>
struct is_fun<Function, TypeOut,
typename enable_if_c<
@@ -50,10 +46,10 @@ namespace boost { namespace cnv
!is_same<Function, TypeOut>::value,
void>::type>
{
typedef TypeOut out_type;
typedef typename function_types::result_type<Function>::type func_out_type;
using out_type = TypeOut;
using func_type = typename function_types::result_type<Function>::type;
BOOST_STATIC_CONSTANT(bool, value = (is_convertible<func_out_type, out_type>::value));
BOOST_STATIC_CONSTANT(bool, value = (is_convertible<func_type, out_type>::value));
};
}}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -15,20 +15,22 @@ namespace boost { namespace cnv
template<typename T> struct is_string<T*, false>
{
static bool const value = cnv::is_char<T>::value;
static bool BOOST_CONSTEXPR_OR_CONST value = cnv::is_char<T>::value;
};
template <typename T, std::size_t N> struct is_string<T [N], false>
{
static bool const value = cnv::is_char<T>::value;
static bool BOOST_CONSTEXPR_OR_CONST value = cnv::is_char<T>::value;
};
template<typename T> struct is_string<T, /*is_range_class=*/true>
{
static bool const value = cnv::is_char<typename T::value_type>::value;
static bool BOOST_CONSTEXPR_OR_CONST value = cnv::is_char<typename T::value_type>::value;
};
}
template<typename T> struct is_string : detail::is_string<
typename boost::remove_const<T>::type,
boost::is_class<T>::value && boost::cnv::is_range<T>::value> {};
template<typename T>
struct is_string : detail::is_string<
typename std::remove_const<T>::type,
std::is_class<T>::value && cnv::is_range<T>::value>
{};
}}
#endif // BOOST_CONVERT_DETAIL_IS_STRING_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -7,7 +7,6 @@
#include <boost/convert/detail/has_member.hpp>
#include <boost/convert/detail/char.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/range/iterator.hpp>
namespace boost { namespace cnv
@@ -21,7 +20,7 @@ namespace boost { namespace cnv
BOOST_DECLARE_HAS_MEMBER(has_begin, begin);
BOOST_DECLARE_HAS_MEMBER( has_end, end);
static bool const value = has_begin<T>::value && has_end<T>::value;
static bool BOOST_CONSTEXPR_OR_CONST value = has_begin<T>::value && has_end<T>::value;
};
}
template<typename T> struct is_range : detail::is_range<typename boost::remove_const<T>::type, boost::is_class<T>::value> {};
@@ -29,26 +28,26 @@ namespace boost { namespace cnv
template<typename T, typename enable =void> struct iterator;
template<typename T>
struct iterator<T, typename enable_if<is_range<T> >::type>
struct iterator<T, typename std::enable_if<is_range<T>::value>::type>
{
typedef typename boost::range_iterator<T>::type type;
typedef typename boost::range_iterator<T const>::type const_type;
typedef typename boost::iterator_value<type>::type value_type;
using type = typename boost::range_iterator<T>::type;
using const_type = typename boost::range_iterator<T const>::type;
using value_type = typename boost::iterator_value<type>::type;
};
template<typename T>
struct iterator<T*, void>
{
typedef typename boost::remove_const<T>::type value_type;
typedef T* type;
typedef value_type const* const_type;
using value_type = typename boost::remove_const<T>::type;
using type = T*;
using const_type = value_type const*;
};
template<typename T>
struct range_base
{
typedef typename cnv::iterator<T>::value_type value_type;
typedef typename cnv::iterator<T>::type iterator;
typedef typename cnv::iterator<T>::const_type const_iterator;
typedef const_iterator sentry_type;
using value_type = typename cnv::iterator<T>::value_type;
using iterator = typename cnv::iterator<T>::type;
using const_iterator = typename cnv::iterator<T>::const_type;
using sentry_type = const_iterator;
iterator begin () { return begin_; }
const_iterator begin () const { return begin_; }
@@ -64,17 +63,17 @@ namespace boost { namespace cnv
};
template<typename T>
struct range<T, typename enable_if<is_range<T> >::type> : public range_base<T>
struct range<T, typename std::enable_if<is_range<T>::value>::type> : public range_base<T>
{
typedef range this_type;
typedef range_base<T> base_type;
typedef typename base_type::iterator iterator;
typedef typename base_type::const_iterator const_iterator;
typedef const_iterator sentry_type;
using this_type = range;
using base_type = range_base<T>;
using iterator = typename base_type::iterator;
using const_iterator = typename base_type::const_iterator;
using sentry_type = const_iterator;
range (T& r) : base_type(r.begin(), r.end()) {}
iterator end () { return base_type::end_; }
iterator end () { return base_type::end_; }
const_iterator end () const { return base_type::end_; }
sentry_type sentry () const { return base_type::end_; }
std::size_t size () const { return base_type::end_ - base_type::begin_; }
@@ -82,7 +81,7 @@ namespace boost { namespace cnv
};
template<typename T>
struct range<T*, typename enable_if<cnv::is_char<T> >::type> : public range_base<T*>
struct range<T*, typename std::enable_if<cnv::is_char<T>::value>::type> : public range_base<T*>
{
using this_type = range;
using base_type = range_base<T*>;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -7,10 +7,7 @@
#include <boost/lexical_cast.hpp>
namespace boost { namespace cnv
{
struct lexical_cast;
}}
namespace boost { namespace cnv { struct lexical_cast; }}
/// @brief boost::lexical_cast-based converter
/// @details The purpose of the converter is to

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -6,12 +6,14 @@
#define BOOST_CONVERT_PARAMETERS_HPP
#include <boost/parameter/name.hpp>
#include <boost/parameter/is_argument_pack.hpp>
#include <boost/mpl/has_key.hpp>
namespace boost { namespace cnv
{
enum class adjust { left, right, center };
enum class base { bin =2, oct =8, dec =10, hex =16 };
enum class notation { fixed, scientific };
enum class adjust : uint8_t { left, right, center };
enum class base : uint8_t { bin =2, oct =8, dec =10, hex =16 };
enum class notation : uint8_t { fixed, scientific, hex };
namespace parameter
{
@@ -23,6 +25,7 @@ namespace boost { namespace cnv
BOOST_PARAMETER_NAME((precision, type) precision)
BOOST_PARAMETER_NAME(( skipws, type) skipws)
BOOST_PARAMETER_NAME((uppercase, type) uppercase)
BOOST_PARAMETER_NAME((lowercase, type) lowercase)
BOOST_PARAMETER_NAME(( width, type) width)
}
}}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -9,14 +9,10 @@
#include <boost/make_default.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/find.hpp>
#include <boost/range/as_literal.hpp>
#include <string>
#include <cstdio>
namespace boost { namespace cnv
{
struct printf;
}}
namespace boost { namespace cnv { struct printf; }}
struct boost::cnv::printf : boost::cnv::cnvbase<boost::cnv::printf>
{
@@ -29,9 +25,9 @@ struct boost::cnv::printf : boost::cnv::cnvbase<boost::cnv::printf>
cnv::range<char*>
to_str(in_type value_in, char* buf) const
{
char const* fmt = pformat(pos<in_type>());
int const num_chars = snprintf(buf, bufsize_, fmt, precision_, value_in);
bool const success = num_chars < bufsize_;
char_cptr fmt = printf_format(pos<in_type>());
int num_chars = snprintf(buf, bufsize_, fmt, precision_, value_in);
bool success = num_chars < bufsize_;
return cnv::range<char*>(buf, success ? (buf + num_chars) : buf);
}
@@ -39,8 +35,9 @@ struct boost::cnv::printf : boost::cnv::cnvbase<boost::cnv::printf>
void
str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
{
out_type result = boost::make_default<out_type>();
int const num_read = sscanf(&*range.begin(), format(pos<out_type>()), &result);
out_type result = boost::make_default<out_type>();
char_cptr fmt = sscanf_format(pos<out_type>());
int num_read = sscanf(&*range.begin(), fmt, &result);
if (num_read == 1)
result_out = result;
@@ -50,37 +47,65 @@ struct boost::cnv::printf : boost::cnv::cnvbase<boost::cnv::printf>
template<typename Type> int pos() const
{
using managed_types = boost::mpl::vector<double, float,
int, unsigned int,
short int, unsigned short int,
long int, unsigned long int>;
using type_iterator = typename boost::mpl::find<managed_types, Type>::type;
using type_pos = typename type_iterator::pos;
// C1. The orders of types and formats must match.
return type_pos::value;
}
using types = boost::mpl::vector<
double, float, int, unsigned int, short int,
unsigned short int, long int, unsigned long int>;
using found = typename boost::mpl::find<types, Type>::type;
using pos = typename found::pos;
char const* pformat(int pos) const
{
static char const* d_fmt[] = { "%.*f", "%.*f", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }; // Must match managed_types
static char const* x_fmt[] = { "%.*f", "%.*f", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }; // Must match managed_types
static char const* o_fmt[] = { "%.*f", "%.*f", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }; // Must match managed_types
char const* fmt = base_ == boost::cnv::base::dec ? d_fmt[pos]
: base_ == boost::cnv::base::hex ? x_fmt[pos]
: base_ == boost::cnv::base::oct ? o_fmt[pos]
: (BOOST_ASSERT(0), nullptr);
return fmt;
return pos::value;
}
char const* format(int pos) const
char_cptr printf_format(int type_pos) const
{
static char const* d_fmt[] = { "%f", "%f", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }; // Must match managed_types
static char const* x_fmt[] = { "%f", "%f", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }; // Must match managed_types
static char const* o_fmt[] = { "%f", "%f", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }; // Must match managed_types
char const* fmt = base_ == boost::cnv::base::dec ? d_fmt[pos]
: base_ == boost::cnv::base::hex ? x_fmt[pos]
: base_ == boost::cnv::base::oct ? o_fmt[pos]
: (BOOST_ASSERT(0), nullptr);
return fmt;
char_cptr BOOST_CONSTEXPR_OR_CONST d_fmt[3][8] =
{
{ "%.*f", "%.*f", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }, //C1. fxd
{ "%.*e", "%.*e", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" }, //C1. sci
{ "%.*a", "%.*a", "%.*d", "%.*u", "%.*hd", "%.*hu", "%.*ld", "%.*lu" } //C1. hex
};
char_cptr BOOST_CONSTEXPR_OR_CONST x_fmt[3][8] =
{
{ "%.*f", "%.*f", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }, //C1. fxd
{ "%.*e", "%.*e", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" }, //C1. sci
{ "%.*a", "%.*a", "%.*x", "%.*x", "%.*hx", "%.*hx", "%.*lx", "%.*lx" } //C1. hex
};
char_cptr BOOST_CONSTEXPR_OR_CONST o_fmt[3][8] =
{
{ "%.*f", "%.*f", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }, //C1. fxd
{ "%.*e", "%.*e", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" }, //C1. sci
{ "%.*a", "%.*a", "%.*o", "%.*o", "%.*ho", "%.*ho", "%.*lo", "%.*lo" } //C1. hex
};
return base_ == base::dec ? d_fmt[int(notation_)][type_pos]
: base_ == base::hex ? x_fmt[int(notation_)][type_pos]
: base_ == base::oct ? o_fmt[int(notation_)][type_pos]
: (BOOST_ASSERT(0), nullptr);
}
char_cptr sscanf_format(int type_pos) const
{
char_cptr BOOST_CONSTEXPR_OR_CONST d_fmt[3][8] =
{
{ "%lf", "%f", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }, //C1. fxd
{ "%le", "%e", "%d", "%u", "%hd", "%hu", "%ld", "%lu" }, //C1. sci
{ "%la", "%a", "%d", "%u", "%hd", "%hu", "%ld", "%lu" } //C1. hex
};
char_cptr BOOST_CONSTEXPR_OR_CONST x_fmt[3][8] =
{
{ "%lf", "%f", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }, //C1. fxd
{ "%le", "%e", "%x", "%x", "%hx", "%hx", "%lx", "%lx" }, //C1. sci
{ "%la", "%a", "%x", "%x", "%hx", "%hx", "%lx", "%lx" } //C1. hex
};
char_cptr BOOST_CONSTEXPR_OR_CONST o_fmt[3][8] =
{
{ "%lf", "%f", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }, //C1. fxd
{ "%le", "%e", "%o", "%o", "%ho", "%ho", "%lo", "%lo" }, //C1. sci
{ "%la", "%a", "%o", "%o", "%ho", "%ho", "%lo", "%lo" } //C1. hex
};
return base_ == base::dec ? d_fmt[int(notation_)][type_pos]
: base_ == base::hex ? x_fmt[int(notation_)][type_pos]
: base_ == base::oct ? o_fmt[int(notation_)][type_pos]
: (BOOST_ASSERT(0), nullptr);
}
};

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -10,15 +10,12 @@
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace boost { namespace cnv
{
struct spirit;
}}
namespace boost { namespace cnv { struct spirit; }}
struct boost::cnv::spirit : public boost::cnv::cnvbase<boost::cnv::spirit>
struct boost::cnv::spirit : boost::cnv::cnvbase<boost::cnv::spirit>
{
typedef boost::cnv::spirit this_type;
typedef boost::cnv::cnvbase<this_type> base_type;
using this_type = boost::cnv::spirit;
using base_type = boost::cnv::cnvbase<this_type>;
using base_type::operator();
@@ -26,12 +23,11 @@ struct boost::cnv::spirit : public boost::cnv::cnvbase<boost::cnv::spirit>
void
str_to(cnv::range<string_type> range, optional<out_type>& result_out) const
{
typedef typename cnv::range<string_type>::iterator iterator;
typedef typename boost::spirit::traits::create_parser<out_type>::type parser;
using parser = typename boost::spirit::traits::create_parser<out_type>::type;
iterator beg = range.begin();
iterator end = range.end();
out_type result;
auto beg = range.begin();
auto end = range.end();
auto result = out_type();
if (boost::spirit::qi::parse(beg, end, parser(), result))
if (beg == end) // ensure the whole string has been parsed
@@ -41,11 +37,11 @@ struct boost::cnv::spirit : public boost::cnv::cnvbase<boost::cnv::spirit>
cnv::range<char_type*>
to_str(in_type value_in, char_type* beg) const
{
typedef typename boost::spirit::traits::create_generator<in_type>::type generator;
using generator = typename boost::spirit::traits::create_generator<in_type>::type;
auto end = beg;
bool good = boost::spirit::karma::generate(end, generator(), value_in);
char_type* end = beg;
bool good = boost::spirit::karma::generate(end, generator(), value_in);
return cnv::range<char_type*>(beg, good ? end : beg);
}
};

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -8,18 +8,27 @@
#include <boost/convert/parameters.hpp>
#include <boost/convert/detail/is_string.hpp>
#include <boost/make_default.hpp>
#include <boost/noncopyable.hpp>
#include <sstream>
#include <iomanip>
#define BOOST_CNV_STRING_ENABLE \
template<typename string_type, typename type> \
typename boost::enable_if<cnv::is_string<string_type>, void>::type \
#define BOOST_CNV_STRING_ENABLE \
template<typename string_type, typename type> \
typename std::enable_if<cnv::is_string<string_type>::value, void>::type \
operator()
#define BOOST_CNV_PARAM(PARAM_NAME, PARAM_TYPE) \
this_type& \
operator()(boost::parameter::aux::tag<boost::cnv::parameter::type::PARAM_NAME, PARAM_TYPE>::type const& arg)
#define BOOST_CNV_PARAM_SET(param_name) \
template <typename argument_pack> \
void set_( \
argument_pack const& arg, \
cnv::parameter::type::param_name, \
mpl::true_)
#define BOOST_CNV_PARAM_TRY(param_name) \
this->set_( \
arg, \
cnv::parameter::type::param_name(), \
typename mpl::has_key< \
argument_pack, cnv::parameter::type::param_name>::type());
namespace boost { namespace cnv
{
@@ -30,7 +39,7 @@ namespace boost { namespace cnv
}}
template<class Char>
struct boost::cnv::basic_stream : boost::noncopyable
struct boost::cnv::basic_stream
{
// C01. In string-to-type conversions the "string" must be a CONTIGUOUS ARRAY of
// characters because "ibuffer_type" uses/relies on that (it deals with char_type*).
@@ -70,51 +79,71 @@ struct boost::cnv::basic_stream : boost::noncopyable
using buffer_type::epptr;
};
basic_stream() : stream_(std::ios_base::in | std::ios_base::out) {}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
basic_stream(this_type&& other) : stream_(std::move(other.stream_)) {}
#endif
basic_stream () : stream_(std::ios_base::in | std::ios_base::out) {}
basic_stream (this_type&& other) : stream_(std::move(other.stream_)) {}
basic_stream(this_type const&) = delete;
this_type& operator=(this_type const&) = delete;
BOOST_CNV_STRING_ENABLE(type const& v, optional<string_type>& s) const { to_str(v, s); }
BOOST_CNV_STRING_ENABLE(string_type const& s, optional<type>& r) const { str_to(cnv::range<string_type const>(s), r); }
// Resolve ambiguity of string-to-string
template<typename type> void operator()( char_type const* s, optional<type>& r) const { str_to(cnv::range< char_type const*>(s), r); }
template<typename type> void operator()(stdstr_type const& s, optional<type>& r) const { str_to(cnv::range<stdstr_type const>(s), r); }
// Formatters
template<typename manipulator>
this_type& operator() (manipulator m) { return (stream_ << m, *this); }
typename boost::disable_if<boost::parameter::is_argument_pack<manipulator>, this_type&>::type
operator()(manipulator m) { return (this->stream_ << m, *this); }
this_type& operator() (manipulator_type m) { return (m(stream_), *this); }
this_type& operator() (std::locale const& l) { return (stream_.imbue(l), *this); }
BOOST_CNV_PARAM(locale, std::locale const) { return (stream_.imbue(arg[cnv::parameter::locale]), *this); }
BOOST_CNV_PARAM(precision, int const) { return (stream_.precision(arg[cnv::parameter::precision]), *this); }
BOOST_CNV_PARAM(precision, int) { return (stream_.precision(arg[cnv::parameter::precision]), *this); }
BOOST_CNV_PARAM(width, int const) { return (stream_.width(arg[cnv::parameter::width]), *this); }
BOOST_CNV_PARAM(fill, char const) { return (stream_.fill(arg[cnv::parameter::fill]), *this); }
BOOST_CNV_PARAM(uppercase, bool const)
template<typename argument_pack>
typename std::enable_if<boost::parameter::is_argument_pack<argument_pack>::value, this_type&>::type
operator()(argument_pack const& arg)
{
BOOST_CNV_PARAM_TRY(precision);
BOOST_CNV_PARAM_TRY(width);
BOOST_CNV_PARAM_TRY(fill);
BOOST_CNV_PARAM_TRY(uppercase);
BOOST_CNV_PARAM_TRY(skipws);
BOOST_CNV_PARAM_TRY(adjust);
BOOST_CNV_PARAM_TRY(base);
BOOST_CNV_PARAM_TRY(notation);
return *this;
}
private:
template<typename argument_pack, typename keyword_tag>
void set_(argument_pack const&, keyword_tag, mpl::false_) {}
BOOST_CNV_PARAM_SET (locale) { stream_.imbue(arg[cnv::parameter::locale]); }
BOOST_CNV_PARAM_SET (precision) { stream_.precision(arg[cnv::parameter::precision]); }
BOOST_CNV_PARAM_SET (width) { stream_.width(arg[cnv::parameter::width]); }
BOOST_CNV_PARAM_SET (fill) { stream_.fill(arg[cnv::parameter::fill]); }
BOOST_CNV_PARAM_SET (uppercase)
{
bool uppercase = arg[cnv::parameter::uppercase];
uppercase ? (void) stream_.setf(std::ios::uppercase) : stream_.unsetf(std::ios::uppercase);
return *this;
}
BOOST_CNV_PARAM(skipws, bool const)
BOOST_CNV_PARAM_SET (skipws)
{
bool skipws = arg[cnv::parameter::skipws];
skipws ? (void) stream_.setf(std::ios::skipws) : stream_.unsetf(std::ios::skipws);
return *this;
}
BOOST_CNV_PARAM(adjust, boost::cnv::adjust const)
BOOST_CNV_PARAM_SET (adjust)
{
cnv::adjust adjust = arg[cnv::parameter::adjust];
/**/ if (adjust == cnv::adjust:: left) stream_.setf(std::ios::adjustfield, std::ios:: left);
else if (adjust == cnv::adjust::right) stream_.setf(std::ios::adjustfield, std::ios::right);
else BOOST_ASSERT(!"Not implemented");
return *this;
}
BOOST_CNV_PARAM(base, boost::cnv::base const)
BOOST_CNV_PARAM_SET (base)
{
cnv::base base = arg[cnv::parameter::base];
@@ -122,22 +151,17 @@ struct boost::cnv::basic_stream : boost::noncopyable
else if (base == cnv::base::hex) std::hex(stream_);
else if (base == cnv::base::oct) std::oct(stream_);
else BOOST_ASSERT(!"Not implemented");
return *this;
}
BOOST_CNV_PARAM(notation, boost::cnv::notation const)
BOOST_CNV_PARAM_SET (notation)
{
cnv::notation notation = arg[cnv::parameter::notation];
/**/ if (notation == cnv::notation:: fixed) std::fixed(stream_);
/**/ if (notation == cnv::notation:: fixed) std::fixed(stream_);
else if (notation == cnv::notation::scientific) std::scientific(stream_);
else if (notation == cnv::notation:: hex) std::hexfloat(stream_);
else BOOST_ASSERT(!"Not implemented");
return *this;
}
private:
template<typename string_type, typename out_type> void str_to(cnv::range<string_type>, optional<out_type>&) const;
template<typename string_type, typename in_type> void to_str(in_type const&, optional<string_type>&) const;
@@ -158,7 +182,7 @@ boost::cnv::basic_stream<char_type>::to_str(
if (!(stream_ << value_in).fail())
{
buffer_type* buf = stream_.rdbuf();
obuffer_type* obuf = static_cast<obuffer_type*>(buf);
obuffer_type* obuf = reinterpret_cast<obuffer_type*>(buf);
char_type const* beg = obuf->pbase();
char_type const* end = obuf->pptr();
@@ -194,6 +218,7 @@ boost::cnv::basic_stream<char_type>::str_to(
}
#undef BOOST_CNV_STRING_ENABLE
#undef BOOST_CNV_PARAM
#undef BOOST_CNV_PARAM_SET
#undef BOOST_CNV_PARAM_TRY
#endif // BOOST_CONVERT_STRINGSTREAM_BASED_CONVERTER_HPP

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2009-2016 Vladimir Batov.
// Copyright (c) 2009-2020 Vladimir Batov.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
@@ -6,33 +6,20 @@
#define BOOST_CONVERT_STRTOL_CONVERTER_HPP
#include <boost/convert/base.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/math/special_functions/round.hpp>
#include <limits>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cstdlib>
#if __GNUC__ == 4 && __GNUC_MINOR__ <= 2
namespace std
{
using ::strtold; // Tests indicated that gcc-4.2.1 does not have 'std::strtold'
}
#endif
namespace boost { namespace cnv
{
struct strtol;
}}
namespace boost { namespace cnv { struct strtol; }}
/// @brief std::strtol-based extended converter
/// @details The converter offers a fairly decent overall performance and moderate formatting facilities.
struct boost::cnv::strtol : public boost::cnv::cnvbase<boost::cnv::strtol>
struct boost::cnv::strtol : boost::cnv::cnvbase<boost::cnv::strtol>
{
typedef boost::cnv::strtol this_type;
typedef boost::cnv::cnvbase<this_type> base_type;
using this_type = boost::cnv::strtol;
using base_type = boost::cnv::cnvbase<this_type>;
using base_type::operator();
@@ -74,7 +61,7 @@ boost::cnv::strtol::i_to_str(Type in_value, char_type* buf) const
{
// C1. Base=10 optimization improves performance 10%
typedef typename boost::make_unsigned<Type>::type unsigned_type;
using unsigned_type = typename std::make_unsigned<Type>::type;
char_type* beg = buf + bufsize_ / 2;
char_type* end = beg;
@@ -122,14 +109,14 @@ inline
boost::cnv::range<char_type*>
boost::cnv::strtol::to_str(double value, char_type* buf) const
{
char_type* beg = buf + bufsize_ / 2;
char_type* end = beg;
char_type* ipos = end - 1;
bool const is_negative = (value < 0) ? (value = -value, true) : false;
double ipart = std::floor(value);
double fpart = adjust_fraction(value - ipart, precision_);
int precision = precision_;
int const base = 10;
char_type* beg = buf + bufsize_ / 2;
char_type* end = beg;
char_type* ipos = end - 1;
bool is_negative = (value < 0) ? (value = -value, true) : false;
double ipart = std::floor(value);
double fpart = adjust_fraction(value - ipart, precision_);
int precision = precision_;
int const base = 10;
for (; 1 <= ipart; ipart /= base)
*(--beg) = get_char(int(ipart - std::floor(ipart / base) * base));
@@ -158,24 +145,26 @@ template<typename string_type, typename out_type>
void
boost::cnv::strtol::str_to_i(cnv::range<string_type> range, boost::optional<out_type>& result_out) const
{
typedef typename boost::make_unsigned<out_type>::type unsigned_type;
typedef cnv::range<string_type> range_type;
typedef typename range_type::iterator iterator;
using uint_type = unsigned int;
using unsigned_type = typename std::make_unsigned<out_type>::type;
using range_type = cnv::range<string_type>;
using iterator = typename range_type::iterator;
iterator s = range.begin();
unsigned int ch = *s;
bool const is_negative = ch == '-' ? (ch = *++s, true) : ch == '+' ? (ch = *++s, false) : false;
bool const is_unsigned = boost::is_same<out_type, unsigned_type>::value;
int base = int(base_);
iterator s = range.begin();
uint_type ch = *s;
bool is_negative = ch == '-' ? (ch = *++s, true) : ch == '+' ? (ch = *++s, false) : false;
bool is_unsigned = std::is_same<out_type, unsigned_type>::value;
uint_type base = uint_type(base_);
/**/ if (is_negative && is_unsigned) return;
else if ((base == 0 || base == 16) && ch == '0' && (*++s == 'x' || *s == 'X')) ++s, base = 16;
else if (base == 0) base = ch == '0' ? (++s, 8) : 10;
unsigned_type const max = (std::numeric_limits<out_type>::max)() + (is_negative ? 1 : 0);
unsigned_type const cutoff = max / base;
unsigned int const cutlim = max % base;
unsigned_type result = 0;
unsigned_type max = (std::numeric_limits<out_type>::max)();
unsigned_type umax = max + (is_negative ? 1 : 0);
unsigned_type cutoff = umax / base;
uint_type cutlim = umax % base;
unsigned_type result = 0;
for (; s != range.sentry(); ++s)
{
@@ -203,8 +192,8 @@ boost::cnv::strtol::str_to_d(cnv::range<string_type> range, optional<out_type>&
// Consequently, we have to copy the supplied range into a string for strtold().
// C3. Check if the end-of-string was reached -- *cnv_end == 0.
typedef cnv::range<string_type> range_type;
typedef typename range_type::value_type ch_type;
using range_type = cnv::range<string_type>;
using ch_type = typename range_type::value_type;
size_t const sz = 128;
ch_type str[sz] = {0}; std::strncpy(str, &*range.begin(), (std::min)(sz - 1, range.size()));