update boost
This commit is contained in:
@@ -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
|
||||
|
||||
85
linx64/include/boost/convert/charconv.hpp
Normal file
85
linx64/include/boost/convert/charconv.hpp
Normal 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
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {}; \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
};
|
||||
}}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*>;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
|
||||
Reference in New Issue
Block a user