1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-13 17:48:00 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
CRTLinkage: dynamic
LibraryLinkage: dynamic

View File

@@ -0,0 +1,8 @@
Package: boost-lexical-cast
Version: 1.79.0
Depends: boost-array, boost-assert, boost-config, boost-container, boost-core, boost-integer, boost-numeric-conversion, boost-range, boost-static-assert, boost-throw-exception, boost-type-traits, boost-vcpkg-helpers
Architecture: x64-windows
Multi-Arch: same
Abi: 25419bb02ca50db7244c1bbdfc53d5ea42afab7c3d07470da51f773f6c556a68
Description: Boost lexical_cast module
Type: Port

View File

@@ -0,0 +1,138 @@
//-----------------------------------------------------------------------------
// boost detail/templated_streams.hpp header file
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
// Copyright (c) 2013 John Maddock, Antony Polukhin
//
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_DETAIL_BASIC_POINTERBUF_HPP
#define BOOST_DETAIL_BASIC_POINTERBUF_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include "boost/config.hpp"
#include <streambuf>
namespace boost { namespace detail {
//
// class basic_pointerbuf:
// acts as a stream buffer which wraps around a pair of pointers:
//
template <class charT, class BufferT >
class basic_pointerbuf : public BufferT {
protected:
typedef BufferT base_type;
typedef basic_pointerbuf<charT, BufferT> this_type;
typedef typename base_type::int_type int_type;
typedef typename base_type::char_type char_type;
typedef typename base_type::pos_type pos_type;
typedef ::std::streamsize streamsize;
typedef typename base_type::off_type off_type;
public:
basic_pointerbuf() : base_type() { this_type::setbuf(0, 0); }
const charT* getnext() { return this->gptr(); }
#ifndef BOOST_NO_USING_TEMPLATE
using base_type::pptr;
using base_type::pbase;
#else
charT* pptr() const { return base_type::pptr(); }
charT* pbase() const { return base_type::pbase(); }
#endif
protected:
// VC mistakenly assumes that `setbuf` and other functions are not referenced.
// Marking those functions with `inline` suppresses the warnings.
// There must be no harm from marking virtual functions as inline: inline virtual
// call can be inlined ONLY when the compiler knows the "exact class".
inline base_type* setbuf(char_type* s, streamsize n) BOOST_OVERRIDE;
inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) BOOST_OVERRIDE;
inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) BOOST_OVERRIDE;
private:
basic_pointerbuf& operator=(const basic_pointerbuf&);
basic_pointerbuf(const basic_pointerbuf&);
};
template<class charT, class BufferT>
BufferT*
basic_pointerbuf<charT, BufferT>::setbuf(char_type* s, streamsize n)
{
this->setg(s, s, s + n);
return this;
}
template<class charT, class BufferT>
typename basic_pointerbuf<charT, BufferT>::pos_type
basic_pointerbuf<charT, BufferT>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
{
typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
if(which & ::std::ios_base::out)
return pos_type(off_type(-1));
std::ptrdiff_t size = this->egptr() - this->eback();
std::ptrdiff_t pos = this->gptr() - this->eback();
charT* g = this->eback();
switch(static_cast<cast_type>(way))
{
case ::std::ios_base::beg:
if((off < 0) || (off > size))
return pos_type(off_type(-1));
else
this->setg(g, g + off, g + size);
break;
case ::std::ios_base::end:
if((off < 0) || (off > size))
return pos_type(off_type(-1));
else
this->setg(g, g + size - off, g + size);
break;
case ::std::ios_base::cur:
{
std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
if((newpos < 0) || (newpos > size))
return pos_type(off_type(-1));
else
this->setg(g, g + newpos, g + size);
break;
}
default: ;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4244)
#endif
return static_cast<pos_type>(this->gptr() - this->eback());
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<class charT, class BufferT>
typename basic_pointerbuf<charT, BufferT>::pos_type
basic_pointerbuf<charT, BufferT>::seekpos(pos_type sp, ::std::ios_base::openmode which)
{
if(which & ::std::ios_base::out)
return pos_type(off_type(-1));
off_type size = static_cast<off_type>(this->egptr() - this->eback());
charT* g = this->eback();
if(off_type(sp) <= size)
{
this->setg(g, g + off_type(sp), g + size);
}
return pos_type(off_type(-1));
}
}} // namespace boost::detail
#endif // BOOST_DETAIL_BASIC_POINTERBUF_HPP

View File

@@ -0,0 +1,185 @@
// Copyright Alexander Nasonov & Paul A. Bristow 2006.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#include <climits>
#include <ios>
#include <limits>
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#ifndef BOOST_NO_IS_ABSTRACT
// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_abstract.hpp>
#endif
#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \
(defined(BOOST_MSVC) && (BOOST_MSVC<1310))
#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#endif
#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#include <boost/assert.hpp>
#else
#include <boost/static_assert.hpp>
#endif
namespace boost { namespace detail {
class lcast_abstract_stub {};
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
// Calculate an argument to pass to std::ios_base::precision from
// lexical_cast. See alternative implementation for broken standard
// libraries in lcast_get_precision below. Keep them in sync, please.
template<class T>
struct lcast_precision
{
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_abstract<T>::value
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
BOOST_STATIC_CONSTANT(bool, use_default_precision =
!limits::is_specialized || limits::is_exact
);
BOOST_STATIC_CONSTANT(bool, is_specialized_bin =
!use_default_precision &&
limits::radix == 2 && limits::digits > 0
);
BOOST_STATIC_CONSTANT(bool, is_specialized_dec =
!use_default_precision &&
limits::radix == 10 && limits::digits10 > 0
);
BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max =
boost::integer_traits<std::streamsize>::const_max
);
BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U);
BOOST_STATIC_ASSERT(!is_specialized_dec ||
precision_dec <= streamsize_max + 0UL
);
BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
2UL + limits::digits * 30103UL / 100000UL
);
BOOST_STATIC_ASSERT(!is_specialized_bin ||
(limits::digits + 0UL < ULONG_MAX / 30103UL &&
precision_bin > limits::digits10 + 0UL &&
precision_bin <= streamsize_max + 0UL)
);
BOOST_STATIC_CONSTANT(std::streamsize, value =
is_specialized_bin ? precision_bin
: is_specialized_dec ? precision_dec : 6
);
};
#endif
template<class T>
inline std::streamsize lcast_get_precision(T* = 0)
{
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
return lcast_precision<T>::value;
#else // Follow lcast_precision algorithm at run-time:
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_abstract<T>::value
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
bool const use_default_precision =
!limits::is_specialized || limits::is_exact;
if(!use_default_precision)
{ // Includes all built-in floating-point types, float, double ...
// and UDT types for which digits (significand bits) is defined (not zero)
bool const is_specialized_bin =
limits::radix == 2 && limits::digits > 0;
bool const is_specialized_dec =
limits::radix == 10 && limits::digits10 > 0;
std::streamsize const streamsize_max =
(boost::integer_traits<std::streamsize>::max)();
(void)streamsize_max;
if(is_specialized_bin)
{ // Floating-point types with
// limits::digits defined by the specialization.
unsigned long const digits = limits::digits;
unsigned long const precision = 2UL + digits * 30103UL / 100000UL;
// unsigned long is selected because it is at least 32-bits
// and thus ULONG_MAX / 30103UL is big enough for all types.
BOOST_ASSERT(
digits < ULONG_MAX / 30103UL &&
precision > limits::digits10 + 0UL &&
precision <= streamsize_max + 0UL
);
return precision;
}
else if(is_specialized_dec)
{ // Decimal Floating-point type, most likely a User Defined Type
// rather than a real floating-point hardware type.
unsigned int const precision = limits::digits10 + 1U;
BOOST_ASSERT(precision <= streamsize_max + 0UL);
return precision;
}
}
// Integral type (for which precision has no effect)
// or type T for which limits is NOT specialized,
// so assume stream precision remains the default 6 decimal digits.
// Warning: if your User-defined Floating-point type T is NOT specialized,
// then you may lose accuracy by only using 6 decimal digits.
// To avoid this, you need to specialize T with either
// radix == 2 and digits == the number of significand bits,
// OR
// radix = 10 and digits10 == the number of decimal digits.
return 6;
#endif
}
template<class T>
inline void lcast_set_precision(std::ios_base& stream, T*)
{
stream.precision(lcast_get_precision<T>());
}
template<class Source, class Target>
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
{
std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
stream.precision(s > t ? s : t);
}
}}
#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED

View File

