mirror of
https://github.com/boostorg/conversion.git
synced 2026-08-06 13:34:14 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ad90f47db |
@@ -10,13 +10,6 @@
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Header boost/cast.hpp Documentation</title>
|
||||
<style>
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
@@ -138,9 +131,10 @@ void f( Fruit * fruit ) {
|
||||
-->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348"
|
||||
--></p>
|
||||
|
||||
<p class="copyright">© Copyright boost.org 1999.
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
<p>© Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice
|
||||
appears in all copies. This document is provided "as is" without express
|
||||
or implied warranty, and with no claim as to its suitability for any
|
||||
purpose.</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
+96
-151
@@ -3,7 +3,7 @@
|
||||
[version 1.0]
|
||||
[copyright 2000-2005 Kevlin Henney]
|
||||
[copyright 2006-2010 Alexander Nasonov]
|
||||
[copyright 2011-2013 Antony Polukhin]
|
||||
[copyright 2011-2012 Antony Polukhin]
|
||||
[category String and text processing]
|
||||
[category Miscellaneous]
|
||||
[license
|
||||
@@ -38,22 +38,54 @@ For a good discussion of the options and issues involved in string-based formatt
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
The following example treats command line arguments as a sequence of numeric data:
|
||||
``
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
using boost::lexical_cast;
|
||||
using boost::bad_lexical_cast;
|
||||
|
||||
[import ../example/args_to_numbers.cpp]
|
||||
std::vector<short> args;
|
||||
|
||||
[section Strings to numbers conversion] [lexical_cast_args_example] [endsect]
|
||||
|
||||
[import ../example/small_examples.cpp]
|
||||
[section Numbers to strings conversion] [lexical_cast_log_errno] [endsect]
|
||||
[section Converting to string without dynamic memory allocation] [lexical_cast_fixed_buffer] [endsect]
|
||||
[section Converting part of the string] [lexical_cast_substring_conversion] [endsect]
|
||||
|
||||
[import ../example/generic_stringize.cpp]
|
||||
[section Generic programming (Boost.Fusion)] [lexical_cast_stringize] [endsect]
|
||||
|
||||
[import ../example/variant_to_long_double.cpp]
|
||||
[section Generic programming (Boost.Variant)] [lexical_cast_variant_to_long_double] [endsect]
|
||||
while(*++argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
args.push_back(lexical_cast<short>(*argv));
|
||||
}
|
||||
catch(bad_lexical_cast &)
|
||||
{
|
||||
args.push_back(0);
|
||||
}
|
||||
}
|
||||
...
|
||||
}
|
||||
``
|
||||
The following example uses numeric data in a string expression:
|
||||
``
|
||||
void log_message(const std::string &);
|
||||
|
||||
void log_errno(int yoko)
|
||||
{
|
||||
log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
|
||||
}
|
||||
``
|
||||
Following example converts some number and puts it to file:
|
||||
``
|
||||
int i;
|
||||
FILE* file;
|
||||
...
|
||||
typedef boost::array<char, 50> buf_t; // You can use std::array if your compiler supports it
|
||||
buf_t buffer = boost::lexical_cast<buf_t>(i); // No dynamic memory allocation
|
||||
puts(buffer.begin(), file);
|
||||
``
|
||||
Following example takes part of the string and converts it to `int`:
|
||||
``
|
||||
int convert_strings_part(const std::string& s, std::size_t pos, std::size_t n)
|
||||
{
|
||||
return boost::lexical_cast<int>(s.data() + pos, n);
|
||||
}
|
||||
``
|
||||
[endsect]
|
||||
|
||||
[section Synopsis]
|
||||
@@ -124,6 +156,56 @@ Exception used to indicate runtime lexical_cast failure.
|
||||
|
||||
[endsect]
|
||||
|
||||
[/ Commenting out bad advise (this will break the ability to get correct function pointers via &lexical_cast<Target, Source>)
|
||||
[section Tuning classes for fast lexical conversions]
|
||||
Because of `boost::lexical_cast` optimizations for `boost::iterator_range<character_type*>`, it is possibile to make very fast lexical conversions for non zero terminated strings, substrings and user-defined classes.
|
||||
|
||||
Consider the following example:
|
||||
``
|
||||
class example_class {
|
||||
char non_zero_terminated_data[10];
|
||||
std::size_t data_length;
|
||||
|
||||
public:
|
||||
example_class();
|
||||
void fill_data();
|
||||
|
||||
const char* data() const {
|
||||
return non_zero_terminated_data;
|
||||
}
|
||||
|
||||
std::size_t size() const {
|
||||
return data_length;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator << (std::ostream& ostr, const example_class& rhs) {
|
||||
return ostr << boost::make_iterator_range(rhs.data(), rhs.data() + rhs.size());
|
||||
}
|
||||
``
|
||||
|
||||
This is a good generic solution for most use cases.
|
||||
But we can make it even faster for some performance critical applications. During conversion, we loose speed at:
|
||||
|
||||
* `std::ostream` construction (it makes some heap allocations)
|
||||
* `operator <<` (it copyies one by one all the symbols to an instance of `std::ostream`)
|
||||
* `std::ostream` destruction (it makes some heap deallocations)
|
||||
|
||||
We can avoid all of this, by specifieng an overload for `boost::lexical_cast`:
|
||||
``
|
||||
namespace boost {
|
||||
template <class OutT>
|
||||
OutT lexical_cast(const example_class& rhs) {
|
||||
return boost::lexical_cast<OutT>(
|
||||
boost::make_iterator_range(rhs.data(), rhs.data() + rhs.size())
|
||||
);
|
||||
}
|
||||
}
|
||||
``
|
||||
Now `boost::lexical_cast<some_type>(example_class_instance)` conversions won't copy data and construct heavy STL stream objects. See [link boost_lexical_cast.performance Performance] section for info on `boost::iterator_range` conversion performance.
|
||||
[endsect]
|
||||
]
|
||||
|
||||
[section Frequently Asked Questions]
|
||||
|
||||
* [*Question:] Why does `lexical_cast<int8_t>("127")` throw `bad_lexical_cast`?
|
||||
@@ -194,17 +276,6 @@ limitation of compiler options that you use.
|
||||
|
||||
[section Changes]
|
||||
|
||||
* [*boost 1.54.0 :]
|
||||
|
||||
* Fix some issues with `boost::int128_type` and `boost::uint128_type` conversions. Notify user at compile time
|
||||
if the `std::numeric_limits` are not specialized for 128bit types and `boost::lexical_cast` can not make conversions.
|
||||
|
||||
* [*boost 1.54.0 :]
|
||||
|
||||
* Added code to convert `boost::int128_type` and `boost::uint128_type` types (requires GCC 4.7 or higher).
|
||||
* Conversions to pointers will now fail to compile, instead of throwing at runtime.
|
||||
* Restored ability to get pointers to `lexical_cast` function (was broken in 1.53.0).
|
||||
|
||||
* [*boost 1.53.0 :]
|
||||
|
||||
* Much better input and output streams detection for user defined types.
|
||||
@@ -809,132 +880,6 @@ Do not use this results to compare compilers, because tests were taken on differ
|
||||
]
|
||||
[endsect]
|
||||
|
||||
[section Microsoft Visual C++ version 11.0]
|
||||
[table:id Performance Table ( Microsoft Visual C++ version 11.0)
|
||||
[[From->To] [lexical_cast] [std::stringstream with construction] [std::stringstream without construction][scanf/printf]]
|
||||
[[ string->char ][ !!! *<1* !!! ][ 43 ][ 17 ][ 7 ]]
|
||||
[[ string->signed char ][ !!! *<1* !!! ][ 43 ][ 17 ][ 8 ]]
|
||||
[[ string->unsigned char ][ !!! *<1* !!! ][ 42 ][ 17 ][ 8 ]]
|
||||
[[ string->int ][ !!! *8* !!! ][ 71 ][ 49 ][ 10 ]]
|
||||
[[ string->short ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ string->long int ][ !!! *8* !!! ][ 71 ][ 47 ][ 10 ]]
|
||||
[[ string->long long ][ !!! *8* !!! ][ 71 ][ 47 ][ 10 ]]
|
||||
[[ string->unsigned int ][ !!! *8* !!! ][ 72 ][ 46 ][ 10 ]]
|
||||
[[ string->unsigned short ][ !!! *8* !!! ][ 71 ][ 47 ][ 10 ]]
|
||||
[[ string->unsigned long int ][ !!! *8* !!! ][ 70 ][ 45 ][ 10 ]]
|
||||
[[ string->unsigned long long ][ !!! *8* !!! ][ 70 ][ 46 ][ 10 ]]
|
||||
[[ string->float ][ !!! *14* !!! ][ 586 ][ 559 ][ 37 ]]
|
||||
[[ string->double ][ 601 ][ 618 ][ 592 ][ !!! *37* !!! ]]
|
||||
[[ string->long double ][ 629 ][ 645 ][ 618 ][ !!! *37* !!! ]]
|
||||
[[ string->array<char, 50> ][ !!! *<1* !!! ][ 52 ][ 28 ][ 11 ]]
|
||||
[[ string->string ][ !!! *1* !!! ][ 59 ][ 34 ][ --- ]]
|
||||
[[ string->container::string ][ !!! *2* !!! ][ 54 ][ 31 ][ --- ]]
|
||||
[[ string->char ][ !!! *2* !!! ][ 50 ][ 24 ][ 9 ]]
|
||||
[[ string->signed char ][ !!! *2* !!! ][ 50 ][ 24 ][ 13 ]]
|
||||
[[ string->unsigned char ][ !!! *2* !!! ][ 50 ][ 24 ][ 13 ]]
|
||||
[[ int->string ][ !!! *9* !!! ][ 86 ][ 59 ][ 13 ]]
|
||||
[[ short->string ][ !!! *9* !!! ][ 86 ][ 59 ][ 13 ]]
|
||||
[[ long int->string ][ !!! *9* !!! ][ 87 ][ 59 ][ 13 ]]
|
||||
[[ long long->string ][ !!! *9* !!! ][ 88 ][ 62 ][ 13 ]]
|
||||
[[ unsigned int->string ][ !!! *9* !!! ][ 87 ][ 60 ][ 13 ]]
|
||||
[[ unsigned short->string ][ !!! *9* !!! ][ 91 ][ 63 ][ 13 ]]
|
||||
[[ unsigned long int->string ][ !!! *9* !!! ][ 91 ][ 62 ][ 13 ]]
|
||||
[[ unsigned long long->string ][ !!! *9* !!! ][ 88 ][ 60 ][ 13 ]]
|
||||
[[ float->string ][ 73 ][ 167 ][ 137 ][ !!! *56* !!! ]]
|
||||
[[ double->string ][ 77 ][ 176 ][ 144 ][ !!! *64* !!! ]]
|
||||
[[ long double->string ][ 79 ][ 175 ][ 143 ][ !!! *63* !!! ]]
|
||||
[[ char*->char ][ !!! *<1* !!! ][ 43 ][ 17 ][ 7 ]]
|
||||
[[ char*->signed char ][ !!! *<1* !!! ][ 43 ][ 17 ][ 8 ]]
|
||||
[[ char*->unsigned char ][ !!! *<1* !!! ][ 44 ][ 17 ][ 8 ]]
|
||||
[[ char*->int ][ !!! *8* !!! ][ 70 ][ 47 ][ 10 ]]
|
||||
[[ char*->short ][ !!! *8* !!! ][ 72 ][ 48 ][ 10 ]]
|
||||
[[ char*->long int ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ char*->long long ][ !!! *8* !!! ][ 71 ][ 47 ][ 10 ]]
|
||||
[[ char*->unsigned int ][ !!! *8* !!! ][ 72 ][ 46 ][ 10 ]]
|
||||
[[ char*->unsigned short ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ char*->unsigned long int ][ !!! *8* !!! ][ 70 ][ 46 ][ 10 ]]
|
||||
[[ char*->unsigned long long ][ !!! *8* !!! ][ 70 ][ 45 ][ 10 ]]
|
||||
[[ char*->float ][ !!! *14* !!! ][ 586 ][ 560 ][ 37 ]]
|
||||
[[ char*->double ][ 598 ][ 617 ][ 597 ][ !!! *40* !!! ]]
|
||||
[[ char*->long double ][ 635 ][ 653 ][ 622 ][ !!! *37* !!! ]]
|
||||
[[ char*->array<char, 50> ][ !!! *1* !!! ][ 53 ][ 28 ][ 11 ]]
|
||||
[[ char*->string ][ !!! *1* !!! ][ 59 ][ 35 ][ --- ]]
|
||||
[[ char*->container::string ][ !!! *3* !!! ][ 54 ][ 30 ][ --- ]]
|
||||
[[ unsigned char*->char ][ !!! *<1* !!! ][ 41 ][ 17 ][ 7 ]]
|
||||
[[ unsigned char*->signed char ][ !!! *<1* !!! ][ 42 ][ 17 ][ 8 ]]
|
||||
[[ unsigned char*->unsigned char ][ !!! *<1* !!! ][ 41 ][ 17 ][ 8 ]]
|
||||
[[ unsigned char*->int ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ unsigned char*->short ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ unsigned char*->long int ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ unsigned char*->long long ][ !!! *8* !!! ][ 72 ][ 47 ][ 11 ]]
|
||||
[[ unsigned char*->unsigned int ][ !!! *8* !!! ][ 70 ][ 46 ][ 10 ]]
|
||||
[[ unsigned char*->unsigned short ][ !!! *8* !!! ][ 72 ][ 48 ][ 10 ]]
|
||||
[[ unsigned char*->unsigned long int ][ !!! *8* !!! ][ 71 ][ 46 ][ 10 ]]
|
||||
[[ unsigned char*->unsigned long long ][ !!! *8* !!! ][ 70 ][ 45 ][ 11 ]]
|
||||
[[ unsigned char*->float ][ !!! *14* !!! ][ 589 ][ 564 ][ 38 ]]
|
||||
[[ unsigned char*->double ][ 601 ][ 615 ][ 588 ][ !!! *37* !!! ]]
|
||||
[[ unsigned char*->long double ][ 628 ][ 644 ][ 620 ][ !!! *38* !!! ]]
|
||||
[[ unsigned char*->array<char, 50> ][ !!! *1* !!! ][ 54 ][ 28 ][ 11 ]]
|
||||
[[ unsigned char*->string ][ !!! *2* !!! ][ 59 ][ 36 ][ --- ]]
|
||||
[[ unsigned char*->container::string ][ !!! *3* !!! ][ 54 ][ 30 ][ --- ]]
|
||||
[[ signed char*->char ][ !!! *<1* !!! ][ 41 ][ 17 ][ 7 ]]
|
||||
[[ signed char*->signed char ][ !!! *<1* !!! ][ 43 ][ 17 ][ 8 ]]
|
||||
[[ signed char*->unsigned char ][ !!! *<1* !!! ][ 42 ][ 17 ][ 8 ]]
|
||||
[[ signed char*->int ][ !!! *8* !!! ][ 71 ][ 47 ][ 10 ]]
|
||||
[[ signed char*->short ][ !!! *8* !!! ][ 72 ][ 48 ][ 10 ]]
|
||||
[[ signed char*->long int ][ !!! *8* !!! ][ 71 ][ 47 ][ 10 ]]
|
||||
[[ signed char*->long long ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ signed char*->unsigned int ][ !!! *8* !!! ][ 70 ][ 46 ][ 10 ]]
|
||||
[[ signed char*->unsigned short ][ !!! *8* !!! ][ 72 ][ 47 ][ 10 ]]
|
||||
[[ signed char*->unsigned long int ][ !!! *8* !!! ][ 70 ][ 46 ][ 10 ]]
|
||||
[[ signed char*->unsigned long long ][ !!! *8* !!! ][ 70 ][ 46 ][ 11 ]]
|
||||
[[ signed char*->float ][ !!! *14* !!! ][ 586 ][ 562 ][ 37 ]]
|
||||
[[ signed char*->double ][ 603 ][ 615 ][ 589 ][ !!! *37* !!! ]]
|
||||
[[ signed char*->long double ][ 630 ][ 644 ][ 623 ][ !!! *40* !!! ]]
|
||||
[[ signed char*->array<char, 50> ][ !!! *1* !!! ][ 54 ][ 28 ][ 11 ]]
|
||||
[[ signed char*->string ][ !!! *2* !!! ][ 59 ][ 36 ][ --- ]]
|
||||
[[ signed char*->container::string ][ !!! *3* !!! ][ 54 ][ 30 ][ --- ]]
|
||||
[[ iterator_range<char*>->char ][ !!! *<1* !!! ][ 74 ][ 46 ][ 7 ]]
|
||||
[[ iterator_range<char*>->signed char ][ !!! *<1* !!! ][ 75 ][ 46 ][ 8 ]]
|
||||
[[ iterator_range<char*>->unsigned char ][ !!! *<1* !!! ][ 74 ][ 46 ][ 8 ]]
|
||||
[[ iterator_range<char*>->int ][ !!! *8* !!! ][ 98 ][ 70 ][ 10 ]]
|
||||
[[ iterator_range<char*>->short ][ !!! *8* !!! ][ 103 ][ 72 ][ 10 ]]
|
||||
[[ iterator_range<char*>->long int ][ !!! *8* !!! ][ 111 ][ 71 ][ 10 ]]
|
||||
[[ iterator_range<char*>->long long ][ !!! *8* !!! ][ 98 ][ 70 ][ 10 ]]
|
||||
[[ iterator_range<char*>->unsigned int ][ !!! *7* !!! ][ 103 ][ 76 ][ 10 ]]
|
||||
[[ iterator_range<char*>->unsigned short ][ !!! *8* !!! ][ 104 ][ 75 ][ 10 ]]
|
||||
[[ iterator_range<char*>->unsigned long int ][ !!! *7* !!! ][ 104 ][ 71 ][ 10 ]]
|
||||
[[ iterator_range<char*>->unsigned long long ][ !!! *8* !!! ][ 99 ][ 71 ][ 11 ]]
|
||||
[[ iterator_range<char*>->float ][ !!! *13* !!! ][ 123 ][ 93 ][ 37 ]]
|
||||
[[ iterator_range<char*>->double ][ 603 ][ 111 ][ 82 ][ !!! *38* !!! ]]
|
||||
[[ iterator_range<char*>->long double ][ 629 ][ 116 ][ 83 ][ !!! *38* !!! ]]
|
||||
[[ iterator_range<char*>->array<char, 50> ][ !!! *<1* !!! ][ 82 ][ 52 ][ 11 ]]
|
||||
[[ iterator_range<char*>->string ][ !!! *2* !!! ][ 83 ][ 56 ][ --- ]]
|
||||
[[ iterator_range<char*>->container::string ][ !!! *2* !!! ][ 81 ][ 53 ][ --- ]]
|
||||
[[ array<char, 50>->char ][ !!! *<1* !!! ][ 41 ][ 17 ][ 7 ]]
|
||||
[[ array<char, 50>->signed char ][ !!! *<1* !!! ][ 41 ][ 17 ][ 8 ]]
|
||||
[[ array<char, 50>->unsigned char ][ !!! *<1* !!! ][ 41 ][ 17 ][ 8 ]]
|
||||
[[ array<char, 50>->int ][ !!! *8* !!! ][ 73 ][ 46 ][ 10 ]]
|
||||
[[ array<char, 50>->short ][ !!! *8* !!! ][ 73 ][ 47 ][ 10 ]]
|
||||
[[ array<char, 50>->long int ][ !!! *8* !!! ][ 75 ][ 48 ][ 10 ]]
|
||||
[[ array<char, 50>->long long ][ !!! *8* !!! ][ 73 ][ 48 ][ 11 ]]
|
||||
[[ array<char, 50>->unsigned int ][ !!! *8* !!! ][ 73 ][ 47 ][ 10 ]]
|
||||
[[ array<char, 50>->unsigned short ][ !!! *8* !!! ][ 74 ][ 50 ][ 10 ]]
|
||||
[[ array<char, 50>->unsigned long int ][ !!! *8* !!! ][ 71 ][ 46 ][ 10 ]]
|
||||
[[ array<char, 50>->unsigned long long ][ !!! *8* !!! ][ 70 ][ 47 ][ 11 ]]
|
||||
[[ array<char, 50>->float ][ !!! *14* !!! ][ 586 ][ 567 ][ 37 ]]
|
||||
[[ array<char, 50>->double ][ 599 ][ 624 ][ 590 ][ !!! *37* !!! ]]
|
||||
[[ array<char, 50>->long double ][ 632 ][ 643 ][ 618 ][ !!! *37* !!! ]]
|
||||
[[ array<char, 50>->array<char, 50> ][ !!! *1* !!! ][ 52 ][ 28 ][ 11 ]]
|
||||
[[ array<char, 50>->string ][ !!! *2* !!! ][ 59 ][ 34 ][ --- ]]
|
||||
[[ array<char, 50>->container::string ][ !!! *3* !!! ][ 55 ][ 30 ][ --- ]]
|
||||
[[ int->int ][ !!! *<1* !!! ][ 105 ][ 79 ][ --- ]]
|
||||
[[ float->double ][ !!! *<1* !!! ][ 226 ][ 188 ][ --- ]]
|
||||
[[ char->signed char ][ !!! *<1* !!! ][ 40 ][ 16 ][ --- ]]
|
||||
]
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[/ END of section, generated by performance measuring program ]
|
||||
[endsect]
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2013 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
//[lexical_cast_args_example
|
||||
//`The following example treats command line arguments as a sequence of numeric data
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <vector>
|
||||
|
||||
int main(int /*argc*/, char * argv[])
|
||||
{
|
||||
using boost::lexical_cast;
|
||||
using boost::bad_lexical_cast;
|
||||
|
||||
std::vector<short> args;
|
||||
|
||||
while (*++argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
args.push_back(lexical_cast<short>(*argv));
|
||||
}
|
||||
catch(const bad_lexical_cast &)
|
||||
{
|
||||
args.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
//] [/lexical_cast_args_example]
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright 2013 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
|
||||
//[lexical_cast_stringize
|
||||
/*`
|
||||
In this example we'll make a `stringize` method that accepts a sequence, converts
|
||||
each element of the sequence into string and appends that string to the result.
|
||||
|
||||
Example is based on the example from the [@http://www.packtpub.com/boost-cplusplus-application-development-cookbook/book Boost C++ Application Development Cookbook]
|
||||
by Antony Polukhin, ISBN 9781849514880.
|
||||
|
||||
Step 1: Making a functor that converts any type to a string and remembers result:
|
||||
*/
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
struct stringize_functor {
|
||||
private:
|
||||
std::string& result;
|
||||
|
||||
public:
|
||||
explicit stringize_functor(std::string& res)
|
||||
: result(res)
|
||||
{}
|
||||
|
||||
template <class T>
|
||||
void operator()(const T& v) const {
|
||||
result += boost::lexical_cast<std::string>(v);
|
||||
}
|
||||
};
|
||||
|
||||
//` Step 2: Applying `stringize_functor` to each element in sequence:
|
||||
#include <boost/fusion/include/for_each.hpp>
|
||||
template <class Sequence>
|
||||
std::string stringize(const Sequence& seq) {
|
||||
std::string result;
|
||||
boost::fusion::for_each(seq, stringize_functor(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
//` Step 3: Using the `stringize` with different types:
|
||||
#include <cassert>
|
||||
#include <boost/fusion/adapted/boost_tuple.hpp>
|
||||
#include <boost/fusion/adapted/std_pair.hpp>
|
||||
|
||||
int main() {
|
||||
boost::tuple<char, int, char, int> decim('-', 10, 'e', 5);
|
||||
assert(stringize(decim) == "-10e5");
|
||||
|
||||
std::pair<short, std::string> value_and_type(270, "Kelvin");
|
||||
assert(stringize(value_and_type) == "270Kelvin");
|
||||
}
|
||||
|
||||
//] [/lexical_cast_stringize]
|
||||
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright 2013 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
//[lexical_cast_log_errno
|
||||
//`The following example uses numeric data in a string expression:
|
||||
|
||||
void log_message(const std::string &);
|
||||
|
||||
void log_errno(int yoko)
|
||||
{
|
||||
log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
|
||||
}
|
||||
|
||||
//] [/lexical_cast_log_errno]
|
||||
|
||||
|
||||
//[lexical_cast_fixed_buffer
|
||||
//`The following example converts some number and puts it to file:
|
||||
|
||||
void number_to_file(int number, FILE* file)
|
||||
{
|
||||
typedef boost::array<char, 50> buf_t; // You can use std::array if your compiler supports it
|
||||
buf_t buffer = boost::lexical_cast<buf_t>(number); // No dynamic memory allocation
|
||||
fputs(buffer.begin(), file);
|
||||
}
|
||||
|
||||
//] [/lexical_cast_fixed_buffer]
|
||||
|
||||
//[lexical_cast_substring_conversion
|
||||
//`The following example takes part of the string and converts it to `int`:
|
||||
|
||||
int convert_strings_part(const std::string& s, std::size_t pos, std::size_t n)
|
||||
{
|
||||
return boost::lexical_cast<int>(s.data() + pos, n);
|
||||
}
|
||||
|
||||
//] [/lexical_cast_substring_conversion]
|
||||
|
||||
void log_message(const std::string &) {}
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2013 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
|
||||
//[lexical_cast_variant_to_long_double
|
||||
/*`
|
||||
In this example we'll make a `to_long_double` method that converts value of the Boost.Variant to `long double`.
|
||||
*/
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <cassert>
|
||||
|
||||
struct to_long_double_functor: boost::static_visitor<long double> {
|
||||
template <class T>
|
||||
long double operator()(const T& v) const {
|
||||
// Lexical cast has many optimizations including optimizations for situations that usually
|
||||
// occur in generic programming, like std::string to std::string or arithmetic type to arithmetic type conversion.
|
||||
return boost::lexical_cast<long double>(v);
|
||||
}
|
||||
};
|
||||
|
||||
// Throws `boost::bad_lexical_cast` if value of the variant is not convertible to `long double`
|
||||
template <class Variant>
|
||||
long double to_long_double(const Variant& v) {
|
||||
return boost::apply_visitor(to_long_double_functor(), v);
|
||||
}
|
||||
|
||||
int main() {
|
||||
boost::variant<char, int, std::string> v1('0'), v2("10.0001"), v3(1);
|
||||
|
||||
long double sum = to_long_double(v1) + to_long_double(v2) + to_long_double(v3);
|
||||
assert(sum > 11 && sum < 11.1);
|
||||
}
|
||||
|
||||
//] [/lexical_cast_variant_to_long_double]
|
||||
+67
-247
@@ -19,7 +19,7 @@
|
||||
// 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 - 2013
|
||||
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
|
||||
@@ -168,7 +168,6 @@ namespace boost
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#ifndef BOOST_NO_CWCHAR
|
||||
# include <cwchar>
|
||||
#endif
|
||||
@@ -311,11 +310,6 @@ namespace boost {
|
||||
> {};
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_INT128
|
||||
template <> struct stream_char_common< boost::int128_type >: public boost::mpl::identity< char > {};
|
||||
template <> struct stream_char_common< boost::uint128_type >: public boost::mpl::identity< char > {};
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
template <>
|
||||
struct stream_char_common< wchar_t >
|
||||
@@ -608,10 +602,6 @@ namespace boost {
|
||||
BOOST_LCAST_DEF(unsigned __int64)
|
||||
BOOST_LCAST_DEF( __int64)
|
||||
#endif
|
||||
#ifdef BOOST_HAS_INT128
|
||||
BOOST_LCAST_DEF(boost::int128_type)
|
||||
BOOST_LCAST_DEF(boost::uint128_type)
|
||||
#endif
|
||||
|
||||
#undef BOOST_LCAST_DEF
|
||||
|
||||
@@ -834,7 +824,7 @@ namespace boost {
|
||||
if(group < grouping_size)
|
||||
{
|
||||
char const grp_size = grouping[group];
|
||||
last_grp_size = grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size;
|
||||
last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
|
||||
}
|
||||
|
||||
left = last_grp_size;
|
||||
@@ -874,23 +864,15 @@ namespace boost {
|
||||
{
|
||||
#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
|
||||
typedef typename Traits::int_type int_type;
|
||||
CharT const czero = lcast_char_constants<CharT>::zero;
|
||||
--end;
|
||||
value = 0;
|
||||
|
||||
if (begin > end || *end < czero || *end >= czero + 10)
|
||||
return false;
|
||||
value = static_cast<T>(*end - czero);
|
||||
value = *end - czero;
|
||||
--end;
|
||||
T multiplier = 1;
|
||||
bool multiplier_overflowed = false;
|
||||
@@ -910,17 +892,17 @@ namespace boost {
|
||||
{
|
||||
unsigned char current_grouping = 0;
|
||||
CharT const thousands_sep = np.thousands_sep();
|
||||
char remained = static_cast<char>(grouping[current_grouping] - 1);
|
||||
char remained = grouping[current_grouping] - 1;
|
||||
bool shall_we_return = true;
|
||||
|
||||
for(;end>=begin; --end)
|
||||
{
|
||||
if (remained) {
|
||||
T const multiplier_10 = static_cast<T>(multiplier * 10);
|
||||
T const multiplier_10 = multiplier * 10;
|
||||
if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
|
||||
|
||||
T const dig_value = static_cast<T>(*end - czero);
|
||||
T const new_sub_value = static_cast<T>(multiplier_10 * dig_value);
|
||||
T const dig_value = *end - czero;
|
||||
T const new_sub_value = multiplier_10 * dig_value;
|
||||
|
||||
if (*end < czero || *end >= czero + 10
|
||||
/* detecting overflow */
|
||||
@@ -930,8 +912,8 @@ namespace boost {
|
||||
)
|
||||
return false;
|
||||
|
||||
value = static_cast<T>(value + new_sub_value);
|
||||
multiplier = static_cast<T>(multiplier * 10);
|
||||
value += new_sub_value;
|
||||
multiplier *= 10;
|
||||
--remained;
|
||||
} else {
|
||||
if ( !Traits::eq(*end, thousands_sep) ) //|| begin == end ) return false;
|
||||
@@ -964,11 +946,11 @@ namespace boost {
|
||||
{
|
||||
while ( begin <= end )
|
||||
{
|
||||
T const multiplier_10 = static_cast<T>(multiplier * 10);
|
||||
T const multiplier_10 = multiplier * 10;
|
||||
if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
|
||||
|
||||
T const dig_value = static_cast<T>(*end - czero);
|
||||
T const new_sub_value = static_cast<T>(multiplier_10 * dig_value);
|
||||
T const dig_value = *end - czero;
|
||||
T const new_sub_value = multiplier_10 * dig_value;
|
||||
|
||||
if (*end < czero || *end >= czero + 10
|
||||
/* detecting overflow */
|
||||
@@ -978,8 +960,8 @@ namespace boost {
|
||||
)
|
||||
return false;
|
||||
|
||||
value = static_cast<T>(value + new_sub_value);
|
||||
multiplier = static_cast<T>(multiplier * 10);
|
||||
value += new_sub_value;
|
||||
multiplier *= 10;
|
||||
--end;
|
||||
}
|
||||
}
|
||||
@@ -1160,12 +1142,6 @@ namespace boost {
|
||||
|
||||
namespace detail // lcast_ret_float
|
||||
{
|
||||
|
||||
// Silence buggy MS warnings like C4244: '+=' : conversion from 'int' to 'unsigned short', possible loss of data
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4244)
|
||||
#endif
|
||||
template <class T>
|
||||
struct mantissa_holder_type
|
||||
{
|
||||
@@ -1176,19 +1152,15 @@ namespace boost {
|
||||
struct mantissa_holder_type<float>
|
||||
{
|
||||
typedef unsigned int type;
|
||||
typedef double wide_result_t;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct mantissa_holder_type<double>
|
||||
{
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
typedef long double wide_result_t;
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
typedef boost::ulong_long_type type;
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
typedef unsigned __int64 type;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1206,7 +1178,7 @@ namespace boost {
|
||||
: np.grouping()
|
||||
);
|
||||
std::string::size_type const grouping_size = grouping.size();
|
||||
CharT const thousands_sep = static_cast<CharT>(grouping_size ? np.thousands_sep() : 0);
|
||||
CharT const thousands_sep = grouping_size ? np.thousands_sep() : 0;
|
||||
CharT const decimal_point = np.decimal_point();
|
||||
bool found_grouping = false;
|
||||
std::string::size_type last_grouping_pos = grouping_size - 1;
|
||||
@@ -1226,7 +1198,6 @@ namespace boost {
|
||||
|
||||
typedef typename Traits::int_type int_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::type mantissa_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::wide_result_t wide_result_t;
|
||||
int_type const zero = Traits::to_int_type(czero);
|
||||
if (begin == end) return false;
|
||||
|
||||
@@ -1405,110 +1376,32 @@ namespace boost {
|
||||
/* We need a more accurate algorithm... We can not use current algorithm
|
||||
* with long doubles (and with doubles if sizeof(double)==sizeof(long double)).
|
||||
*/
|
||||
const wide_result_t result = std::pow(static_cast<wide_result_t>(10.0), pow_of_10) * mantissa;
|
||||
long double result = std::pow(10.0L, pow_of_10) * mantissa;
|
||||
value = static_cast<T>( has_minus ? (boost::math::changesign)(result) : result);
|
||||
|
||||
if ( (boost::math::isinf)(value) || (boost::math::isnan)(value) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// Unsilence buggy MS warnings like C4244: '+=' : conversion from 'int' to 'unsigned short', possible loss of data
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace detail // parser_buf
|
||||
namespace detail // stl_buf_unlocker
|
||||
{
|
||||
//
|
||||
// class parser_buf:
|
||||
// acts as a stream buffer which wraps around a pair of pointers
|
||||
//
|
||||
// This class is copied (and slightly changed) from
|
||||
// boost/regex/v4/cpp_regex_traits.hpp
|
||||
// Thanks John Maddock for it! (previous version had some
|
||||
// problems with libc++ and some other STL implementations)
|
||||
template <class BufferType, class charT>
|
||||
class parser_buf : public BufferType {
|
||||
typedef BufferType base_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;
|
||||
|
||||
template< class BufferType, class CharT >
|
||||
class stl_buf_unlocker: public BufferType{
|
||||
public:
|
||||
parser_buf() : base_type() { setbuf(0, 0); }
|
||||
const charT* getnext() { return this->gptr(); }
|
||||
typedef BufferType base_class;
|
||||
#ifndef BOOST_NO_USING_TEMPLATE
|
||||
using base_type::pptr;
|
||||
using base_type::pbase;
|
||||
using base_class::pptr;
|
||||
using base_class::pbase;
|
||||
using base_class::setg;
|
||||
using base_class::setp;
|
||||
#else
|
||||
charT* pptr() const { return base_type::pptr(); }
|
||||
charT* pbase() const { return base_type::pbase(); }
|
||||
CharT* pptr() const { return base_class::pptr(); }
|
||||
CharT* pbase() const { return base_class::pbase(); }
|
||||
void setg(CharT* gbeg, CharT* gnext, CharT* gend){ return base_class::setg(gbeg, gnext, gend); }
|
||||
void setp(CharT* pbeg, CharT* pend) { return setp(pbeg, pend); }
|
||||
#endif
|
||||
base_type* setbuf(char_type* s, streamsize n) {
|
||||
this->setg(s, s, s + n);
|
||||
return this;
|
||||
}
|
||||
|
||||
pos_type 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));
|
||||
}
|
||||
|
||||
pos_type 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
|
||||
}
|
||||
private:
|
||||
parser_buf& operator=(const parser_buf&);
|
||||
parser_buf(const parser_buf&);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1529,12 +1422,13 @@ namespace boost {
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
typedef std::ostrstream out_stream_t;
|
||||
typedef stl_buf_unlocker<std::strstreambuf, char> unlocked_but_t;
|
||||
#elif defined(BOOST_NO_STD_LOCALE)
|
||||
typedef std::ostringstream out_stream_t;
|
||||
typedef parser_buf<std::streambuf, char> buffer_t;
|
||||
typedef stl_buf_unlocker<std::stringbuf, char> unlocked_but_t;
|
||||
#else
|
||||
typedef std::basic_ostringstream<CharT, Traits> out_stream_t;
|
||||
typedef parser_buf<std::basic_streambuf<CharT, Traits>, CharT> buffer_t;
|
||||
typedef std::basic_ostringstream<CharT, Traits> out_stream_t;
|
||||
typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT> unlocked_but_t;
|
||||
#endif
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
||||
RequiresStringbuffer,
|
||||
@@ -1548,7 +1442,7 @@ namespace boost {
|
||||
deduced_out_stream_t out_stream;
|
||||
|
||||
public:
|
||||
lexical_stream_limited_src(CharT* sta, CharT* fin) BOOST_NOEXCEPT
|
||||
lexical_stream_limited_src(CharT* sta, CharT* fin)
|
||||
: start(sta)
|
||||
, finish(fin)
|
||||
{}
|
||||
@@ -1616,23 +1510,12 @@ namespace boost {
|
||||
// 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 buffer_t* const p = static_cast<buffer_t*>(
|
||||
static_cast<std::basic_streambuf<CharT, Traits>*>(out_stream.rdbuf())
|
||||
);
|
||||
const unlocked_but_t* const p
|
||||
= static_cast<unlocked_but_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>
|
||||
@@ -1840,12 +1723,6 @@ namespace boost {
|
||||
bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
||||
bool operator<<( __int64 n) { return shl_signed(n); }
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_INT128
|
||||
bool operator<<(const boost::uint128_type& n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
|
||||
bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
|
||||
#endif
|
||||
|
||||
bool operator<<(float val) { return shl_real_type(val, start, finish); }
|
||||
bool operator<<(double val) { return shl_real_type(val, start, finish); }
|
||||
bool operator<<(long double val) {
|
||||
@@ -1981,38 +1858,35 @@ namespace boost {
|
||||
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 _MSC_VER)
|
||||
# pragma warning( push )
|
||||
// conditional expression is constant
|
||||
# pragma warning( disable : 4127 )
|
||||
#endif
|
||||
if(is_pointer<InputStreamable>::value)
|
||||
return false;
|
||||
|
||||
#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."
|
||||
);
|
||||
// If you have compilation error at this point, than your STL library
|
||||
// unsupports such conversions. Try updating it.
|
||||
BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
std::istrstream stream(start, finish - start);
|
||||
#elif defined(BOOST_NO_STD_LOCALE)
|
||||
std::istringstream stream;
|
||||
#else
|
||||
|
||||
buffer_t buf;
|
||||
buf.setbuf(start, 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 {
|
||||
std::basic_istringstream<CharT, Traits> stream;
|
||||
#endif
|
||||
static_cast<unlocked_but_t*>(stream.rdbuf())
|
||||
->setg(start, start, finish);
|
||||
|
||||
stream.unsetf(std::ios::skipws);
|
||||
lcast_set_precision(stream, static_cast<InputStreamable*>(0));
|
||||
|
||||
#if (defined _MSC_VER)
|
||||
# pragma warning( pop )
|
||||
#endif
|
||||
return stream >> output &&
|
||||
stream.get() ==
|
||||
#if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
|
||||
@@ -2024,12 +1898,6 @@ namespace boost {
|
||||
#else
|
||||
Traits::eof();
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch (const ::std::ios_base::failure& /*f*/) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -2048,7 +1916,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
/************************************ OPERATORS >> ( ... ) ********************************/
|
||||
public:
|
||||
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); }
|
||||
@@ -2062,12 +1930,6 @@ namespace boost {
|
||||
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); }
|
||||
@@ -2223,10 +2085,10 @@ namespace boost {
|
||||
* double, because it will give a big precision loss.
|
||||
* */
|
||||
boost::mpl::if_c<
|
||||
#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
|
||||
#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
|
||||
boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
|
||||
#else
|
||||
1,
|
||||
0
|
||||
#endif
|
||||
int,
|
||||
char
|
||||
@@ -2462,7 +2324,7 @@ namespace boost {
|
||||
> converter_t;
|
||||
|
||||
return (
|
||||
arg < 0 ? static_cast<Target>(0u - converter_t::convert(0u - arg)) : converter_t::convert(arg)
|
||||
arg < 0 ? 0u - converter_t::convert(0u - arg) : converter_t::convert(arg)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -2543,59 +2405,17 @@ namespace boost {
|
||||
return caster_type::lexical_cast_impl(arg);
|
||||
}
|
||||
|
||||
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, typename CharType>
|
||||
inline Target lexical_cast(const CharType* chars, std::size_t count)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(boost::detail::is_char_or_wchar<CharType>::value,
|
||||
"CharType must be a character or wide character type");
|
||||
|
||||
|
||||
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)
|
||||
return boost::lexical_cast<Target>(
|
||||
boost::iterator_range<const CharType*>(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
|
||||
|
||||
#else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
@@ -2735,7 +2555,7 @@ namespace boost {
|
||||
|
||||
// Copyright Kevlin Henney, 2000-2005.
|
||||
// Copyright Alexander Nasonov, 2006-2010.
|
||||
// Copyright Antony Polukhin, 2011-2013.
|
||||
// Copyright Antony Polukhin, 2011-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
+2
-13
@@ -6,13 +6,6 @@
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Boost Conversion Library</title>
|
||||
<style>
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
@@ -39,11 +32,7 @@ supplied by several headers:</p>
|
||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED"
|
||||
S-Format="%d %B, %Y" startspan -->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348" -->
|
||||
</p>
|
||||
<p class="copyright">
|
||||
Copyright 2001 Beman Dawes.
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+10
-5
@@ -36,7 +36,6 @@
|
||||
#include <boost/type_traits/integral_promotion.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm> // std::transform
|
||||
#include <memory>
|
||||
|
||||
#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
|
||||
@@ -67,6 +66,7 @@ void test_conversion_to_bool();
|
||||
void test_conversion_with_nonconst_char();
|
||||
void test_conversion_to_string();
|
||||
void test_conversion_from_to_wchar_t_alias();
|
||||
void test_conversion_to_pointer();
|
||||
void test_conversion_from_wchar_t();
|
||||
void test_conversion_to_wchar_t();
|
||||
void test_conversion_from_wstring();
|
||||
@@ -99,6 +99,7 @@ unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_double));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_bool));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_pointer));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_string));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_with_nonconst_char));
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
@@ -310,6 +311,14 @@ void test_conversion_from_to_wchar_t_alias()
|
||||
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123ul));
|
||||
}
|
||||
|
||||
void test_conversion_to_pointer()
|
||||
{
|
||||
BOOST_CHECK_THROW(lexical_cast<char *>("Test"), bad_lexical_cast);
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), bad_lexical_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_from_wchar_t()
|
||||
{
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
@@ -613,10 +622,6 @@ void test_getting_pointer_to_function()
|
||||
typedef std::string(*f3)(const int&);
|
||||
f3 p3 = &boost::lexical_cast<std::string, int>;
|
||||
BOOST_CHECK(p3);
|
||||
|
||||
std::vector<int> values;
|
||||
std::vector<std::string> ret;
|
||||
std::transform(values.begin(), values.end(), ret.begin(), boost::lexical_cast<std::string, int>);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ int test_main( int , char * [] )
|
||||
long large_negative_value = LONG_MIN;
|
||||
signed char c = 0;
|
||||
|
||||
c = static_cast<signed char>(large_value);
|
||||
c = large_value; // see if compiler generates warning
|
||||
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
BOOST_CHECK( c == 1 );
|
||||
|
||||
+2
-16
@@ -1,5 +1,5 @@
|
||||
# Copyright (C) 2001-2003 Douglas Gregor
|
||||
# Copyright (C) 2011-2013 Antony Polukhin
|
||||
# Copyright (C) 2011-2012 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)
|
||||
@@ -15,11 +15,6 @@ project
|
||||
<toolset>gcc-4.7:<cxxflags>-ftrapv
|
||||
<toolset>gcc-4.6:<cxxflags>-ftrapv
|
||||
<toolset>clang:<cxxflags>-ftrapv
|
||||
# default to all warnings on:
|
||||
<warnings>all
|
||||
# set warnings as errors for those compilers we know we get warning free:
|
||||
<toolset>gcc:<cxxflags>-Wextra
|
||||
<toolset>gcc:<cxxflags>-Wno-uninitialized
|
||||
;
|
||||
|
||||
# Thanks to Steven Watanabe for helping with <nowchar> feature
|
||||
@@ -40,7 +35,7 @@ test-suite conversion
|
||||
[ run lexical_cast_wchars_test.cpp ]
|
||||
[ run lexical_cast_float_types_test.cpp ]
|
||||
[ run lexical_cast_inf_nan_test.cpp ]
|
||||
[ run lexical_cast_containers_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-long-long <toolset>clang:<cxxflags>-Wno-long-long ]
|
||||
[ run lexical_cast_containers_test.cpp ]
|
||||
[ run lexical_cast_empty_input_test.cpp ]
|
||||
[ run lexical_cast_pointers_test.cpp ]
|
||||
[ compile lexical_cast_typedefed_wchar_test.cpp : <toolset>msvc:<nowchar>on ]
|
||||
@@ -60,14 +55,5 @@ test-suite conversion
|
||||
[ run lexical_cast_integral_types_test.cpp ]
|
||||
[ run lexical_cast_stream_detection_test.cpp ]
|
||||
[ run lexical_cast_stream_traits_test.cpp ]
|
||||
[ compile-fail lexical_cast_to_pointer_test.cpp ]
|
||||
[ run lexical_cast_filesystem_test.cpp ../../filesystem/build//boost_filesystem/<link>static ]
|
||||
;
|
||||
|
||||
# Assuring that examples compile and run. Adding sources from `example` directory to the `conversion` test suite.
|
||||
for local p in [ glob ../example/*.cpp ]
|
||||
{
|
||||
conversion += [ run $(p) ] ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ struct foo
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
foo x = implicit_cast<foo>("foobar");
|
||||
(void)x; // warning suppression.
|
||||
BOOST_CHECK(false); // suppressing warning about 'boost::unit_test::{anonymous}::unit_test_log' defined but not used
|
||||
(void)x; // warning suppression.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,6 @@ void testing_std_array_input_conversion();
|
||||
|
||||
using namespace boost;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION)
|
||||
#define BOOST_LC_RUNU16
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION)
|
||||
#define BOOST_LC_RUNU32
|
||||
#endif
|
||||
|
||||
boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
{
|
||||
unit_test::test_suite *suite =
|
||||
@@ -99,7 +91,7 @@ static void testing_template_array_output_on_spec_value(T val)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LC_RUNU16
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
typedef ArrayT<char16_t, 300> u16arr_type;
|
||||
typedef ArrayT<char16_t, 3> u16short_arr_type;
|
||||
std::u16string u16ethalon(u"100");
|
||||
@@ -117,7 +109,7 @@ static void testing_template_array_output_on_spec_value(T val)
|
||||
BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LC_RUNU32
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
typedef ArrayT<char32_t, 300> u32arr_type;
|
||||
typedef ArrayT<char32_t, 3> u32short_arr_type;
|
||||
std::u32string u32ethalon(U"100");
|
||||
@@ -198,7 +190,7 @@ static void testing_template_array_output_on_char_value()
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LC_RUNU16
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
typedef ArrayT<char16_t, 300> u16arr_type;
|
||||
typedef ArrayT<char16_t, 3> u16short_arr_type;
|
||||
std::u16string u16ethalon(u"100");
|
||||
@@ -222,11 +214,10 @@ static void testing_template_array_output_on_char_value()
|
||||
BOOST_CHECK(&res3[0] == u16ethalon);
|
||||
}
|
||||
|
||||
// Some compillers may throw std::bad_alloc here
|
||||
BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), std::exception);
|
||||
BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LC_RUNU32
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
typedef ArrayT<char32_t, 300> u32arr_type;
|
||||
typedef ArrayT<char32_t, 3> u32short_arr_type;
|
||||
std::u32string u32ethalon(U"100");
|
||||
@@ -249,8 +240,7 @@ static void testing_template_array_output_on_char_value()
|
||||
BOOST_CHECK(&res3[0] == u32ethalon);
|
||||
}
|
||||
|
||||
// Some compillers may throw std::bad_alloc here
|
||||
BOOST_CHECK_THROW(lexical_cast<u32short_arr_type>(val), std::exception);
|
||||
BOOST_CHECK_THROW(lexical_cast<u32short_arr_type>(val), boost::bad_lexical_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -338,7 +328,7 @@ static void testing_generic_array_input_conversion()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LC_RUNU16
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
{
|
||||
const ArrayT<const char16_t, 4> var_zero_terminated_const_var_const_char = {{ u'1', u'0', u'0', u'\0'}};
|
||||
BOOST_CHECK(lexical_cast<std::u16string>(var_zero_terminated_const_var_const_char) == u"100");
|
||||
@@ -349,7 +339,7 @@ static void testing_generic_array_input_conversion()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LC_RUNU32
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
{
|
||||
const ArrayT<const char32_t, 4> var_zero_terminated_const_var_const_char = {{ U'1', U'0', U'0', U'\0'}};
|
||||
BOOST_CHECK(lexical_cast<std::u32string>(var_zero_terminated_const_var_const_char) == U"100");
|
||||
|
||||
@@ -32,9 +32,7 @@ void do_test_on_empty_input(T& v)
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(v), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<float>(v), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<double>(v), bad_lexical_cast);
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
BOOST_CHECK_THROW(lexical_cast<long double>(v), bad_lexical_cast);
|
||||
#endif
|
||||
BOOST_CHECK_THROW(lexical_cast<unsigned int>(v), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<unsigned short>(v), bad_lexical_cast);
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// Unit test for boost::lexical_cast.
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Antony Polukhin, 2013.
|
||||
//
|
||||
// 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).
|
||||
//
|
||||
// Test lexical_cast usage with long filesystem::path. Bug 7704.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
void test_filesystem();
|
||||
|
||||
unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
{
|
||||
unit_test::test_suite *suite =
|
||||
BOOST_TEST_SUITE("lexical_cast unit test");
|
||||
suite->add(BOOST_TEST_CASE(&test_filesystem));
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
void test_filesystem()
|
||||
{
|
||||
boost::filesystem::path p;
|
||||
std::string s1 = "aaaaaaaaaaaaaaaaaaaaaaa";
|
||||
p = boost::lexical_cast<boost::filesystem::path>(s1);
|
||||
BOOST_CHECK(!p.empty());
|
||||
BOOST_CHECK_EQUAL(p, s1);
|
||||
p.clear();
|
||||
|
||||
const char ab[] = "aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
p = boost::lexical_cast<boost::filesystem::path>(ab);
|
||||
BOOST_CHECK(!p.empty());
|
||||
BOOST_CHECK_EQUAL(p, ab);
|
||||
}
|
||||
|
||||
@@ -264,11 +264,8 @@ void test_converion_to_float_types()
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("."), bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("-B"), bad_lexical_cast);
|
||||
|
||||
// Following two tests are not valid for C++11 compilers
|
||||
//BOOST_CHECK_THROW(lexical_cast<test_t>("0xB"), bad_lexical_cast);
|
||||
//BOOST_CHECK_THROW(lexical_cast<test_t>("0x0"), bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("0xB"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("0x0"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("--1.0"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0e--1"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0.0"), bad_lexical_cast);
|
||||
@@ -297,16 +294,12 @@ void test_float_typess_for_overflows()
|
||||
BOOST_CHECK_CLOSE_FRACTION(maxvalue, lexical_cast<test_t>(maxvalue), (std::numeric_limits<test_t>::epsilon()));
|
||||
BOOST_CHECK_CLOSE_FRACTION(maxvalue, lexical_cast<test_t>(s_max_value), (std::numeric_limits<test_t>::epsilon()));
|
||||
|
||||
#ifndef _LIBCPP_VERSION
|
||||
// libc++ had a bug in implementation of stream conversions for values that must be represented as infinity.
|
||||
// http://llvm.org/bugs/show_bug.cgi?id=15723#c4
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>(s_max_value+"1"), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>(s_max_value+"9"), bad_lexical_cast);
|
||||
|
||||
// VC9 can fail the following tests on floats and doubles when using stingstream...
|
||||
// VC9 can fail the fllowing tests on floats and doubles when using stingstream...
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("1"+s_max_value), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<test_t>("9"+s_max_value), bad_lexical_cast);
|
||||
#endif
|
||||
|
||||
if ( is_same<test_t,float>::value )
|
||||
{
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <boost/test/floating_point_comparison.hpp>
|
||||
|
||||
#include <boost/type_traits/integral_promotion.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@@ -57,8 +56,6 @@ int const lcast_integral_test_counter=500;
|
||||
|
||||
using namespace boost;
|
||||
|
||||
|
||||
|
||||
void test_conversion_from_to_short();
|
||||
void test_conversion_from_to_ushort();
|
||||
void test_conversion_from_to_int();
|
||||
@@ -71,10 +68,6 @@ void test_conversion_from_to_uintmax_t();
|
||||
void test_conversion_from_to_longlong();
|
||||
void test_conversion_from_to_ulonglong();
|
||||
#endif
|
||||
#ifdef BOOST_HAS_INT128
|
||||
void test_conversion_from_to_int128();
|
||||
void test_conversion_from_to_uint128();
|
||||
#endif
|
||||
void test_integral_conversions_on_min_max();
|
||||
|
||||
|
||||
@@ -94,10 +87,6 @@ unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
#ifdef LCAST_TEST_LONGLONG
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_longlong));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulonglong));
|
||||
#endif
|
||||
#ifdef BOOST_HAS_INT128
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int128));
|
||||
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint128));
|
||||
#endif
|
||||
suite->add(BOOST_TEST_CASE(&test_integral_conversions_on_min_max));
|
||||
|
||||
@@ -383,7 +372,7 @@ struct restore_oldloc
|
||||
};
|
||||
|
||||
template<class T>
|
||||
void test_conversion_from_to_integral_minimal()
|
||||
void test_conversion_from_to_integral()
|
||||
{
|
||||
char const zero = '0';
|
||||
signed char const szero = '0';
|
||||
@@ -399,12 +388,12 @@ void test_conversion_from_to_integral_minimal()
|
||||
test_conversion_from_integral_to_char<T>(wzero);
|
||||
test_conversion_from_char_to_integral<T>(wzero);
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
char16_t const u16zero = u'0';
|
||||
test_conversion_from_integral_to_char<T>(u16zero);
|
||||
test_conversion_from_char_to_integral<T>(u16zero);
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
char32_t const u32zero = u'0';
|
||||
test_conversion_from_integral_to_char<T>(u32zero);
|
||||
test_conversion_from_char_to_integral<T>(u32zero);
|
||||
@@ -440,8 +429,8 @@ void test_conversion_from_to_integral_minimal()
|
||||
// test_conversion_from_to_integral_for_locale
|
||||
|
||||
// Overflow test case from David W. Birdsall
|
||||
std::string must_owerflow_str = (sizeof(T) < 16 ? "160000000000000000000" : "1600000000000000000000000000000000000000");
|
||||
std::string must_owerflow_negative_str = (sizeof(T) < 16 ? "-160000000000000000000" : "-1600000000000000000000000000000000000000");
|
||||
std::string must_owerflow_str = "160000000000000000000";
|
||||
std::string must_owerflow_negative_str = "-160000000000000000000";
|
||||
for (int i = 0; i < 15; ++i) {
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(must_owerflow_str), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(must_owerflow_negative_str), bad_lexical_cast);
|
||||
@@ -449,12 +438,7 @@ void test_conversion_from_to_integral_minimal()
|
||||
must_owerflow_str += '0';
|
||||
must_owerflow_negative_str += '0';
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_conversion_from_to_integral()
|
||||
{
|
||||
test_conversion_from_to_integral_minimal<T>();
|
||||
typedef std::numpunct<char> numpunct;
|
||||
|
||||
restore_oldloc guard;
|
||||
@@ -552,76 +536,19 @@ void test_conversion_from_to_ulonglong()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BOOST_HAS_INT128
|
||||
|
||||
template <bool Specialized, class T>
|
||||
struct test_if_specialized {
|
||||
static void test() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct test_if_specialized<true, T> {
|
||||
static void test() {
|
||||
test_conversion_from_to_integral_minimal<T>();
|
||||
}
|
||||
};
|
||||
|
||||
void test_conversion_from_to_int128()
|
||||
{
|
||||
test_if_specialized<
|
||||
std::numeric_limits<boost::int128_type>::is_specialized,
|
||||
boost::int128_type
|
||||
>::test();
|
||||
}
|
||||
|
||||
void test_conversion_from_to_uint128()
|
||||
{
|
||||
test_if_specialized<
|
||||
std::numeric_limits<boost::int128_type>::is_specialized,
|
||||
boost::uint128_type
|
||||
>::test();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename SignedT>
|
||||
void test_integral_conversions_on_min_max_impl()
|
||||
{
|
||||
typedef SignedT signed_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<signed_t>::type unsigned_t;
|
||||
|
||||
typedef std::numeric_limits<signed_t> s_limits;
|
||||
typedef std::numeric_limits<unsigned_t> uns_limits;
|
||||
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((uns_limits::max)()), (uns_limits::max)());
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((uns_limits::min)()), (uns_limits::min)());
|
||||
|
||||
BOOST_CHECK_EQUAL(lexical_cast<signed_t>((s_limits::max)()), (s_limits::max)());
|
||||
BOOST_CHECK_EQUAL(lexical_cast<signed_t>((uns_limits::min)()), static_cast<signed_t>((uns_limits::min)()));
|
||||
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((s_limits::max)()), static_cast<unsigned_t>((s_limits::max)()));
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned_t>((s_limits::min)()), static_cast<unsigned_t>((s_limits::min)()));
|
||||
}
|
||||
|
||||
void test_integral_conversions_on_min_max()
|
||||
{
|
||||
test_integral_conversions_on_min_max_impl<int>();
|
||||
test_integral_conversions_on_min_max_impl<short>();
|
||||
typedef std::numeric_limits<int> int_limits;
|
||||
typedef std::numeric_limits<unsigned int> uint_limits;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
test_integral_conversions_on_min_max_impl<long int>();
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((uint_limits::max)()), (uint_limits::max)());
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((uint_limits::min)()), (uint_limits::min)());
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
test_integral_conversions_on_min_max_impl<boost::long_long_type>();
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
test_integral_conversions_on_min_max_impl<__int64>();
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_INT128
|
||||
test_integral_conversions_on_min_max_impl<boost::int128_type>();
|
||||
#endif
|
||||
#endif
|
||||
BOOST_CHECK_EQUAL(lexical_cast<int>((int_limits::max)()), (int_limits::max)());
|
||||
BOOST_CHECK_EQUAL(lexical_cast<int>((uint_limits::min)()), static_cast<int>((uint_limits::min)()));
|
||||
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((int_limits::max)()), static_cast<unsigned int>((int_limits::max)()));
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>((int_limits::min)()), static_cast<unsigned int>((int_limits::min)()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,15 +27,6 @@ using namespace boost;
|
||||
#define BOOST_LCAST_NO_WCHAR_T
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION)
|
||||
#define BOOST_LC_RUNU16
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION)
|
||||
#define BOOST_LC_RUNU32
|
||||
#endif
|
||||
|
||||
struct class_with_user_defined_sream_operators {
|
||||
int i;
|
||||
|
||||
@@ -72,10 +63,8 @@ void do_test_iterator_range_impl(const RngT& rng)
|
||||
BOOST_CHECK_EQUAL(lexical_cast<float>(rng.begin(), rng.size()), 1.0f);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<double>(rng), 1.0);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<double>(rng.begin(), rng.size()), 1.0);
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long double>(rng), 1.0L);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long double>(rng.begin(), rng.size()), 1.0L);
|
||||
#endif
|
||||
BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(rng), 1);
|
||||
#endif
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
@@ -130,16 +119,12 @@ void test_it_range_using_char(CharT* one, CharT* eleven)
|
||||
|
||||
BOOST_CHECK_EQUAL(lexical_cast<float>(rng1), 1.0f);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<double>(rng1), 1.0);
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long double>(rng1), 1.0L);
|
||||
#endif
|
||||
BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(rng1), 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(lexical_cast<float>(crng2), 1.0f);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<double>(crng2), 1.0);
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long double>(crng2), 1.0L);
|
||||
#endif
|
||||
BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(crng2), 1);
|
||||
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
@@ -149,7 +134,7 @@ void test_it_range_using_char(CharT* one, CharT* eleven)
|
||||
BOOST_CHECK(lexical_cast<std::wstring>(crng2) == L"1");
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LC_RUNU16) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
|
||||
typedef std::basic_string<char16_t> my_char16_string;
|
||||
BOOST_CHECK(lexical_cast<my_char16_string>(rng1) == u"1");
|
||||
BOOST_CHECK(lexical_cast<my_char16_string>(crng1) == u"1");
|
||||
@@ -157,7 +142,7 @@ void test_it_range_using_char(CharT* one, CharT* eleven)
|
||||
BOOST_CHECK(lexical_cast<my_char16_string>(crng2) == u"1");
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LC_RUNU32) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
|
||||
typedef std::basic_string<char32_t> my_char32_string;
|
||||
BOOST_CHECK(lexical_cast<my_char32_string>(rng1) == U"1");
|
||||
BOOST_CHECK(lexical_cast<my_char32_string>(crng1) == U"1");
|
||||
@@ -209,7 +194,7 @@ void test_wchar_iterator_ranges()
|
||||
|
||||
void test_char16_iterator_ranges()
|
||||
{
|
||||
#if defined(BOOST_LC_RUNU16)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
typedef char16_t test_char_type;
|
||||
test_char_type data1[] = u"1";
|
||||
test_char_type data2[] = u"11";
|
||||
@@ -221,7 +206,7 @@ void test_char16_iterator_ranges()
|
||||
|
||||
void test_char32_iterator_ranges()
|
||||
{
|
||||
#if defined(BOOST_LC_RUNU32)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
||||
typedef char32_t test_char_type;
|
||||
test_char_type data1[] = U"1";
|
||||
test_char_type data2[] = U"11";
|
||||
|
||||
@@ -37,9 +37,7 @@ void do_test_on_empty_input(T& v)
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(v), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<float>(v), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<double>(v), bad_lexical_cast);
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
BOOST_CHECK_THROW(lexical_cast<long double>(v), bad_lexical_cast);
|
||||
#endif
|
||||
BOOST_CHECK_THROW(lexical_cast<unsigned int>(v), bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<unsigned short>(v), bad_lexical_cast);
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// // Unit test for boost::lexical_cast.
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Antony Polukhin, 2013.
|
||||
//
|
||||
// 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).
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/type.hpp>
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
int test_main(int, char*[])
|
||||
{
|
||||
boost::lexical_cast<char*>("Hello");
|
||||
BOOST_CHECK(false); // suppressing warning about 'boost::unit_test::{anonymous}::unit_test_log' defined but not used
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ void test_too_long_number(CharT zero)
|
||||
o << (limits::max)() << zero;
|
||||
s = o.str();
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
s[s.size()-1] += static_cast<CharT>(9); // '0' -> '9'
|
||||
s[s.size()-1] += 9; // '0' -> '9'
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
|
||||
if(limits::is_signed)
|
||||
@@ -43,7 +43,7 @@ void test_too_long_number(CharT zero)
|
||||
o << (limits::min)() << zero;
|
||||
s = o.str();
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
s[s.size()-1] += static_cast<CharT>(9); // '0' -> '9'
|
||||
s[s.size()-1] += 9; // '0' -> '9'
|
||||
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user