summaryrefslogtreecommitdiff
path: root/boost/convert
diff options
context:
space:
mode:
Diffstat (limited to 'boost/convert')
-rw-r--r--boost/convert/base.hpp56
-rw-r--r--boost/convert/detail/char.hpp28
-rw-r--r--boost/convert/detail/config.hpp (renamed from boost/convert/detail/forward.hpp)45
-rw-r--r--boost/convert/detail/has_member.hpp3
-rw-r--r--boost/convert/detail/is_converter.hpp2
-rw-r--r--boost/convert/detail/is_fun.hpp2
-rw-r--r--boost/convert/detail/is_string.hpp4
-rw-r--r--boost/convert/detail/range.hpp29
-rw-r--r--boost/convert/spirit.hpp2
-rw-r--r--boost/convert/strtol.hpp32
10 files changed, 108 insertions, 95 deletions
diff --git a/boost/convert/base.hpp b/boost/convert/base.hpp
index 27931194cc..678d99cfc6 100644
--- a/boost/convert/base.hpp
+++ b/boost/convert/base.hpp
@@ -7,7 +7,6 @@
#include <boost/convert/parameters.hpp>
#include <boost/convert/detail/is_string.hpp>
-#include <cctype>
#include <cstring>
namespace boost { namespace cnv
@@ -106,19 +105,13 @@ struct boost::cnv::cnvbase
void
str_to_(string_type const& str, optional<out_type>& result_out) const
{
- using range_type = cnv::range<string_type const>;
- using char_type = typename range_type::value_type;
+ cnv::range<string_type const> range (str);
- range_type range (str);
- auto is_space = [](char_type ch)
- {
- return std::isspace(static_cast<unsigned char>(ch));
- };
if (skipws_)
- for (; !range.empty() && is_space(*range.begin()); ++range);
+ for (; !range.empty() && cnv::is_space(*range.begin()); ++range);
- if (range.empty()) return;
- if (is_space(*range.begin())) return;
+ if (range.empty()) return;
+ if (cnv::is_space(*range.begin())) return;
dncast().str_to(range, result_out);
}
@@ -126,35 +119,31 @@ struct boost::cnv::cnvbase
void
to_str_(in_type value_in, optional<string_type>& result_out) const
{
- using range_type = cnv::range<string_type>;
- using char_type = typename range_type::value_type;
+ using char_type = typename cnv::range<string_type>::value_type;
+ using range_type = cnv::range<char_type*>;
+ using buf_type = char_type[bufsize_];
- char_type buf[bufsize_];
- cnv::range<char_type*> range = dncast().to_str(value_in, buf);
- char_type* beg = range.begin();
- char_type* end = range.end();
+ buf_type buf;
+ range_type range = dncast().to_str(value_in, buf);
+ char_type* beg = range.begin();
+ char_type* end = range.end();
+ int str_size = end - beg;
- if (beg < end)
- format_(buf, beg, end), result_out = string_type(beg, end);
- }
+ if (str_size <= 0)
+ return;
- template<typename char_type>
- void
- format_(char_type* buf, char_type*& beg, char_type*& end) const
- {
if (uppercase_)
- for (char_type* p = beg; p < end; ++p) *p = std::toupper(*p);
+ for (char_type* p = beg; p < end; ++p) *p = cnv::to_upper(*p);
if (width_)
{
- int num_fillers = (std::max)(0, int(width_ - (end - beg)));
- int num_left = adjust_ == boost::cnv::adjust::left ? 0
- : adjust_ == boost::cnv::adjust::right ? num_fillers
- : (num_fillers / 2);
- int num_right = num_fillers - num_left;
- int str_size = end - beg;
- bool move = (beg < buf + num_left) // No room for left fillers
- || (buf + bufsize_ < end + num_right); // No room for right fillers
+ int num_fill = (std::max)(0, int(width_ - (end - beg)));
+ int num_left = adjust_ == cnv::adjust::left ? 0
+ : adjust_ == cnv::adjust::right ? num_fill
+ : (num_fill / 2);
+ int num_right = num_fill - num_left;
+ bool move = (beg < buf + num_left) // No room for left fillers
+ || (buf + bufsize_ < end + num_right); // No room for right fillers
if (move)
{
std::memmove(buf + num_left, beg, str_size * sizeof(char_type));
@@ -164,6 +153,7 @@ struct boost::cnv::cnvbase
for (int k = 0; k < num_left; *(--beg) = fill_, ++k);
for (int k = 0; k < num_right; *(end++) = fill_, ++k);
}
+ result_out = string_type(beg, end);
}
derived_type const& dncast () const { return *static_cast<derived_type const*>(this); }
diff --git a/boost/convert/detail/char.hpp b/boost/convert/detail/char.hpp
index 1d375bad51..a829dc8806 100644
--- a/boost/convert/detail/char.hpp
+++ b/boost/convert/detail/char.hpp
@@ -5,18 +5,34 @@
#ifndef BOOST_CONVERT_DETAIL_IS_CHAR_HPP
#define BOOST_CONVERT_DETAIL_IS_CHAR_HPP
-#include <boost/mpl/bool.hpp>
-#include <boost/type_traits/remove_const.hpp>
+#include <boost/convert/detail/config.hpp>
+#include <type_traits>
+#include <cctype>
+#include <cwctype>
namespace boost { namespace cnv
{
+ using char_type = char;
+ using uchar_type = unsigned char;
+ using wchar_type = wchar_t;
+
namespace detail
{
- template<typename T> struct is_char : mpl::false_ {};
- template<> struct is_char<char> : mpl:: true_ {};
- template<> struct is_char<wchar_t> : mpl:: true_ {};
+ template<typename> struct is_char : std::false_type {};
+ template<> struct is_char< char_type> : std:: true_type {};
+ template<> struct is_char<wchar_type> : std:: true_type {};
}
- template <typename T> struct is_char : detail::is_char<typename remove_const<T>::type> {};
+ template <typename T> struct is_char : detail::is_char<typename boost::remove_const<T>::type> {};
+
+ template<typename char_type> inline bool is_space(char_type);
+ template<typename char_type> inline char_type to_upper(char_type);
+
+ template<> inline bool is_space ( char_type c) { return bool(std::isspace(static_cast<uchar_type>(c))); }
+ template<> inline bool is_space (uchar_type c) { return bool(std::isspace(c)); }
+ template<> inline bool is_space (wchar_type c) { return bool(std::iswspace(c)); }
+ template<> inline char_type to_upper ( char_type c) { return std::toupper(static_cast<uchar_type>(c)); }
+ template<> inline uchar_type to_upper (uchar_type c) { return std::toupper(c); }
+ template<> inline wchar_type to_upper (wchar_type c) { return std::towupper(c); }
}}
#endif // BOOST_CONVERT_DETAIL_IS_CHAR_HPP
diff --git a/boost/convert/detail/forward.hpp b/boost/convert/detail/config.hpp
index 7ea7960490..6c74cd308a 100644
--- a/boost/convert/detail/forward.hpp
+++ b/boost/convert/detail/config.hpp
@@ -5,7 +5,33 @@
#ifndef BOOST_CONVERT_FORWARD_HPP
#define BOOST_CONVERT_FORWARD_HPP
+#include <boost/config.hpp>
+#include <boost/version.hpp>
+#include <boost/optional.hpp>
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#undef BOOST_CONVERT_CXX11
+#else
+#define BOOST_CONVERT_CXX11
+#endif
+
+// Intel 12.0 and lower have broken SFINAE
+#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1200)
+# define BOOST_CONVERT_IS_NOT_SUPPORTED
+#endif
+
+// No C++11 support
+#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION <= 40600)
+# define BOOST_CONVERT_IS_NOT_SUPPORTED
+#endif
+
+// MSVC-11 and lower have broken SFINAE
+#if defined(BOOST_MSVC) && (BOOST_MSVC < 1800)
+# define BOOST_CONVERT_IS_NOT_SUPPORTED
+#endif
+
#if defined(_MSC_VER)
+
//MSVC++ 7.0 _MSC_VER == 1300
//MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
//MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
@@ -29,23 +55,4 @@
#endif
-#include <boost/config.hpp>
-#include <boost/version.hpp>
-#include <boost/optional.hpp>
-
-#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
-#undef BOOST_CONVERT_CXX11
-#else
-#define BOOST_CONVERT_CXX11
-#endif
-
-#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1200) /* Intel 12.0 and lower have broken SFINAE */
-#error "Boost.Convert is not supported on this platform due to broken SFINAE."
-#endif
-
-#if defined(BOOST_MSVC) && (BOOST_MSVC < 1800) /* MSVC-11 and lower have broken SFINAE */
-//# error "Boost.Convert is not supported on this platform due to broken SFINAE."
-# define BOOST_CONVERT_MSVC_SFINAE_BROKEN
-#endif
-
#endif // BOOST_CONVERT_FORWARD_HPP
diff --git a/boost/convert/detail/has_member.hpp b/boost/convert/detail/has_member.hpp
index 68e53807a9..2cd617f7b0 100644
--- a/boost/convert/detail/has_member.hpp
+++ b/boost/convert/detail/has_member.hpp
@@ -5,7 +5,6 @@
#ifndef BOOST_CONVERT_HAS_MEMBER_HPP
#define BOOST_CONVERT_HAS_MEMBER_HPP
-#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
// This macro allows to check if a type has a member named "__member_name__"...
@@ -41,7 +40,7 @@
template <typename __boost_has_member_T__> /*C4*/ \
class __trait_name__ \
{ \
- typedef typename ::boost::remove_const<__boost_has_member_T__>::type check_type; \
+ typedef typename boost::remove_const<__boost_has_member_T__>::type check_type; \
typedef ::boost::type_traits::yes_type yes_type; \
typedef ::boost::type_traits:: no_type no_type; \
\
diff --git a/boost/convert/detail/is_converter.hpp b/boost/convert/detail/is_converter.hpp
index 7633b6daba..6964655409 100644
--- a/boost/convert/detail/is_converter.hpp
+++ b/boost/convert/detail/is_converter.hpp
@@ -5,7 +5,7 @@
#ifndef BOOST_CONVERT_IS_CONVERTER_HPP
#define BOOST_CONVERT_IS_CONVERTER_HPP
-#include <boost/convert/detail/forward.hpp>
+#include <boost/convert/detail/config.hpp>
#include <boost/convert/detail/is_callable.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
diff --git a/boost/convert/detail/is_fun.hpp b/boost/convert/detail/is_fun.hpp
index 9fa4d96f9b..72a768188a 100644
--- a/boost/convert/detail/is_fun.hpp
+++ b/boost/convert/detail/is_fun.hpp
@@ -5,7 +5,7 @@
#ifndef BOOST_CONVERT_IS_FUNCTION_HPP
#define BOOST_CONVERT_IS_FUNCTION_HPP
-#include <boost/convert/detail/forward.hpp>
+#include <boost/convert/detail/config.hpp>
#include <boost/convert/detail/has_member.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
diff --git a/boost/convert/detail/is_string.hpp b/boost/convert/detail/is_string.hpp
index ea6ca82e90..75d565e3e7 100644
--- a/boost/convert/detail/is_string.hpp
+++ b/boost/convert/detail/is_string.hpp
@@ -11,7 +11,7 @@ namespace boost { namespace cnv
{
namespace detail
{
- template<typename T, bool is_range_class> struct is_string : mpl::false_ {};
+ template<typename T, bool is_range_class> struct is_string : std::false_type {};
template<typename T> struct is_string<T*, false>
{
@@ -27,7 +27,7 @@ namespace boost { namespace cnv
};
}
template<typename T> struct is_string : detail::is_string<
- typename remove_const<T>::type,
+ typename boost::remove_const<T>::type,
boost::is_class<T>::value && boost::cnv::is_range<T>::value> {};
}}
diff --git a/boost/convert/detail/range.hpp b/boost/convert/detail/range.hpp
index 345321039e..82d105f949 100644
--- a/boost/convert/detail/range.hpp
+++ b/boost/convert/detail/range.hpp
@@ -14,7 +14,7 @@ namespace boost { namespace cnv
{
namespace detail
{
- template<typename T, bool is_class> struct is_range : mpl::false_ {};
+ template<typename T, bool is_class> struct is_range : std::false_type {};
template<typename T> struct is_range<T, /*is_class=*/true>
{
@@ -24,7 +24,7 @@ namespace boost { namespace cnv
static bool const value = has_begin<T>::value && has_end<T>::value;
};
}
- template<typename T> struct is_range : detail::is_range<typename remove_const<T>::type, boost::is_class<T>::value> {};
+ template<typename T> struct is_range : detail::is_range<typename boost::remove_const<T>::type, boost::is_class<T>::value> {};
template<typename T, typename enable =void> struct range;
template<typename T, typename enable =void> struct iterator;
@@ -38,9 +38,9 @@ namespace boost { namespace cnv
template<typename T>
struct iterator<T*, void>
{
- typedef typename remove_const<T>::type value_type;
- typedef T* type;
- typedef value_type const* const_type;
+ typedef typename boost::remove_const<T>::type value_type;
+ typedef T* type;
+ typedef value_type const* const_type;
};
template<typename T>
struct range_base
@@ -74,20 +74,21 @@ namespace boost { namespace cnv
range (T& r) : base_type(r.begin(), r.end()) {}
- iterator end () { return base_type::end_; }
- const_iterator end () const { return base_type::end_; }
- sentry_type sentry () const { return base_type::end_; }
- bool empty () const { return base_type::begin_ == base_type::end_; }
+ iterator end () { return base_type::end_; }
+ const_iterator end () const { return base_type::end_; }
+ sentry_type sentry () const { return base_type::end_; }
+ std::size_t size () const { return base_type::end_ - base_type::begin_; }
+ bool empty () const { return base_type::begin_ == base_type::end_; }
};
template<typename T>
struct range<T*, typename enable_if<cnv::is_char<T> >::type> : public range_base<T*>
{
- typedef range this_type;
- typedef range_base<T*> base_type;
- typedef typename remove_const<T>::type value_type;
- typedef T* iterator;
- typedef value_type const* const_iterator;
+ using this_type = range;
+ using base_type = range_base<T*>;
+ using value_type = typename boost::remove_const<T>::type;
+ using iterator = T*;
+ using const_iterator = value_type const*;
struct sentry_type
{
diff --git a/boost/convert/spirit.hpp b/boost/convert/spirit.hpp
index 22a88b9b3f..b33a793f38 100644
--- a/boost/convert/spirit.hpp
+++ b/boost/convert/spirit.hpp
@@ -6,7 +6,7 @@
#define BOOST_CONVERT_SPIRIT_BASED_CONVERTER_HPP
#include <boost/convert/base.hpp>
-#include <boost/convert/detail/forward.hpp>
+#include <boost/convert/detail/config.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
diff --git a/boost/convert/strtol.hpp b/boost/convert/strtol.hpp
index de5aa29a8a..4dd26eef7f 100644
--- a/boost/convert/strtol.hpp
+++ b/boost/convert/strtol.hpp
@@ -76,16 +76,16 @@ boost::cnv::strtol::i_to_str(Type in_value, char_type* buf) const
typedef typename boost::make_unsigned<Type>::type unsigned_type;
- char_type* beg = buf + bufsize_ / 2;
- char_type* end = beg;
- bool const is_negative = in_value < 0;
- unsigned_type value = static_cast<unsigned_type>(is_negative ? -in_value : in_value);
+ char_type* beg = buf + bufsize_ / 2;
+ char_type* end = beg;
+ bool const is_neg = std::is_signed<Type>::value && in_value < 0;
+ unsigned_type value = static_cast<unsigned_type>(is_neg ? -in_value : in_value);
if (base_ == 10) for (; value; *(--beg) = int(value % 10) + '0', value /= 10); //C1
else for (; value; *(--beg) = get_char(value % base_), value /= base_);
- if (beg == end) *(--beg) = '0';
- if (is_negative) *(--beg) = '-';
+ if (beg == end) *(--beg) = '0';
+ if (is_neg) *(--beg) = '-';
return cnv::range<char_type*>(beg, end);
}
@@ -197,20 +197,20 @@ template<typename string_type, typename out_type>
void
boost::cnv::strtol::str_to_d(cnv::range<string_type> range, optional<out_type>& result_out) const
{
- // C2. Simply check if the end-of-string was reached -- *cnv_end == 0
- // instead of traversing once with strlen() to find the end iterator
- // and then comparing to it as in
- // char const* end = str + strlen(str); // Unnecessary traversal!
- // bool const good = ... && cnv_end == end;
+ // C1. Because of strtold() currently only works with 'char'
+ // C2. strtold() does not work with ranges.
+ // Consequently, we have to copy the supplied range into a string for strtold().
+ // C3. Check if the end-of-string was reached -- *cnv_end == 0.
typedef cnv::range<string_type> range_type;
typedef typename range_type::value_type ch_type;
- ch_type const* str = &*range.begin(); // Currently only works with 'char'
- char* cnv_end = 0;
- ldbl_type result = strtold(str, &cnv_end);
- bool good = result != -HUGE_VALL && result != HUGE_VALL && *cnv_end == 0/*C2*/;
- out_type max = (std::numeric_limits<out_type>::max)();
+ size_t const sz = 128;
+ ch_type str[sz] = {0}; std::strncpy(str, &*range.begin(), std::min(sz - 1, range.size()));
+ char* cnv_end = 0;
+ ldbl_type result = strtold(str, &cnv_end);
+ bool good = result != -HUGE_VALL && result != HUGE_VALL && *cnv_end == 0; //C3
+ out_type max = (std::numeric_limits<out_type>::max)();
if (good && -max <= result && result <= max)
result_out = out_type(result);