@@ -0,0 +1,105 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_INCLUDED
#define BOOST_LEXICAL_CAST_INCLUDED
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <boost/range/iterator_range_core.hpp>
#include <boost/lexical_cast/bad_lexical_cast.hpp>
#include <boost/lexical_cast/try_lexical_convert.hpp>
namespace boost
{
template <typename Target, typename Source>
inline Target lexical_cast(const Source &arg)
{
Target result = Target();
if (!boost::conversion::detail::try_lexical_convert(arg, result)) {
boost::conversion::detail::throw_bad_cast<Source, Target>();
}
return result;
}
template <typename Target>
inline Target lexical_cast(const char* chars, std::size_t count)
{
return ::boost::lexical_cast<Target>(
::boost::iterator_range<const char*>(chars, chars + count)
);
}
template <typename Target>
inline Target lexical_cast(const unsigned char* chars, std::size_t count)
{
return ::boost::lexical_cast<Target>(
::boost::iterator_range<const unsigned char*>(chars, chars + count)
);
}
template <typename Target>
inline Target lexical_cast(const signed char* chars, std::size_t count)
{
return ::boost::lexical_cast<Target>(
::boost::iterator_range<const signed char*>(chars, chars + count)
);
}
#ifndef BOOST_LCAST_NO_WCHAR_T
template <typename Target>
inline Target lexical_cast(const wchar_t* chars, std::size_t count)
{
return ::boost::lexical_cast<Target>(
::boost::iterator_range<const wchar_t*>(chars, chars + count)
);
}
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
template <typename Target>
inline Target lexical_cast(const char16_t* chars, std::size_t count)
{
return ::boost::lexical_cast<Target>(
::boost::iterator_range<const char16_t*>(chars, chars + count)
);
}
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
template <typename Target>
inline Target lexical_cast(const char32_t* chars, std::size_t count)
{
return ::boost::lexical_cast<Target>(
::boost::iterator_range<const char32_t*>(chars, chars + count)
);
}
#endif
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // BOOST_LEXICAL_CAST_INCLUDED

View File

@@ -0,0 +1,106 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP
#define BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <exception>
#include <typeinfo>
#include <boost/throw_exception.hpp>
namespace boost
{
// exception used to indicate runtime lexical_cast failure
class BOOST_SYMBOL_VISIBLE bad_lexical_cast :
// workaround MSVC bug with std::bad_cast when _HAS_EXCEPTIONS == 0
#if defined(BOOST_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
public std::exception
#else
public std::bad_cast
#endif
#if defined(BOOST_BORLANDC) && BOOST_WORKAROUND( BOOST_BORLANDC, < 0x560 )
// under bcc32 5.5.1 bad_cast doesn't derive from exception
, public std::exception
#endif
{
public:
bad_lexical_cast() BOOST_NOEXCEPT
#ifndef BOOST_NO_TYPEID
: source(&typeid(void)), target(&typeid(void))
#endif
{}
const char *what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {
return "bad lexical cast: "
"source type value could not be interpreted as target";
}
~bad_lexical_cast() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
{}
#ifndef BOOST_NO_TYPEID
private:
#ifdef BOOST_NO_STD_TYPEINFO
typedef ::type_info type_info_t;
#else
typedef ::std::type_info type_info_t;
#endif
public:
bad_lexical_cast(
const type_info_t &source_type_arg,
const type_info_t &target_type_arg) BOOST_NOEXCEPT
: source(&source_type_arg), target(&target_type_arg)
{}
const type_info_t &source_type() const BOOST_NOEXCEPT {
return *source;
}
const type_info_t &target_type() const BOOST_NOEXCEPT {
return *target;
}
private:
const type_info_t *source;
const type_info_t *target;
#endif
};
namespace conversion { namespace detail {
#ifdef BOOST_NO_TYPEID
template <class S, class T>
inline void throw_bad_cast() {
boost::throw_exception(bad_lexical_cast());
}
#else
template <class S, class T>
inline void throw_bad_cast() {
boost::throw_exception(bad_lexical_cast(typeid(S), typeid(T)));
}
#endif
}} // namespace conversion::detail
} // namespace boost
#endif // BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP

View File

@@ -0,0 +1,498 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <cstddef>
#include <string>
#include <boost/limits.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_float.hpp>
#include <boost/type_traits/has_left_shift.hpp>
#include <boost/type_traits/has_right_shift.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lcast_precision.hpp>
#include <boost/lexical_cast/detail/widest_char.hpp>
#include <boost/lexical_cast/detail/is_character.hpp>
#ifndef BOOST_NO_CXX11_HDR_ARRAY
#include <array>
#endif
#include <boost/array.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/lexical_cast/detail/converter_lexical_streams.hpp>
namespace boost {
namespace detail // normalize_single_byte_char<Char>
{
// Converts signed/unsigned char to char
template < class Char >
struct normalize_single_byte_char
{
typedef Char type;
};
template <>
struct normalize_single_byte_char< signed char >
{
typedef char type;
};
template <>
struct normalize_single_byte_char< unsigned char >
{
typedef char type;
};
}
namespace detail // deduce_character_type_later<T>
{
// Helper type, meaning that stram character for T must be deduced
// at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
template < class T > struct deduce_character_type_later {};
}
namespace detail // stream_char_common<T>
{
// Selectors to choose stream character type (common for Source and Target)
// Returns one of char, wchar_t, char16_t, char32_t or deduce_character_type_later<T> types
// Executed on Stage 1 (See deduce_source_char<T> and deduce_target_char<T>)
template < typename Type >
struct stream_char_common: public boost::conditional<
boost::detail::is_character< Type >::value,
Type,
boost::detail::deduce_character_type_later< Type >
> {};
template < typename Char >
struct stream_char_common< Char* >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< Char* >
> {};
template < typename Char >
struct stream_char_common< const Char* >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< const Char* >
> {};
template < typename Char >
struct stream_char_common< boost::iterator_range< Char* > >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::iterator_range< Char* > >
> {};
template < typename Char >
struct stream_char_common< boost::iterator_range< const Char* > >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::iterator_range< const Char* > >
> {};
template < class Char, class Traits, class Alloc >
struct stream_char_common< std::basic_string< Char, Traits, Alloc > >
{
typedef Char type;
};
template < class Char, class Traits, class Alloc >
struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
{
typedef Char type;
};
template < typename Char, std::size_t N >
struct stream_char_common< boost::array< Char, N > >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::array< Char, N > >
> {};
template < typename Char, std::size_t N >
struct stream_char_common< boost::array< const Char, N > >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::array< const Char, N > >
> {};
#ifndef BOOST_NO_CXX11_HDR_ARRAY
template < typename Char, std::size_t N >
struct stream_char_common< std::array<Char, N > >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< std::array< Char, N > >
> {};
template < typename Char, std::size_t N >
struct stream_char_common< std::array< const Char, N > >: public boost::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< std::array< const Char, N > >
> {};
#endif
#ifdef BOOST_HAS_INT128
template <> struct stream_char_common< boost::int128_type >: public boost::type_identity< char > {};
template <> struct stream_char_common< boost::uint128_type >: public boost::type_identity< char > {};
#endif
#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <>
struct stream_char_common< wchar_t >
{
typedef char type;
};
#endif
}
namespace detail // deduce_source_char_impl<T>
{
// If type T is `deduce_character_type_later` type, then tries to deduce
// character type using boost::has_left_shift<T> metafunction.
// Otherwise supplied type T is a character type, that must be normalized
// using normalize_single_byte_char<Char>.
// Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
template < class Char >
struct deduce_source_char_impl
{
typedef BOOST_DEDUCED_TYPENAME boost::detail::normalize_single_byte_char< Char >::type type;
};
template < class T >
struct deduce_source_char_impl< deduce_character_type_later< T > >
{
typedef boost::has_left_shift< std::basic_ostream< char >, T > result_t;
#if defined(BOOST_LCAST_NO_WCHAR_T)
BOOST_STATIC_ASSERT_MSG((result_t::value),
"Source type is not std::ostream`able and std::wostream`s are not supported by your STL implementation");
typedef char type;
#else
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
result_t::value, char, wchar_t
>::type type;
BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_left_shift< std::basic_ostream< type >, T >::value),
"Source type is neither std::ostream`able nor std::wostream`able");
#endif
};
}
namespace detail // deduce_target_char_impl<T>
{
// If type T is `deduce_character_type_later` type, then tries to deduce
// character type using boost::has_right_shift<T> metafunction.
// Otherwise supplied type T is a character type, that must be normalized
// using normalize_single_byte_char<Char>.
// Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
template < class Char >
struct deduce_target_char_impl
{
typedef BOOST_DEDUCED_TYPENAME normalize_single_byte_char< Char >::type type;
};
template < class T >
struct deduce_target_char_impl< deduce_character_type_later<T> >
{
typedef boost::has_right_shift<std::basic_istream<char>, T > result_t;
#if defined(BOOST_LCAST_NO_WCHAR_T)
BOOST_STATIC_ASSERT_MSG((result_t::value),
"Target type is not std::istream`able and std::wistream`s are not supported by your STL implementation");
typedef char type;
#else
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
result_t::value, char, wchar_t
>::type type;
BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value),
"Target type is neither std::istream`able nor std::wistream`able");
#endif
};
}
namespace detail // deduce_target_char<T> and deduce_source_char<T>
{
// We deduce stream character types in two stages.
//
// Stage 1 is common for Target and Source. At Stage 1 we get
// non normalized character type (may contain unsigned/signed char)
// or deduce_character_type_later<T> where T is the original type.
// Stage 1 is executed by stream_char_common<T>
//
// At Stage 2 we normalize character types or try to deduce character
// type using metafunctions.
// Stage 2 is executed by deduce_target_char_impl<T> and
// deduce_source_char_impl<T>
//
// deduce_target_char<T> and deduce_source_char<T> functions combine
// both stages
template < class T >
struct deduce_target_char
{
typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
typedef BOOST_DEDUCED_TYPENAME deduce_target_char_impl< stage1_type >::type stage2_type;
typedef stage2_type type;
};
template < class T >
struct deduce_source_char
{
typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
typedef BOOST_DEDUCED_TYPENAME deduce_source_char_impl< stage1_type >::type stage2_type;
typedef stage2_type type;
};
}
namespace detail // extract_char_traits template
{
// We are attempting to get char_traits<> from T
// template parameter. Otherwise we'll be using std::char_traits<Char>
template < class Char, class T >
struct extract_char_traits
: boost::false_type
{
typedef std::char_traits< Char > trait_t;
};
template < class Char, class Traits, class Alloc >
struct extract_char_traits< Char, std::basic_string< Char, Traits, Alloc > >
: boost::true_type
{
typedef Traits trait_t;
};
template < class Char, class Traits, class Alloc>
struct extract_char_traits< Char, boost::container::basic_string< Char, Traits, Alloc > >
: boost::true_type
{
typedef Traits trait_t;
};
}
namespace detail // array_to_pointer_decay<T>
{
template<class T>
struct array_to_pointer_decay
{
typedef T type;
};
template<class T, std::size_t N>
struct array_to_pointer_decay<T[N]>
{
typedef const T * type;
};
}
namespace detail // lcast_src_length
{
// Return max. length of string representation of Source;
template< class Source, // Source type of lexical_cast.
class Enable = void // helper type
>
struct lcast_src_length
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
// Helper for integral types.
// Notes on length calculation:
// Max length for 32bit int with grouping "\1" and thousands_sep ',':
// "-2,1,4,7,4,8,3,6,4,7"
// ^ - is_signed
// ^ - 1 digit not counted by digits10
// ^^^^^^^^^^^^^^^^^^ - digits10 * 2
//
// Constant is_specialized is used instead of constant 1
// to prevent buffer overflow in a rare case when
// <boost/limits.hpp> doesn't add missing specialization for
// numeric_limits<T> for some integral type T.
// When is_specialized is false, the whole expression is 0.
template <class Source>
struct lcast_src_length<
Source, BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_integral<Source> >::type
>
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_CONSTANT(std::size_t, value =
std::numeric_limits<Source>::is_signed +
std::numeric_limits<Source>::is_specialized + /* == 1 */
std::numeric_limits<Source>::digits10 * 2
);
#else
BOOST_STATIC_CONSTANT(std::size_t, value = 156);
BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
#endif
};
// Helper for floating point types.
// -1.23456789e-123456
// ^ sign
// ^ leading digit
// ^ decimal point
// ^^^^^^^^ lcast_precision<Source>::value
// ^ "e"
// ^ exponent sign
// ^^^^^^ exponent (assumed 6 or less digits)
// sign + leading digit + decimal point + "e" + exponent sign == 5
template<class Source>
struct lcast_src_length<
Source, BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_float<Source> >::type
>
{
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
BOOST_STATIC_ASSERT(
std::numeric_limits<Source>::max_exponent10 <= 999999L &&
std::numeric_limits<Source>::min_exponent10 >= -999999L
);
BOOST_STATIC_CONSTANT(std::size_t, value =
5 + lcast_precision<Source>::value + 6
);
#else // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
BOOST_STATIC_CONSTANT(std::size_t, value = 156);
#endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
};
}
namespace detail // lexical_cast_stream_traits<Source, Target>
{
template <class Source, class Target>
struct lexical_cast_stream_traits {
typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<src>::type no_cv_src;
typedef boost::detail::deduce_source_char<no_cv_src> deduce_src_char_metafunc;
typedef BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::type src_char_t;
typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_target_char<Target>::type target_char_t;
typedef BOOST_DEDUCED_TYPENAME boost::detail::widest_char<
target_char_t, src_char_t
>::type char_type;
#if !defined(BOOST_NO_CXX11_CHAR16_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char16_t, src_char_t>::value
&& !boost::is_same<char16_t, target_char_t>::value),
"Your compiler does not have full support for char16_t" );
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char32_t, src_char_t>::value
&& !boost::is_same<char32_t, target_char_t>::value),
"Your compiler does not have full support for char32_t" );
#endif
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::detail::extract_char_traits<char_type, Target>::value,
BOOST_DEDUCED_TYPENAME boost::detail::extract_char_traits<char_type, Target>,
BOOST_DEDUCED_TYPENAME boost::detail::extract_char_traits<char_type, no_cv_src>
>::type::trait_t traits;
typedef boost::integral_constant<
bool,
boost::is_same<char, src_char_t>::value && // source is not a wide character based type
(sizeof(char) != sizeof(target_char_t)) && // target type is based on wide character
(!(boost::detail::is_character<no_cv_src>::value))
> is_string_widening_required_t;
typedef boost::integral_constant<
bool,
!(boost::is_integral<no_cv_src>::value ||
boost::detail::is_character<
BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type // if we did not get character type at stage1
>::value // then we have no optimization for that type
)
> is_source_input_not_optimized_t;
// If we have an optimized conversion for
// Source, we do not need to construct stringbuf.
BOOST_STATIC_CONSTANT(bool, requires_stringbuf =
(is_string_widening_required_t::value || is_source_input_not_optimized_t::value)
);
typedef boost::detail::lcast_src_length<no_cv_src> len_t;
};
}
namespace detail
{
template<typename Target, typename Source>
struct lexical_converter_impl
{
typedef lexical_cast_stream_traits<Source, Target> stream_trait;
typedef detail::lexical_istream_limited_src<
BOOST_DEDUCED_TYPENAME stream_trait::char_type,
BOOST_DEDUCED_TYPENAME stream_trait::traits,
stream_trait::requires_stringbuf,
stream_trait::len_t::value + 1
> i_interpreter_type;
typedef detail::lexical_ostream_limited_src<
BOOST_DEDUCED_TYPENAME stream_trait::char_type,
BOOST_DEDUCED_TYPENAME stream_trait::traits
> o_interpreter_type;
static inline bool try_convert(const Source& arg, Target& result) {
i_interpreter_type i_interpreter;
// Disabling ADL, by directly specifying operators.
if (!(i_interpreter.operator <<(arg)))
return false;
o_interpreter_type out(i_interpreter.cbegin(), i_interpreter.cend());
// Disabling ADL, by directly specifying operators.
if(!(out.operator >>(result)))
return false;
return true;
}
};
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP

View File

@@ -0,0 +1,786 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014, Nowember 2016
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <cstddef>
#include <string>
#include <cstring>
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lcast_precision.hpp>
#include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_STD_LOCALE
# include <locale>
#else
# ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
// Getting error at this point means, that your STL library is old/lame/misconfigured.
// If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
// but beware: lexical_cast will understand only 'C' locale delimeters and thousands
// separators.
# error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
# error "boost::lexical_cast to use only 'C' locale during conversions."
# endif
#endif
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
#include <boost/lexical_cast/detail/lcast_unsigned_converters.hpp>
#include <boost/lexical_cast/detail/inf_nan.hpp>
#include <istream>
#ifndef BOOST_NO_CXX11_HDR_ARRAY
#include <array>
#endif
#include <boost/array.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_float.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/integer.hpp>
#include <boost/detail/basic_pointerbuf.hpp>
#include <boost/noncopyable.hpp>
#ifndef BOOST_NO_CWCHAR
# include <cwchar>
#endif
namespace boost {
namespace detail // basic_unlockedbuf
{
// acts as a stream buffer which wraps around a pair of pointers
// and gives acces to internals
template <class BufferType, class CharT>
class basic_unlockedbuf : public basic_pointerbuf<CharT, BufferType> {
public:
typedef basic_pointerbuf<CharT, BufferType> base_type;
typedef BOOST_DEDUCED_TYPENAME base_type::streamsize streamsize;
#ifndef BOOST_NO_USING_TEMPLATE
using base_type::pptr;
using base_type::pbase;
using base_type::setbuf;
#else
charT* pptr() const { return base_type::pptr(); }
charT* pbase() const { return base_type::pbase(); }
BufferType* setbuf(char_type* s, streamsize n) { return base_type::setbuf(s, n); }
#endif
};
}
namespace detail
{
struct do_not_construct_out_buffer_t{};
struct do_not_construct_out_stream_t{
do_not_construct_out_stream_t(do_not_construct_out_buffer_t*){}
};
template <class CharT, class Traits>
struct out_stream_helper_trait {
#if defined(BOOST_NO_STRINGSTREAM)
typedef std::ostream out_stream_t;
typedef basic_unlockedbuf<std::strstreambuf, char> stringbuffer_t;
#elif defined(BOOST_NO_STD_LOCALE)
typedef std::ostream out_stream_t;
typedef basic_unlockedbuf<std::stringbuf, char> stringbuffer_t;
typedef basic_unlockedbuf<std::streambuf, char> buffer_t;
#else
typedef std::basic_ostream<CharT, Traits> out_stream_t;
typedef basic_unlockedbuf<std::basic_stringbuf<CharT, Traits>, CharT> stringbuffer_t;
typedef basic_unlockedbuf<std::basic_streambuf<CharT, Traits>, CharT> buffer_t;
#endif
};
}
namespace detail // optimized stream wrappers
{
template< class CharT // a result of widest_char transformation
, class Traits
, bool RequiresStringbuffer
, std::size_t CharacterBufferSize
>
class lexical_istream_limited_src: boost::noncopyable {
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
RequiresStringbuffer,
BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::out_stream_t,
do_not_construct_out_stream_t
>::type deduced_out_stream_t;
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
RequiresStringbuffer,
BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::stringbuffer_t,
do_not_construct_out_buffer_t
>::type deduced_out_buffer_t;
deduced_out_buffer_t out_buffer;
deduced_out_stream_t out_stream;
CharT buffer[CharacterBufferSize];
// After the `operator <<` finishes, `[start, finish)` is
// the range to output by `operator >>`
const CharT* start;
const CharT* finish;
public:
lexical_istream_limited_src() BOOST_NOEXCEPT
: out_buffer()
, out_stream(&out_buffer)
, start(buffer)
, finish(buffer + CharacterBufferSize)
{}
const CharT* cbegin() const BOOST_NOEXCEPT {
return start;
}
const CharT* cend() const BOOST_NOEXCEPT {
return finish;
}
private:
/************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
bool shl_char(CharT ch) BOOST_NOEXCEPT {
Traits::assign(buffer[0], ch);
finish = start + 1;
return true;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
template <class T>
bool shl_char(T ch) {
BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
"boost::lexical_cast does not support narrowing of char types."
"Use boost::locale instead" );
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
std::locale loc;
CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
#else
CharT const w = static_cast<CharT>(ch);
#endif
Traits::assign(buffer[0], w);
finish = start + 1;
return true;
}
#endif
bool shl_char_array(CharT const* str_value) BOOST_NOEXCEPT {
start = str_value;
finish = start + Traits::length(str_value);
return true;
}
template <class T>
bool shl_char_array(T const* str_value) {
BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
"boost::lexical_cast does not support narrowing of char types."
"Use boost::locale instead" );
return shl_input_streamable(str_value);
}
bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT {
start = str;
finish = std::find(start, start + max_size, Traits::to_char_type(0));
return true;
}
template<typename InputStreamable>
bool shl_input_streamable(InputStreamable& input) {
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
// If you have compilation error at this point, than your STL library
// does not support such conversions. Try updating it.
BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
#endif
#ifndef BOOST_NO_EXCEPTIONS
out_stream.exceptions(std::ios::badbit);
try {
#endif
bool const result = !(out_stream << input).fail();
const deduced_out_buffer_t* const p = static_cast<deduced_out_buffer_t*>(
out_stream.rdbuf()
);
start = p->pbase();
finish = p->pptr();
return result;
#ifndef BOOST_NO_EXCEPTIONS
} catch (const ::std::ios_base::failure& /*f*/) {
return false;
}
#endif
}
template <class T>
inline bool shl_unsigned(const T n) {
CharT* tmp_finish = buffer + CharacterBufferSize;
start = lcast_put_unsigned<Traits, T, CharT>(n, tmp_finish).convert();
finish = tmp_finish;
return true;
}
template <class T>
inline bool shl_signed(const T n) {
CharT* tmp_finish = buffer + CharacterBufferSize;
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type utype;
CharT* tmp_start = lcast_put_unsigned<Traits, utype, CharT>(lcast_to_unsigned(n), tmp_finish).convert();
if (n < 0) {
--tmp_start;
CharT const minus = lcast_char_constants<CharT>::minus;
Traits::assign(*tmp_start, minus);
}
start = tmp_start;
finish = tmp_finish;
return true;
}
template <class T, class SomeCharT>
bool shl_real_type(const T& val, SomeCharT* /*begin*/) {
lcast_set_precision(out_stream, &val);
return shl_input_streamable(val);
}
bool shl_real_type(float val, char* begin) {
using namespace std;
const double val_as_double = val;
finish = start +
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
sprintf_s(begin, CharacterBufferSize,
#else
sprintf(begin,
#endif
"%.*g", static_cast<int>(boost::detail::lcast_get_precision<float>()), val_as_double);
return finish > start;
}
bool shl_real_type(double val, char* begin) {
using namespace std;
finish = start +
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
sprintf_s(begin, CharacterBufferSize,
#else
sprintf(begin,
#endif
"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val);
return finish > start;
}
#ifndef __MINGW32__
bool shl_real_type(long double val, char* begin) {
using namespace std;
finish = start +
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
sprintf_s(begin, CharacterBufferSize,
#else
sprintf(begin,
#endif
"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double>()), val );
return finish > start;
}
#endif
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
bool shl_real_type(float val, wchar_t* begin) {
using namespace std;
const double val_as_double = val;
finish = start + swprintf(begin, CharacterBufferSize,
L"%.*g",
static_cast<int>(boost::detail::lcast_get_precision<float >()),
val_as_double );
return finish > start;
}
bool shl_real_type(double val, wchar_t* begin) {
using namespace std;
finish = start + swprintf(begin, CharacterBufferSize,
L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
return finish > start;
}
bool shl_real_type(long double val, wchar_t* begin) {
using namespace std;
finish = start + swprintf(begin, CharacterBufferSize,
L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
return finish > start;
}
#endif
template <class T>
bool shl_real(T val) {
CharT* tmp_finish = buffer + CharacterBufferSize;
if (put_inf_nan(buffer, tmp_finish, val)) {
finish = tmp_finish;
return true;
}
return shl_real_type(val, static_cast<CharT*>(buffer));
}
/************************************ OPERATORS << ( ... ) ********************************/
public:
template<class Alloc>
bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT {
start = str.data();
finish = start + str.length();
return true;
}
template<class Alloc>
bool operator<<(boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT {
start = str.data();
finish = start + str.length();
return true;
}
bool operator<<(bool value) BOOST_NOEXCEPT {
CharT const czero = lcast_char_constants<CharT>::zero;
Traits::assign(buffer[0], Traits::to_char_type(czero + value));
finish = start + 1;
return true;
}
template <class C>
BOOST_DEDUCED_TYPENAME boost::disable_if<boost::is_const<C>, bool>::type
operator<<(const iterator_range<C*>& rng) BOOST_NOEXCEPT {
return (*this) << iterator_range<const C*>(rng.begin(), rng.end());
}
bool operator<<(const iterator_range<const CharT*>& rng) BOOST_NOEXCEPT {
start = rng.begin();
finish = rng.end();
return true;
}
bool operator<<(const iterator_range<const signed char*>& rng) BOOST_NOEXCEPT {
return (*this) << iterator_range<const char*>(
reinterpret_cast<const char*>(rng.begin()),
reinterpret_cast<const char*>(rng.end())
);
}
bool operator<<(const iterator_range<const unsigned char*>& rng) BOOST_NOEXCEPT {
return (*this) << iterator_range<const char*>(
reinterpret_cast<const char*>(rng.begin()),
reinterpret_cast<const char*>(rng.end())
);
}
bool operator<<(char ch) { return shl_char(ch); }
bool operator<<(unsigned char ch) { return ((*this) << static_cast<char>(ch)); }
bool operator<<(signed char ch) { return ((*this) << static_cast<char>(ch)); }
#if !defined(BOOST_LCAST_NO_WCHAR_T)
bool operator<<(wchar_t const* str) { return shl_char_array(str); }
bool operator<<(wchar_t * str) { return shl_char_array(str); }
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
bool operator<<(wchar_t ch) { return shl_char(ch); }
#endif
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
bool operator<<(char16_t ch) { return shl_char(ch); }
bool operator<<(char16_t * str) { return shl_char_array(str); }
bool operator<<(char16_t const * str) { return shl_char_array(str); }
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
bool operator<<(char32_t ch) { return shl_char(ch); }
bool operator<<(char32_t * str) { return shl_char_array(str); }
bool operator<<(char32_t const * str) { return shl_char_array(str); }
#endif
bool operator<<(unsigned char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
bool operator<<(unsigned char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
bool operator<<(signed char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
bool operator<<(signed char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
bool operator<<(char const* str_value) { return shl_char_array(str_value); }
bool operator<<(char* str_value) { return shl_char_array(str_value); }
bool operator<<(short n) { return shl_signed(n); }
bool operator<<(int n) { return shl_signed(n); }
bool operator<<(long n) { return shl_signed(n); }
bool operator<<(unsigned short n) { return shl_unsigned(n); }
bool operator<<(unsigned int n) { return shl_unsigned(n); }
bool operator<<(unsigned long n) { return shl_unsigned(n); }
#if defined(BOOST_HAS_LONG_LONG)
bool operator<<(boost::ulong_long_type n) { return shl_unsigned(n); }
bool operator<<(boost::long_long_type n) { return shl_signed(n); }
#elif defined(BOOST_HAS_MS_INT64)
bool operator<<(unsigned __int64 n) { return shl_unsigned(n); }
bool operator<<( __int64 n) { return shl_signed(n); }
#endif
#ifdef BOOST_HAS_INT128
bool operator<<(const boost::uint128_type& n) { return shl_unsigned(n); }
bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
#endif
bool operator<<(float val) { return shl_real(val); }
bool operator<<(double val) { return shl_real(val); }
bool operator<<(long double val) {
#ifndef __MINGW32__
return shl_real(val);
#else
return shl_real(static_cast<double>(val));
#endif
}
// Adding constness to characters. Constness does not change layout
template <class C, std::size_t N>
BOOST_DEDUCED_TYPENAME boost::disable_if<boost::is_const<C>, bool>::type
operator<<(boost::array<C, N> const& input) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(
(sizeof(boost::array<const C, N>) == sizeof(boost::array<C, N>)),
"boost::array<C, N> and boost::array<const C, N> must have exactly the same layout."
);
return ((*this) << reinterpret_cast<boost::array<const C, N> const& >(input));
}
template <std::size_t N>
bool operator<<(boost::array<const CharT, N> const& input) BOOST_NOEXCEPT {
return shl_char_array_limited(input.data(), N);
}
template <std::size_t N>
bool operator<<(boost::array<const unsigned char, N> const& input) BOOST_NOEXCEPT {
return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input));
}
template <std::size_t N>
bool operator<<(boost::array<const signed char, N> const& input) BOOST_NOEXCEPT {
return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input));
}
#ifndef BOOST_NO_CXX11_HDR_ARRAY
// Making a Boost.Array from std::array
template <class C, std::size_t N>
bool operator<<(std::array<C, N> const& input) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(
(sizeof(std::array<C, N>) == sizeof(boost::array<C, N>)),
"std::array and boost::array must have exactly the same layout. "
"Bug in implementation of std::array or boost::array."
);
return ((*this) << reinterpret_cast<boost::array<C, N> const& >(input));
}
#endif
template <class InStreamable>
bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
};
template <class CharT, class Traits>
class lexical_ostream_limited_src: boost::noncopyable {
//`[start, finish)` is the range to output by `operator >>`
const CharT* start;
const CharT* const finish;
public:
lexical_ostream_limited_src(const CharT* begin, const CharT* end) BOOST_NOEXCEPT
: start(begin)
, finish(end)
{}
/************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
private:
template <typename Type>
bool shr_unsigned(Type& output) {
if (start == finish) return false;
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
bool const has_minus = Traits::eq(minus, *start);
/* We won`t use `start' any more, so no need in decrementing it after */
if (has_minus || Traits::eq(plus, *start)) {
++start;
}
bool const succeed = lcast_ret_unsigned<Traits, Type, CharT>(output, start, finish).convert();
if (has_minus) {
output = static_cast<Type>(0u - output);
}
return succeed;
}
template <typename Type>
bool shr_signed(Type& output) {
if (start == finish) return false;
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
utype out_tmp = 0;
bool const has_minus = Traits::eq(minus, *start);
/* We won`t use `start' any more, so no need in decrementing it after */
if (has_minus || Traits::eq(plus, *start)) {
++start;
}
bool succeed = lcast_ret_unsigned<Traits, utype, CharT>(out_tmp, start, finish).convert();
if (has_minus) {
utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
succeed = succeed && out_tmp<=comp_val;
output = static_cast<Type>(0u - out_tmp);
} else {
utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
succeed = succeed && out_tmp<=comp_val;
output = static_cast<Type>(out_tmp);
}
return succeed;
}
template<typename InputStreamable>
bool shr_using_base_class(InputStreamable& output)
{
BOOST_STATIC_ASSERT_MSG(
(!boost::is_pointer<InputStreamable>::value),
"boost::lexical_cast can not convert to pointers"
);
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
BOOST_STATIC_ASSERT_MSG((boost::is_same<char, CharT>::value),
"boost::lexical_cast can not convert, because your STL library does not "
"support such conversions. Try updating it."
);
#endif
#if defined(BOOST_NO_STRINGSTREAM)
std::istrstream stream(start, static_cast<std::istrstream::streamsize>(finish - start));
#else
typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::buffer_t buffer_t;
buffer_t buf;
// Usually `istream` and `basic_istream` do not modify
// content of buffer; `buffer_t` assures that this is true
buf.setbuf(const_cast<CharT*>(start), static_cast<typename buffer_t::streamsize>(finish - start));
#if defined(BOOST_NO_STD_LOCALE)
std::istream stream(&buf);
#else
std::basic_istream<CharT, Traits> stream(&buf);
#endif // BOOST_NO_STD_LOCALE
#endif // BOOST_NO_STRINGSTREAM
#ifndef BOOST_NO_EXCEPTIONS
stream.exceptions(std::ios::badbit);
try {
#endif
stream.unsetf(std::ios::skipws);
lcast_set_precision(stream, static_cast<InputStreamable*>(0));
return (stream >> output)
&& (stream.get() == Traits::eof());
#ifndef BOOST_NO_EXCEPTIONS
} catch (const ::std::ios_base::failure& /*f*/) {
return false;
}
#endif
}
template<class T>
inline bool shr_xchar(T& output) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
"boost::lexical_cast does not support narrowing of character types."
"Use boost::locale instead" );
bool const ok = (finish - start == 1);
if (ok) {
CharT out;
Traits::assign(out, *start);
output = static_cast<T>(out);
}
return ok;
}
template <std::size_t N, class ArrayT>
bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT {
using namespace std;
const std::size_t size = static_cast<std::size_t>(finish - start);
if (size > N - 1) { // `-1` because we need to store \0 at the end
return false;
}
memcpy(&output[0], start, size * sizeof(CharT));
output[size] = Traits::to_char_type(0);
return true;
}
/************************************ OPERATORS >> ( ... ) ********************************/
public:
bool operator>>(unsigned short& output) { return shr_unsigned(output); }
bool operator>>(unsigned int& output) { return shr_unsigned(output); }
bool operator>>(unsigned long int& output) { return shr_unsigned(output); }
bool operator>>(short& output) { return shr_signed(output); }
bool operator>>(int& output) { return shr_signed(output); }
bool operator>>(long int& output) { return shr_signed(output); }
#if defined(BOOST_HAS_LONG_LONG)
bool operator>>(boost::ulong_long_type& output) { return shr_unsigned(output); }
bool operator>>(boost::long_long_type& output) { return shr_signed(output); }
#elif defined(BOOST_HAS_MS_INT64)
bool operator>>(unsigned __int64& output) { return shr_unsigned(output); }
bool operator>>(__int64& output) { return shr_signed(output); }
#endif
#ifdef BOOST_HAS_INT128
bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); }
bool operator>>(boost::int128_type& output) { return shr_signed(output); }
#endif
bool operator>>(char& output) { return shr_xchar(output); }
bool operator>>(unsigned char& output) { return shr_xchar(output); }
bool operator>>(signed char& output) { return shr_xchar(output); }
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
bool operator>>(wchar_t& output) { return shr_xchar(output); }
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
bool operator>>(char16_t& output) { return shr_xchar(output); }
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
bool operator>>(char32_t& output) { return shr_xchar(output); }
#endif
template<class Alloc>
bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) {
str.assign(start, finish); return true;
}
template<class Alloc>
bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) {
str.assign(start, finish); return true;
}
template <std::size_t N>
bool operator>>(boost::array<CharT, N>& output) BOOST_NOEXCEPT {
return shr_std_array<N>(output);
}
template <std::size_t N>
bool operator>>(boost::array<unsigned char, N>& output) BOOST_NOEXCEPT {
return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
}
template <std::size_t N>
bool operator>>(boost::array<signed char, N>& output) BOOST_NOEXCEPT {
return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
}
#ifndef BOOST_NO_CXX11_HDR_ARRAY
template <class C, std::size_t N>
bool operator>>(std::array<C, N>& output) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(
(sizeof(std::array<C, N>) == sizeof(boost::array<C, N>)),
"std::array<C, N> and boost::array<C, N> must have exactly the same layout."
);
return ((*this) >> reinterpret_cast<boost::array<C, N>& >(output));
}
#endif
bool operator>>(bool& output) BOOST_NOEXCEPT {
output = false; // Suppress warning about uninitalized variable
if (start == finish) return false;
CharT const zero = lcast_char_constants<CharT>::zero;
CharT const plus = lcast_char_constants<CharT>::plus;
CharT const minus = lcast_char_constants<CharT>::minus;
const CharT* const dec_finish = finish - 1;
output = Traits::eq(*dec_finish, zero + 1);
if (!output && !Traits::eq(*dec_finish, zero)) {
return false; // Does not ends on '0' or '1'
}
if (start == dec_finish) return true;
// We may have sign at the beginning
if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
++ start;
}
// Skipping zeros
while (start != dec_finish) {
if (!Traits::eq(zero, *start)) {
return false; // Not a zero => error
}
++ start;
}
return true;
}
private:
// Not optimised converter
template <class T>
bool float_types_converter_internal(T& output) {
if (parse_inf_nan(start, finish, output)) return true;
bool const return_value = shr_using_base_class(output);
/* Some compilers and libraries successfully
* parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
* We are trying to provide a unified behaviour,
* so we just forbid such conversions (as some
* of the most popular compilers/libraries do)
* */
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
CharT const capital_e = lcast_char_constants<CharT>::capital_e;
CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
if ( return_value &&
(
Traits::eq(*(finish-1), lowercase_e) // 1.0e
|| Traits::eq(*(finish-1), capital_e) // 1.0E
|| Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E-
|| Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+
)
) return false;
return return_value;
}
public:
bool operator>>(float& output) { return float_types_converter_internal(output); }
bool operator>>(double& output) { return float_types_converter_internal(output); }
bool operator>>(long double& output) { return float_types_converter_internal(output); }
// Generic istream-based algorithm.
// lcast_streambuf_for_target<InputStreamable>::value is true.
template <typename InputStreamable>
bool operator>>(InputStreamable& output) {
return shr_using_base_class(output);
}
};
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP

