mirror of
https://github.com/boostorg/lexical_cast.git
synced 2025-05-09 23:03:55 +00:00
Reduce template instantiations count by using template aliases (#67)
This commit is contained in:
parent
90ec909dcf
commit
fe9ee41f5c
@ -15,12 +15,6 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/integer_traits.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
|
|
||||||
|
|
||||||
namespace boost { namespace detail {
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
class lcast_abstract_stub {};
|
class lcast_abstract_stub {};
|
||||||
@ -31,15 +25,7 @@ class lcast_abstract_stub {};
|
|||||||
template<class T>
|
template<class T>
|
||||||
struct lcast_precision
|
struct lcast_precision
|
||||||
{
|
{
|
||||||
#ifdef BOOST_NO_IS_ABSTRACT
|
using limits = std::numeric_limits<T>;
|
||||||
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
|
|
||||||
#else
|
|
||||||
typedef 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 =
|
BOOST_STATIC_CONSTANT(bool, use_default_precision =
|
||||||
!limits::is_specialized || limits::is_exact
|
!limits::is_specialized || limits::is_exact
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
#include <boost/type_traits/conditional.hpp>
|
#include <boost/type_traits/conditional.hpp>
|
||||||
#include <boost/type_traits/is_integral.hpp>
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
#include <boost/type_traits/is_float.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/detail/lcast_precision.hpp>
|
#include <boost/detail/lcast_precision.hpp>
|
||||||
|
|
||||||
#include <boost/lexical_cast/detail/widest_char.hpp>
|
#include <boost/lexical_cast/detail/widest_char.hpp>
|
||||||
@ -204,20 +202,29 @@ namespace boost {
|
|||||||
template < class T >
|
template < class T >
|
||||||
struct deduce_source_char_impl< deduce_character_type_later< T > >
|
struct deduce_source_char_impl< deduce_character_type_later< T > >
|
||||||
{
|
{
|
||||||
typedef boost::has_left_shift< std::basic_ostream< char >, T > result_t;
|
template <class U>
|
||||||
|
static auto left_shift_type(long)
|
||||||
|
-> decltype( std::declval<std::basic_ostream< char >&>() << std::declval<const U&>(), char{});
|
||||||
|
|
||||||
#if defined(BOOST_LCAST_NO_WCHAR_T)
|
#if !defined(BOOST_LCAST_NO_WCHAR_T)
|
||||||
static_assert(result_t::value,
|
template <class U>
|
||||||
"Source type is not std::ostream`able and std::wostream`s are not supported by your STL implementation");
|
static auto left_shift_type(int)
|
||||||
typedef char type;
|
-> decltype( std::declval<std::basic_ostream< wchar_t >&>() << std::declval<const U&>(), wchar_t{});
|
||||||
#else
|
|
||||||
typedef typename boost::conditional<
|
|
||||||
result_t::value, char, wchar_t
|
|
||||||
>::type type;
|
|
||||||
|
|
||||||
static_assert(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
|
#endif
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
static void left_shift_type(...);
|
||||||
|
|
||||||
|
using type = decltype(left_shift_type<T>(1L));
|
||||||
|
|
||||||
|
static_assert(!std::is_same<type, void>::value,
|
||||||
|
#if defined(BOOST_LCAST_NO_WCHAR_T)
|
||||||
|
"Source type is not std::ostream`able and std::wostream`s are "
|
||||||
|
"not supported by your STL implementation"
|
||||||
|
#else
|
||||||
|
"Source type is neither std::ostream`able nor std::wostream`able"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,20 +244,29 @@ namespace boost {
|
|||||||
template < class T >
|
template < class T >
|
||||||
struct deduce_target_char_impl< deduce_character_type_later<T> >
|
struct deduce_target_char_impl< deduce_character_type_later<T> >
|
||||||
{
|
{
|
||||||
typedef boost::has_right_shift<std::basic_istream<char>, T > result_t;
|
template <class U>
|
||||||
|
static auto right_shift_type(long)
|
||||||
|
-> decltype( std::declval<std::basic_istream< char >&>() >> std::declval<U&>(), char{});
|
||||||
|
|
||||||
#if defined(BOOST_LCAST_NO_WCHAR_T)
|
#if !defined(BOOST_LCAST_NO_WCHAR_T)
|
||||||
static_assert(result_t::value,
|
template <class U>
|
||||||
"Target type is not std::istream`able and std::wistream`s are not supported by your STL implementation");
|
static auto right_shift_type(int)
|
||||||
typedef char type;
|
-> decltype( std::declval<std::basic_istream< wchar_t >&>() >> std::declval<U&>(), wchar_t{});
|
||||||
#else
|
|
||||||
typedef typename boost::conditional<
|
|
||||||
result_t::value, char, wchar_t
|
|
||||||
>::type type;
|
|
||||||
|
|
||||||
static_assert(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
|
#endif
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
static void right_shift_type(...);
|
||||||
|
|
||||||
|
using type = decltype(right_shift_type<T>(1L));
|
||||||
|
|
||||||
|
static_assert(!std::is_same<type, void>::value,
|
||||||
|
#if defined(BOOST_LCAST_NO_WCHAR_T)
|
||||||
|
"Target type is not std::istream`able and std::wistream`s are "
|
||||||
|
"not supported by your STL implementation"
|
||||||
|
#else
|
||||||
|
"Target type is neither std::istream`able nor std::wistream`able"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,16 +376,11 @@ namespace boost {
|
|||||||
Source, typename boost::enable_if<boost::is_integral<Source> >::type
|
Source, typename boost::enable_if<boost::is_integral<Source> >::type
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
|
||||||
BOOST_STATIC_CONSTANT(std::size_t, value =
|
BOOST_STATIC_CONSTANT(std::size_t, value =
|
||||||
std::numeric_limits<Source>::is_signed +
|
std::numeric_limits<Source>::is_signed +
|
||||||
std::numeric_limits<Source>::is_specialized + /* == 1 */
|
std::numeric_limits<Source>::is_specialized + /* == 1 */
|
||||||
std::numeric_limits<Source>::digits10 * 2
|
std::numeric_limits<Source>::digits10 * 2
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
BOOST_STATIC_CONSTANT(std::size_t, value = 156);
|
|
||||||
static_assert(sizeof(Source) * CHAR_BIT <= 256, "");
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper for floating point types.
|
// Helper for floating point types.
|
||||||
@ -387,8 +398,6 @@ namespace boost {
|
|||||||
Source, typename boost::enable_if<boost::is_float<Source> >::type
|
Source, typename boost::enable_if<boost::is_float<Source> >::type
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
|
|
||||||
static_assert(
|
static_assert(
|
||||||
std::numeric_limits<Source>::max_exponent10 <= 999999L &&
|
std::numeric_limits<Source>::max_exponent10 <= 999999L &&
|
||||||
std::numeric_limits<Source>::min_exponent10 >= -999999L
|
std::numeric_limits<Source>::min_exponent10 >= -999999L
|
||||||
@ -397,9 +406,6 @@ namespace boost {
|
|||||||
BOOST_STATIC_CONSTANT(std::size_t, value =
|
BOOST_STATIC_CONSTANT(std::size_t, value =
|
||||||
5 + lcast_precision<Source>::value + 6
|
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
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,34 +26,27 @@
|
|||||||
#include <boost/type_traits/integral_constant.hpp>
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
namespace detail // is_character<...>
|
// returns true, if T is one of the character types
|
||||||
{
|
template < typename T >
|
||||||
// returns true, if T is one of the character types
|
using is_character = boost::integral_constant<
|
||||||
template < typename T >
|
bool,
|
||||||
struct is_character
|
boost::is_same< T, char >::value ||
|
||||||
{
|
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
|
||||||
typedef typename boost::integral_constant<
|
boost::is_same< T, wchar_t >::value ||
|
||||||
bool,
|
#endif
|
||||||
boost::is_same< T, char >::value ||
|
#ifndef BOOST_NO_CXX11_CHAR16_T
|
||||||
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
|
boost::is_same< T, char16_t >::value ||
|
||||||
boost::is_same< T, wchar_t >::value ||
|
#endif
|
||||||
#endif
|
#ifndef BOOST_NO_CXX11_CHAR32_T
|
||||||
#ifndef BOOST_NO_CXX11_CHAR16_T
|
boost::is_same< T, char32_t >::value ||
|
||||||
boost::is_same< T, char16_t >::value ||
|
#endif
|
||||||
#endif
|
boost::is_same< T, unsigned char >::value ||
|
||||||
#ifndef BOOST_NO_CXX11_CHAR32_T
|
boost::is_same< T, signed char >::value
|
||||||
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
|
#endif // BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP
|
||||||
|
|
||||||
|
@ -28,14 +28,12 @@
|
|||||||
|
|
||||||
namespace boost { namespace detail {
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
template <typename TargetChar, typename SourceChar>
|
template <typename TargetChar, typename SourceChar>
|
||||||
struct widest_char {
|
using widest_char = boost::conditional<
|
||||||
typedef typename boost::conditional<
|
(sizeof(TargetChar) > sizeof(SourceChar))
|
||||||
(sizeof(TargetChar) > sizeof(SourceChar))
|
, TargetChar
|
||||||
, TargetChar
|
, SourceChar
|
||||||
, SourceChar
|
>;
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::detail
|
}} // namespace boost::detail
|
||||||
|
|
||||||
|
@ -72,40 +72,26 @@ namespace boost {
|
|||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename Target, typename Source>
|
template<typename Target, typename Source>
|
||||||
struct is_arithmetic_and_not_xchars
|
using is_arithmetic_and_not_xchars = boost::integral_constant<
|
||||||
{
|
bool,
|
||||||
typedef boost::integral_constant<
|
!(boost::detail::is_character<Target>::value) &&
|
||||||
bool,
|
!(boost::detail::is_character<Source>::value) &&
|
||||||
!(boost::detail::is_character<Target>::value) &&
|
boost::is_arithmetic<Source>::value &&
|
||||||
!(boost::detail::is_character<Source>::value) &&
|
boost::is_arithmetic<Target>::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,
|
* 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).
|
* Target and Souce are char types of the same size 1 (char, signed char, unsigned char).
|
||||||
*/
|
*/
|
||||||
template<typename Target, typename Source>
|
template<typename Target, typename Source>
|
||||||
struct is_xchar_to_xchar
|
using is_xchar_to_xchar = boost::integral_constant<
|
||||||
{
|
bool,
|
||||||
typedef boost::integral_constant<
|
sizeof(Source) == sizeof(Target) &&
|
||||||
bool,
|
sizeof(Source) == sizeof(char) &&
|
||||||
sizeof(Source) == sizeof(Target) &&
|
boost::detail::is_character<Target>::value &&
|
||||||
sizeof(Source) == sizeof(char) &&
|
boost::detail::is_character<Source>::value
|
||||||
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>
|
template<typename Target, typename Source>
|
||||||
struct is_char_array_to_stdstring
|
struct is_char_array_to_stdstring
|
||||||
@ -144,7 +130,7 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
// MSVC fail to forward an array (DevDiv#555157 "SILENT BAD CODEGEN triggered by perfect forwarding",
|
// MSVC fail to forward an array (DevDiv#555157 "SILENT BAD CODEGEN triggered by perfect forwarding",
|
||||||
// fixed in 2013 RTM).
|
// fixed in 2013 RTM).
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined(BOOST_MSVC) || BOOST_MSVC >= 1800)
|
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1800
|
||||||
template <class T>
|
template <class T>
|
||||||
static inline bool try_convert(T&& arg, Target& result) {
|
static inline bool try_convert(T&& arg, Target& result) {
|
||||||
result = static_cast<T&&>(arg); // eqaul to `result = std::forward<T>(arg);`
|
result = static_cast<T&&>(arg); // eqaul to `result = std::forward<T>(arg);`
|
||||||
|
@ -12,7 +12,7 @@ import ../../config/checks/config : requires ;
|
|||||||
|
|
||||||
project
|
project
|
||||||
: requirements
|
: requirements
|
||||||
[ requires cxx11_rvalue_references ]
|
[ requires cxx11_rvalue_references cxx11_static_assert cxx11_template_aliases ]
|
||||||
<link>static
|
<link>static
|
||||||
<toolset>gcc-4.7:<cxxflags>-ftrapv
|
<toolset>gcc-4.7:<cxxflags>-ftrapv
|
||||||
<toolset>gcc-4.6:<cxxflags>-ftrapv
|
<toolset>gcc-4.6:<cxxflags>-ftrapv
|
||||||
|
Loading…
x
Reference in New Issue
Block a user