View File

@@ -0,0 +1,175 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2016
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_NUMERIC_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_NUMERIC_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/limits.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_float.hpp>
#include <boost/numeric/conversion/cast.hpp>
namespace boost { namespace detail {
template <class Source >
struct detect_precision_loss
{
typedef Source source_type;
typedef boost::numeric::Trunc<Source> Rounder;
typedef BOOST_DEDUCED_TYPENAME conditional<
boost::is_arithmetic<Source>::value, Source, Source const&
>::type argument_type ;
static inline source_type nearbyint(argument_type s, bool& is_ok) BOOST_NOEXCEPT {
const source_type near_int = Rounder::nearbyint(s);
if (near_int && is_ok) {
const source_type orig_div_round = s / near_int;
const source_type eps = std::numeric_limits<source_type>::epsilon();
is_ok = !((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps);
}
return s;
}
typedef typename Rounder::round_style round_style;
};
template <typename Base, class Source>
struct fake_precision_loss: public Base
{
typedef Source source_type ;
typedef BOOST_DEDUCED_TYPENAME conditional<
boost::is_arithmetic<Source>::value, Source, Source const&
>::type argument_type ;
static inline source_type nearbyint(argument_type s, bool& /*is_ok*/) BOOST_NOEXCEPT {
return s;
}
};
struct nothrow_overflow_handler
{
inline bool operator() ( boost::numeric::range_check_result r ) const BOOST_NOEXCEPT {
return (r == boost::numeric::cInRange);
}
};
template <typename Target, typename Source>
inline bool noexcept_numeric_convert(const Source& arg, Target& result) BOOST_NOEXCEPT {
typedef boost::numeric::converter<
Target,
Source,
boost::numeric::conversion_traits<Target, Source >,
nothrow_overflow_handler,
detect_precision_loss<Source >
> converter_orig_t;
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_base_of< detect_precision_loss<Source >, converter_orig_t >::value,
converter_orig_t,
fake_precision_loss<converter_orig_t, Source>
>::type converter_t;
bool res = nothrow_overflow_handler()(converter_t::out_of_range(arg));
if (res) {
result = converter_t::low_level_convert(converter_t::nearbyint(arg, res));
}
return res;
}
template <typename Target, typename Source>
struct lexical_cast_dynamic_num_not_ignoring_minus
{
static inline bool try_convert(const Source &arg, Target& result) BOOST_NOEXCEPT {
return noexcept_numeric_convert<Target, Source >(arg, result);
}
};
template <typename Target, typename Source>
struct lexical_cast_dynamic_num_ignoring_minus
{
static inline bool try_convert(const Source &arg, Target& result) BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_float<Source>::value,
boost::type_identity<Source>,
boost::make_unsigned<Source>
>::type usource_lazy_t;
typedef BOOST_DEDUCED_TYPENAME usource_lazy_t::type usource_t;
if (arg < 0) {
const bool res = noexcept_numeric_convert<Target, usource_t>(0u - arg, result);
result = static_cast<Target>(0u - result);
return res;
} else {
return noexcept_numeric_convert<Target, usource_t>(arg, result);
}
}
};
/*
* lexical_cast_dynamic_num follows the rules:
* 1) If Source can be converted to Target without precision loss and
* without overflows, then assign Source to Target and return
*
* 2) If Source is less than 0 and Target is an unsigned integer,
* then negate Source, check the requirements of rule 1) and if
* successful, assign static_casted Source to Target and return
*
* 3) Otherwise throw a bad_lexical_cast exception
*
*
* Rule 2) required because boost::lexical_cast has the behavior of
* stringstream, which uses the rules of scanf for conversions. And
* in the C99 standard for unsigned input value minus sign is
* optional, so if a negative number is read, no errors will arise
* and the result will be the two's complement.
*/
template <typename Target, typename Source>
struct dynamic_num_converter_impl
{
static inline bool try_convert(const Source &arg, Target& result) BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_unsigned<Target>::value &&
(boost::is_signed<Source>::value || boost::is_float<Source>::value) &&
!(boost::is_same<Source, bool>::value) &&
!(boost::is_same<Target, bool>::value),
lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
>::type caster_type;
return caster_type::try_convert(arg, result);
}
};
}} // namespace boost::detail
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_NUMERIC_HPP

View File

@@ -0,0 +1,194 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
#define BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <boost/limits.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/core/cmath.hpp>
#include <cstddef>
#include <cstring>
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
namespace boost {
namespace detail
{
template <class CharT>
bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) BOOST_NOEXCEPT {
for( unsigned int i=0; i < len; ++i ) {
if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false;
}
return true;
}
/* Returns true and sets the correct value if found NaN or Inf. */
template <class CharT, class T>
inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
, const CharT* lc_NAN, const CharT* lc_nan
, const CharT* lc_INFINITY, const CharT* lc_infinity
, const CharT opening_brace, const CharT closing_brace) BOOST_NOEXCEPT
{
if (begin == end) return false;
const CharT minus = lcast_char_constants<CharT>::minus;
const CharT plus = lcast_char_constants<CharT>::plus;
const int inifinity_size = 8; // == sizeof("infinity") - 1
/* Parsing +/- */
bool const has_minus = (*begin == minus);
if (has_minus || *begin == plus) {
++ begin;
}
if (end - begin < 3) return false;
if (lc_iequal(begin, lc_nan, lc_NAN, 3)) {
begin += 3;
if (end != begin) {
/* It is 'nan(...)' or some bad input*/
if (end - begin < 2) return false; // bad input
-- end;
if (*begin != opening_brace || *end != closing_brace) return false; // bad input
}
if( !has_minus ) value = std::numeric_limits<T>::quiet_NaN();
else value = boost::core::copysign(std::numeric_limits<T>::quiet_NaN(), static_cast<T>(-1));
return true;
} else if (
( /* 'INF' or 'inf' */
end - begin == 3 // 3 == sizeof('inf') - 1
&& lc_iequal(begin, lc_infinity, lc_INFINITY, 3)
)
||
( /* 'INFINITY' or 'infinity' */
end - begin == inifinity_size
&& lc_iequal(begin, lc_infinity, lc_INFINITY, inifinity_size)
)
)
{
if( !has_minus ) value = std::numeric_limits<T>::infinity();
else value = -std::numeric_limits<T>::infinity();
return true;
}
return false;
}
template <class CharT, class T>
bool put_inf_nan_impl(CharT* begin, CharT*& end, const T& value
, const CharT* lc_nan
, const CharT* lc_infinity) BOOST_NOEXCEPT
{
const CharT minus = lcast_char_constants<CharT>::minus;
if (boost::core::isnan(value)) {
if (boost::core::signbit(value)) {
*begin = minus;
++ begin;
}
std::memcpy(begin, lc_nan, 3 * sizeof(CharT));
end = begin + 3;
return true;
} else if (boost::core::isinf(value)) {
if (boost::core::signbit(value)) {
*begin = minus;
++ begin;
}
std::memcpy(begin, lc_infinity, 3 * sizeof(CharT));
end = begin + 3;
return true;
}
return false;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
template <class T>
bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) BOOST_NOEXCEPT {
return parse_inf_nan_impl(begin, end, value
, L"NAN", L"nan"
, L"INFINITY", L"infinity"
, L'(', L')');
}
template <class T>
bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) BOOST_NOEXCEPT {
return put_inf_nan_impl(begin, end, value, L"nan", L"infinity");
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
template <class T>
bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) BOOST_NOEXCEPT {
return parse_inf_nan_impl(begin, end, value
, u"NAN", u"nan"
, u"INFINITY", u"infinity"
, u'(', u')');
}
template <class T>
bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) BOOST_NOEXCEPT {
return put_inf_nan_impl(begin, end, value, u"nan", u"infinity");
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
template <class T>
bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) BOOST_NOEXCEPT {
return parse_inf_nan_impl(begin, end, value
, U"NAN", U"nan"
, U"INFINITY", U"infinity"
, U'(', U')');
}
template <class T>
bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) BOOST_NOEXCEPT {
return put_inf_nan_impl(begin, end, value, U"nan", U"infinity");
}
#endif
template <class CharT, class T>
bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) BOOST_NOEXCEPT {
return parse_inf_nan_impl(begin, end, value
, "NAN", "nan"
, "INFINITY", "infinity"
, '(', ')');
}
template <class CharT, class T>
bool put_inf_nan(CharT* begin, CharT*& end, const T& value) BOOST_NOEXCEPT {
return put_inf_nan_impl(begin, end, value, "nan", "infinity");
}
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP

View File

@@ -0,0 +1,59 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP
#define BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost {
namespace detail // is_character<...>
{
// returns true, if T is one of the character types
template < typename T >
struct is_character
{
typedef BOOST_DEDUCED_TYPENAME boost::integral_constant<
bool,
boost::is_same< T, char >::value ||
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
boost::is_same< T, wchar_t >::value ||
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
boost::is_same< T, char16_t >::value ||
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
boost::is_same< T, char32_t >::value ||
#endif
boost::is_same< T, unsigned char >::value ||
boost::is_same< T, signed char >::value
> type;
BOOST_STATIC_CONSTANT(bool, value = (type::value) );
};
}
}
#endif // BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP

View File

@@ -0,0 +1,46 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_LCAST_CHAR_CONSTANTS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_LCAST_CHAR_CONSTANTS_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost
{
namespace detail // '0', '-', '+', 'e', 'E' and '.' constants
{
template < typename Char >
struct lcast_char_constants {
// We check in tests assumption that static casted character is
// equal to correctly written C++ literal: U'0' == static_cast<char32_t>('0')
BOOST_STATIC_CONSTANT(Char, zero = static_cast<Char>('0'));
BOOST_STATIC_CONSTANT(Char, minus = static_cast<Char>('-'));
BOOST_STATIC_CONSTANT(Char, plus = static_cast<Char>('+'));
BOOST_STATIC_CONSTANT(Char, lowercase_e = static_cast<Char>('e'));
BOOST_STATIC_CONSTANT(Char, capital_e = static_cast<Char>('E'));
BOOST_STATIC_CONSTANT(Char, c_decimal_separator = static_cast<Char>('.'));
};
}
} // namespace boost
#endif // BOOST_LEXICAL_CAST_DETAIL_LCAST_CHAR_CONSTANTS_HPP

View File

@@ -0,0 +1,294 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_LCAST_UNSIGNED_CONVERTERS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_LCAST_UNSIGNED_CONVERTERS_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <climits>
#include <cstddef>
#include <string>
#include <cstring>
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_STD_LOCALE
# include <locale>
#else
# ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
// Getting error at this point means, that your STL library is old/lame/misconfigured.
// If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
// but beware: lexical_cast will understand only 'C' locale delimeters and thousands
// separators.
# error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
# error "boost::lexical_cast to use only 'C' locale during conversions."
# endif
#endif
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/noncopyable.hpp>
namespace boost
{
namespace detail // lcast_to_unsigned
{
template<class T>
inline
BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type lcast_to_unsigned(const T value) BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
return value < 0
? static_cast<result_type>(0u - static_cast<result_type>(value))
: static_cast<result_type>(value);
}
}
namespace detail // lcast_put_unsigned
{
template <class Traits, class T, class CharT>
class lcast_put_unsigned: boost::noncopyable {
typedef BOOST_DEDUCED_TYPENAME Traits::int_type int_type;
BOOST_DEDUCED_TYPENAME boost::conditional<
(sizeof(unsigned) > sizeof(T))
, unsigned
, T
>::type m_value;
CharT* m_finish;
CharT const m_czero;
int_type const m_zero;
public:
lcast_put_unsigned(const T n_param, CharT* finish) BOOST_NOEXCEPT
: m_value(n_param), m_finish(finish)
, m_czero(lcast_char_constants<CharT>::zero), m_zero(Traits::to_int_type(m_czero))
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
#endif
}
CharT* convert() {
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
std::locale loc;
if (loc == std::locale::classic()) {
return main_convert_loop();
}
typedef std::numpunct<CharT> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, loc);
std::string const grouping = np.grouping();
std::string::size_type const grouping_size = grouping.size();
if (!grouping_size || grouping[0] <= 0) {
return main_convert_loop();
}
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
// Check that ulimited group is unreachable:
BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
#endif
CharT const thousands_sep = np.thousands_sep();
std::string::size_type group = 0; // current group number
char last_grp_size = grouping[0];
char left = last_grp_size;
do {
if (left == 0) {
++group;
if (group < grouping_size) {
char const grp_size = grouping[group];
last_grp_size = (grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size);
}
left = last_grp_size;
--m_finish;
Traits::assign(*m_finish, thousands_sep);
}
--left;
} while (main_convert_iteration());
return m_finish;
#else
return main_convert_loop();
#endif
}
private:
inline bool main_convert_iteration() BOOST_NOEXCEPT {
--m_finish;
int_type const digit = static_cast<int_type>(m_value % 10U);
Traits::assign(*m_finish, Traits::to_char_type(m_zero + digit));
m_value /= 10;
return !!m_value; // suppressing warnings
}
inline CharT* main_convert_loop() BOOST_NOEXCEPT {
while (main_convert_iteration());
return m_finish;
}
};
}
namespace detail // lcast_ret_unsigned
{
template <class Traits, class T, class CharT>
class lcast_ret_unsigned: boost::noncopyable {
bool m_multiplier_overflowed;
T m_multiplier;
T& m_value;
const CharT* const m_begin;
const CharT* m_end;
public:
lcast_ret_unsigned(T& value, const CharT* const begin, const CharT* end) BOOST_NOEXCEPT
: m_multiplier_overflowed(false), m_multiplier(1), m_value(value), m_begin(begin), m_end(end)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
// GCC when used with flag -std=c++0x may not have std::numeric_limits
// specializations for __int128 and unsigned __int128 types.
// Try compilation with -std=gnu++0x or -std=gnu++11.
//
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40856
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<T>::is_specialized,
"std::numeric_limits are not specialized for integral type passed to boost::lexical_cast"
);
#endif
}
inline bool convert() {
CharT const czero = lcast_char_constants<CharT>::zero;
--m_end;
m_value = static_cast<T>(0);
if (m_begin > m_end || *m_end < czero || *m_end >= czero + 10)
return false;
m_value = static_cast<T>(*m_end - czero);
--m_end;
#ifdef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
return main_convert_loop();
#else
std::locale loc;
if (loc == std::locale::classic()) {
return main_convert_loop();
}
typedef std::numpunct<CharT> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, loc);
std::string const& grouping = np.grouping();
std::string::size_type const grouping_size = grouping.size();
/* According to Programming languages - C++
* we MUST check for correct grouping
*/
if (!grouping_size || grouping[0] <= 0) {
return main_convert_loop();
}
unsigned char current_grouping = 0;
CharT const thousands_sep = np.thousands_sep();
char remained = static_cast<char>(grouping[current_grouping] - 1);
for (;m_end >= m_begin; --m_end)
{
if (remained) {
if (!main_convert_iteration()) {
return false;
}
--remained;
} else {
if ( !Traits::eq(*m_end, thousands_sep) ) //|| begin == end ) return false;
{
/*
* According to Programming languages - C++
* Digit grouping is checked. That is, the positions of discarded
* separators is examined for consistency with
* use_facet<numpunct<charT> >(loc ).grouping()
*
* BUT what if there is no separators at all and grouping()
* is not empty? Well, we have no extraced separators, so we
* won`t check them for consistency. This will allow us to
* work with "C" locale from other locales
*/
return main_convert_loop();
} else {
if (m_begin == m_end) return false;
if (current_grouping < grouping_size - 1) ++current_grouping;
remained = grouping[current_grouping];
}
}
} /*for*/
return true;
#endif
}
private:
// Iteration that does not care about grouping/separators and assumes that all
// input characters are digits
inline bool main_convert_iteration() BOOST_NOEXCEPT {
CharT const czero = lcast_char_constants<CharT>::zero;
T const maxv = (std::numeric_limits<T>::max)();
m_multiplier_overflowed = m_multiplier_overflowed || (maxv/10 < m_multiplier);
m_multiplier = static_cast<T>(m_multiplier * 10);
T const dig_value = static_cast<T>(*m_end - czero);
T const new_sub_value = static_cast<T>(m_multiplier * dig_value);
// We must correctly handle situations like `000000000000000000000000000001`.
// So we take care of overflow only if `dig_value` is not '0'.
if (*m_end < czero || *m_end >= czero + 10 // checking for correct digit
|| (dig_value && ( // checking for overflow of ...
m_multiplier_overflowed // ... multiplier
|| static_cast<T>(maxv / dig_value) < m_multiplier // ... subvalue
|| static_cast<T>(maxv - new_sub_value) < m_value // ... whole expression
))
) return false;
m_value = static_cast<T>(m_value + new_sub_value);
return true;
}
bool main_convert_loop() BOOST_NOEXCEPT {
for ( ; m_end >= m_begin; --m_end) {
if (!main_convert_iteration()) {
return false;
}
}
return true;
}
};
}
} // namespace boost
#endif // BOOST_LEXICAL_CAST_DETAIL_LCAST_UNSIGNED_CONVERTERS_HPP

View File

@@ -0,0 +1,43 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_WIDEST_CHAR_HPP
#define BOOST_LEXICAL_CAST_DETAIL_WIDEST_CHAR_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <boost/type_traits/conditional.hpp>
namespace boost { namespace detail {
template <typename TargetChar, typename SourceChar>
struct widest_char {
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
(sizeof(TargetChar) > sizeof(SourceChar))
, TargetChar
, SourceChar
>::type type;
};
}} // namespace boost::detail
#endif // BOOST_LEXICAL_CAST_DETAIL_WIDEST_CHAR_HPP

View File

@@ -0,0 +1,175 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_LEXICAL_CAST_OLD_HPP
#define BOOST_LEXICAL_CAST_LEXICAL_CAST_OLD_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <climits>
#include <cstddef>
#include <string>
#include <cstring>
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lcast_precision.hpp>
#include <boost/detail/workaround.hpp>
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif
#include <boost/lexical_cast/bad_lexical_cast.hpp>
#include <boost/lexical_cast/detail/widest_char.hpp>
namespace boost {
namespace detail
{
// selectors for choosing stream character type
template<typename Type>
struct stream_char
{
typedef char type;
};
#ifndef BOOST_LCAST_NO_WCHAR_T
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<>
struct stream_char<wchar_t>
{
typedef wchar_t type;
};
#endif
template<>
struct stream_char<wchar_t *>
{
typedef wchar_t type;
};
template<>
struct stream_char<const wchar_t *>
{
typedef wchar_t type;
};
template<>
struct stream_char<std::wstring>
{
typedef wchar_t type;
};
#endif
// stream wrapper for handling lexical conversions
template<typename Target, typename Source, typename Traits>
class lexical_stream
{
private:
typedef typename widest_char<
typename stream_char<Target>::type,
typename stream_char<Source>::type>::type char_type;
typedef Traits traits_type;
public:
lexical_stream(char_type* = 0, char_type* = 0)
{
stream.unsetf(std::ios::skipws);
lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
}
~lexical_stream()
{
#if defined(BOOST_NO_STRINGSTREAM)
stream.freeze(false);
#endif
}
bool operator<<(const Source &input)
{
return !(stream << input).fail();
}
template<typename InputStreamable>
bool operator>>(InputStreamable &output)
{
return !is_pointer<InputStreamable>::value &&
stream >> output &&
stream.get() == traits_type::eof();
}
bool operator>>(std::string &output)
{
#if defined(BOOST_NO_STRINGSTREAM)
stream << '\0';
#endif
stream.str().swap(output);
return true;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
bool operator>>(std::wstring &output)
{
stream.str().swap(output);
return true;
}
#endif
private:
#if defined(BOOST_NO_STRINGSTREAM)
std::strstream stream;
#elif defined(BOOST_NO_STD_LOCALE)
std::stringstream stream;
#else
std::basic_stringstream<char_type,traits_type> stream;
#endif
};
}
// call-by-value fallback version (deprecated)
template<typename Target, typename Source>
Target lexical_cast(Source arg)
{
typedef typename detail::widest_char<
BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type
, BOOST_DEDUCED_TYPENAME detail::stream_char<Source>::type
>::type char_type;
typedef std::char_traits<char_type> traits;
detail::lexical_stream<Target, Source, traits> interpreter;
Target result;
if(!(interpreter << arg && interpreter >> result))
boost::conversion::detail::throw_bad_cast<Source, Target>();
return result;
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // BOOST_LEXICAL_CAST_LEXICAL_CAST_OLD_HPP

View File

@@ -0,0 +1,232 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2022.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP
#define BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(__clang__) || (defined(__GNUC__) && \
!(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#include <string>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/lexical_cast/detail/is_character.hpp>
#include <boost/lexical_cast/detail/converter_numeric.hpp>
#include <boost/lexical_cast/detail/converter_lexical.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/container/container_fwd.hpp>
namespace boost {
namespace detail
{
template<typename T>
struct is_stdstring
: boost::false_type
{};
template<typename CharT, typename Traits, typename Alloc>
struct is_stdstring< std::basic_string<CharT, Traits, Alloc> >
: boost::true_type
{};
// Sun Studio has problem with partial specialization of templates differing only in namespace.
// We workaround that by making `is_booststring` trait, instead of specializing `is_stdstring` for `boost::container::basic_string`.
template<typename T>
struct is_booststring
: boost::false_type
{};
template<typename CharT, typename Traits, typename Alloc>
struct is_booststring< boost::container::basic_string<CharT, Traits, Alloc> >
: boost::true_type
{};
template<typename Target, typename Source>
struct is_arithmetic_and_not_xchars
{
typedef boost::integral_constant<
bool,
!(boost::detail::is_character<Target>::value) &&
!(boost::detail::is_character<Source>::value) &&
boost::is_arithmetic<Source>::value &&
boost::is_arithmetic<Target>::value
> type;
BOOST_STATIC_CONSTANT(bool, value = (
type::value
));
};
/*
* is_xchar_to_xchar<Target, Source>::value is true,
* Target and Souce are char types of the same size 1 (char, signed char, unsigned char).
*/
template<typename Target, typename Source>
struct is_xchar_to_xchar
{
typedef boost::integral_constant<
bool,
sizeof(Source) == sizeof(Target) &&
sizeof(Source) == sizeof(char) &&
boost::detail::is_character<Target>::value &&
boost::detail::is_character<Source>::value
> type;
BOOST_STATIC_CONSTANT(bool, value = (
type::value
));
};
template<typename Target, typename Source>
struct is_char_array_to_stdstring
: boost::false_type
{};
template<typename CharT, typename Traits, typename Alloc>
struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, CharT* >
: boost::true_type
{};
template<typename CharT, typename Traits, typename Alloc>
struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, const CharT* >
: boost::true_type
{};
// Sun Studio has problem with partial specialization of templates differing only in namespace.
// We workaround that by making `is_char_array_to_booststring` trait, instead of specializing `is_char_array_to_stdstring` for `boost::container::basic_string`.
template<typename Target, typename Source>
struct is_char_array_to_booststring
: boost::false_type
{};
template<typename CharT, typename Traits, typename Alloc>
struct is_char_array_to_booststring< boost::container::basic_string<CharT, Traits, Alloc>, CharT* >
: boost::true_type
{};
template<typename CharT, typename Traits, typename Alloc>
struct is_char_array_to_booststring< boost::container::basic_string<CharT, Traits, Alloc>, const CharT* >
: boost::true_type
{};
template <typename Target, typename Source>
struct copy_converter_impl
{
// MSVC fail to forward an array (DevDiv#555157 "SILENT BAD CODEGEN triggered by perfect forwarding",
// fixed in 2013 RTM).
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined(BOOST_MSVC) || BOOST_MSVC >= 1800)
template <class T>
static inline bool try_convert(T&& arg, Target& result) {
result = static_cast<T&&>(arg); // eqaul to `result = std::forward<T>(arg);`
return true;
}
#else
static inline bool try_convert(const Source& arg, Target& result) {
result = arg;
return true;
}
#endif
};
}
namespace conversion { namespace detail {
template <typename Target, typename Source>
inline bool try_lexical_convert(const Source& arg, Target& result)
{
typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
typedef boost::integral_constant<
bool,
boost::detail::is_xchar_to_xchar<Target, src >::value ||
boost::detail::is_char_array_to_stdstring<Target, src >::value ||
boost::detail::is_char_array_to_booststring<Target, src >::value ||
(
boost::is_same<Target, src >::value &&
(boost::detail::is_stdstring<Target >::value || boost::detail::is_booststring<Target >::value)
) ||
(
boost::is_same<Target, src >::value &&
boost::detail::is_character<Target >::value
)
> shall_we_copy_t;
typedef boost::detail::is_arithmetic_and_not_xchars<Target, src >
shall_we_copy_with_dynamic_check_t;
// We do evaluate second `if_` lazily to avoid unnecessary instantiations
// of `shall_we_copy_with_dynamic_check_t` and improve compilation times.
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
shall_we_copy_t::value,
boost::type_identity<boost::detail::copy_converter_impl<Target, src > >,
boost::conditional<
shall_we_copy_with_dynamic_check_t::value,
boost::detail::dynamic_num_converter_impl<Target, src >,
boost::detail::lexical_converter_impl<Target, src >
>
>::type caster_type_lazy;
typedef BOOST_DEDUCED_TYPENAME caster_type_lazy::type caster_type;
return caster_type::try_convert(arg, result);
}
template <typename Target, typename CharacterT>
inline bool try_lexical_convert(const CharacterT* chars, std::size_t count, Target& result)
{
BOOST_STATIC_ASSERT_MSG(
boost::detail::is_character<CharacterT>::value,
"This overload of try_lexical_convert is meant to be used only with arrays of characters."
);
return ::boost::conversion::detail::try_lexical_convert(
::boost::iterator_range<const CharacterT*>(chars, chars + count), result
);
}
}} // namespace conversion::detail
namespace conversion {
// ADL barrier
using ::boost::conversion::detail::try_lexical_convert;
}
} // namespace boost
#if defined(__clang__) || (defined(__GNUC__) && \
!(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic pop
#endif
#endif // BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,4 @@
The package boost is compatible with built-in CMake targets:
find_package(Boost REQUIRED [COMPONENTS <libs>...])
target_link_libraries(main PRIVATE Boost::boost Boost::<lib1> Boost::<lib2> ...)

View File

@@ -0,0 +1,115 @@
{
"$schema": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json",
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"documentNamespace": "https://spdx.org/spdxdocs/boost-lexical-cast-x64-windows-1.79.0-65cec38c-bedd-4c1e-b542-c126d3248844",
"name": "boost-lexical-cast:x64-windows@1.79.0 25419bb02ca50db7244c1bbdfc53d5ea42afab7c3d07470da51f773f6c556a68",
"creationInfo": {
"creators": [
"Tool: vcpkg-9268e366206712e38102b28dbd1617697a99ff2e"
],
"created": "2022-07-23T08:23:27Z"
},
"relationships": [
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "GENERATES",
"relatedSpdxElement": "SPDXRef-binary"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-0"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-1"
},
{
"spdxElementId": "SPDXRef-binary",
"relationshipType": "GENERATED_FROM",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-0",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "DEPENDENCY_MANIFEST_OF",
"relatedSpdxElement": "SPDXRef-port"
}
],
"packages": [
{
"name": "boost-lexical-cast",
"SPDXID": "SPDXRef-port",
"versionInfo": "1.79.0",
"downloadLocation": "NOASSERTION",
"homepage": "https://github.com/boostorg/lexical_cast",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"description": "Boost lexical_cast module",
"comment": "This is the port (recipe) consumed by vcpkg."
},
{
"name": "boost-lexical-cast:x64-windows",
"SPDXID": "SPDXRef-binary",
"versionInfo": "25419bb02ca50db7244c1bbdfc53d5ea42afab7c3d07470da51f773f6c556a68",
"downloadLocation": "NONE",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is a binary package built by vcpkg."
},
{
"SPDXID": "SPDXRef-resource-1",
"name": "boostorg/lexical_cast",
"downloadLocation": "git+https://github.com/boostorg/lexical_cast@boost-1.79.0",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA512",
"checksumValue": "9d0b28cd20c88638d048ff48d2f0209627f15558c1ff2619ed28cc07207c71352799289004d4108c20187b1099720064a2d1ca517b8b19e523e6702acb8fe018"
}
]
}
],
"files": [
{
"fileName": "./portfile.cmake",
"SPDXID": "SPDXRef-file-0",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "154e0311379c8367080af0f8dd6b700b0c45de730d791c70b66666143b0afbd8"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./vcpkg.json",
"SPDXID": "SPDXRef-file-1",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "71aefbecb06f4f64610e200e15ce65f1099e52835337567104ffadb4ba4ff5e8"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
}
]
}

View File

@@ -0,0 +1,23 @@
boost-array 4e990836b5cd32944d15ce6514ed5c667da5b743fc9639f71cada01a77d259d8
boost-assert a50eed453b8be6c8932fb3d5f8feaf194a2ebeaed7982db4e36e3ba17f3ec107
boost-config 797535e8975ed7cf5bbe11d9f7fe26caa5da8fe819888564758d82a21109fade
boost-container 28f3292fd533fd5837f4834f534f435bceb9366c9c62e08934c1233a24bc6221
boost-core 498aea0b6b68bcfe1ec683e76c2f0d32477dfe9ba958f518980ff806b6faba90
boost-integer 7a387f2417014a6cf56a8a8cd689c8153efaaf93ea6beba8f390f5b9577da9cb
boost-numeric-conversion c7d1f700231348a54921287cb7cec7268ff76dcc995cb3242e25677261b23a02
boost-range c7bf2eb03ce19786dd1929c6c714b2709ede6b84cf87c3e713106ca002d9c992
boost-static-assert 795e87a155fce50821163bc84e802f28dce54e4af6a3a86045f9ecec76ad4c95
boost-throw-exception 4bb4a0182f0f071c3c1ffd9cbd82fbc3bc7db4a35346f930bbe504e7e3a94e0a
boost-type-traits 74f62124585467fbb6c4fa16015164d11e1a079d6bdb70ec1c3fe7cf65b9a594
boost-vcpkg-helpers c81c7b003df356a1a120a7c0c2f5a2ac95f3c33b006a2a5b4c02dcf0c9f3deaa
cmake 3.23.2
features core
portfile.cmake 154e0311379c8367080af0f8dd6b700b0c45de730d791c70b66666143b0afbd8
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg.json 71aefbecb06f4f64610e200e15ce65f1099e52835337567104ffadb4ba4ff5e8
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f