Compare commits

..

233 Commits

Author SHA1 Message Date
Fedor Osetrov 35d8af6ce2 fix ci: turn on import std tests, fix libc++ build (#96)
This PR:
- enables tests with `import std` usage in CI
- add all tests to build with cmake_subdir_test (because there was only a subset of tests supported)
- fixes tests build with `libc++`
- disables some tests with wchar_t with 'libc++'
2026-04-24 18:03:48 +03:00
Andrey Semashev 4b0d10a1f3 Remove dependencies on Boost.StaticAssert. (#95)
Boost.StaticAssert has been merged into Boost.Config, so remove
the dependency.
2026-01-26 17:58:24 +03:00
Antony Polukhin 184f7e43f0 Update copyright years 2026-01-04 11:10:09 +03:00
dependabot[bot] 4cc0fa77b4 Bump actions/checkout from 2 to 6 (#94)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-26 22:05:36 +03:00
Antony Polukhin 4d1e18cf4c Add dependabot 2025-12-24 20:21:04 +03:00
Antony Polukhin d57771ecf1 CI fixes (#93) 2025-12-23 20:25:26 +03:00
Antony Polukhin 1b804c7a31 Implement initial version of C++20 module boost.lexical_cast (#84) 2025-12-11 22:17:21 +03:00
Antony Polukhin 275844e651 Fix regression in unsigned short to wstring casting without wchar_t b… (#92)
…uiltin type

Fixes: https://github.com/boostorg/lexical_cast/issues/89
2025-10-16 09:15:33 +03:00
Antony Polukhin 1084d98719 More tests and fixes for floating-point special value conversions to integers and bool (#91)
Fixes: https://github.com/boostorg/lexical_cast/issues/81
2025-10-11 17:36:58 +03:00
Antony Polukhin 7f60da84c3 Run all the tests in CMake, add CMake runs into CI. Drop dependency on Boost.TypeTraits (#90) 2025-10-07 20:25:13 +03:00
Romain Geissler @ Amadeus 8fc8a19931 Reduce dependency on Boost.TypeTraits now that C++ >= 11 is required. (#87)
This allows to workaround the following error when using clang >= 21 on the following code:

```
#include <string>
#include <iostream>
#include "boost/lexical_cast.hpp"

enum SomeEnum
{
    OneValue
};

int main()
{
    std::cout << boost::lexical_cast<std::string>(SomeEnum::OneValue) << std::endl;
}
```

Results in:

```
/app/boost/include/boost/type_traits/is_signed.hpp:37:25: error: in-class initializer for static data member is not a constant expression
   37 |    static const no_cv_t minus_one = (static_cast<no_cv_t>(-1));

... (snapped)

/app/boost/include/boost/type_traits/is_signed.hpp:37:38: note: integer value -1 is outside the valid range of values [0, 1] for the enumeration type 'SomeEnum'
   37 |    static const no_cv_t minus_one = (static_cast<no_cv_t>(-1));
```
2025-10-05 12:14:47 +03:00
Antony Polukhin 4862e296d0 CI fixes (#88) 2025-09-08 09:02:39 +03:00
bmagistro a16040a73c Switch from implicit to explicit type conversion (#85)
Signed-off-by: Ben Magistro <koncept1@gmail.com>
2025-08-22 10:33:58 +03:00
ivanpanch 46ee1c3528 Fix mistakes (#86) 2025-08-22 10:32:30 +03:00
Antony Polukhin 5326b49475 Do not permit implicit conversions to floating point types in decltype(shl_real_type(x, buffer)) substitution (fixes #82) (#83) 2025-05-13 19:32:21 +03:00
Antony Polukhin 1c89e3a56c Update copyright years 2025-01-05 19:41:20 +03:00
René Ferdinand Rivera Morell 71a184d20f Add support for modular build structure. (#78)
This is part of the effort to make the Boost libraries "modular" for build and consumption. See https://lists.boost.org/Archives/boost/2024/01/255704.php and https://github.com/grafikrobot/boost-b2-modular/blob/b2-modular/README.adoc for more information.

This PR depends on the following other PRs being merged to both develop and master branches of the respective repos:

- https://github.com/boostorg/boost/pull/854
2024-08-25 09:57:23 +03:00
Antony Polukhin 7f121f8ce3 Drop Boost.Integer dependency (#79) 2024-08-14 21:15:33 +03:00
Antony Polukhin ff2f0496b0 Fixed conversion of std::basic_string_view and boost::basic_string_view containing one or more \0 characters.
Issue was introduced in 1.85.0
2024-07-07 20:08:13 +03:00
Antony Polukhin 7861401ac4 Always use the boost::core::*printf functions and rely on Boost.Core workarounds (#77) 2024-04-13 09:55:14 +03:00
René Ferdinand Rivera Morell 92e55e842e Add macOS testing. (#75)
Fixes https://github.com/boostorg/lexical_cast/issues/76
---------

Co-authored-by: Antony Polukhin <antoshkka@gmail.com>
2024-04-12 19:12:54 +03:00
Antony Polukhin 02e5821ab3 Do not use custom traits from input/output types as it leads to linktime or runtime errors (fixes #46) (#74) 2024-02-15 11:50:10 +03:00
Antony Polukhin 3433c34b43 Suppress the unsigned-integer-overflow sanitizer warnings and do not recover from the integer sanitizer errors (fixes #45) (#73) 2024-02-15 09:24:44 +03:00
Antony Polukhin 518e28ff79 Dropped dependency on Boost.NumericConversion and Boost.MPL (#72)
Fix some corner cases of floating-point conversions (infinities to infinities of smaller type, fractional numbers to integers)
2024-02-13 10:55:25 +03:00
Antony Polukhin fc5ffb67f8 Simplify the code by removing the explicit copy optimization that is not profitable on modern compilers (#71) 2024-01-28 14:05:12 +03:00
Antony Polukhin 31e0fcde67 Optimizations for std::basic_string_view ans boost::basic_string_view (ref https://github.com/boostorg/lexical_cast/issues/30) (#70) 2024-01-26 20:16:50 +03:00
Antony Polukhin f0862bb60d Significant rewrite of the internal logic to separate optimized and C++ Standard Library IO-based streams (#69)
* C++ Standard Library based streams now constructed in less cases leading to **better performance**;
* less template instantiations and simpler maintainance;
* support for `volatile` input types was dropped, following the C++ Standard Library trend.
2024-01-24 22:35:41 +03:00
Antony Polukhin 4bf37fb6ce Do not reinterpret_cast boost:: and std::array and do not check their sizes (refs #64) (#68) 2024-01-21 14:59:43 +03:00
Antony Polukhin 621b9cf431 Merge branch 'develop' of github.com:boostorg/lexical_cast into develop 2024-01-21 14:49:22 +03:00
Antony Polukhin 92ef7fdeaf Update performance measures 2024-01-21 14:49:07 +03:00
Antony Polukhin fe9ee41f5c Reduce template instantiations count by using template aliases (#67) 2024-01-21 14:23:33 +03:00
Antony Polukhin 90ec909dcf Update copyright years 2024-01-07 13:22:00 +03:00
Antony Polukhin a713e09eab Update copyright years 2024-01-07 13:06:23 +03:00
Antony Polukhin 1ca93a8e27 Drop Boost.Range dependecy (#63) 2023-09-10 16:52:10 +03:00
Antony Polukhin c65a020401 Use BOOST_OVERRIDE to satisfy GCC-4.6 (refs #60) 2023-09-09 15:34:52 +03:00
Antony Polukhin 515e5988b2 Minor changes to satisfy GCC-4.6 (refs #60) 2023-09-03 15:00:21 +03:00
Antony Polukhin af5ce2a5fe Drop C++03 and C++98 support (#62)
Also update tests to not use Boost.Test
2023-09-02 17:42:14 +03:00
Antony Polukhin 844a4d1640 Merge pull request #59 from Romain-Geissler-1A/fix-warning
Fix -Wdeprecated-copy-with-dtor warnings with clang.
2023-08-12 10:58:56 +03:00
Romain Geissler 20db4f8d32 Fix -Wdeprecated-copy-with-dtor warnings with clang.
/data/mwrep/res/osp/Boost/23-0-0-0/include/boost/lexical_cast/bad_lexical_cast.hpp:59:9: error: definition of implicit copy constructor for 'bad_lexical_cast' is deprecated because it has a user-declared destructor
 [-Werror,-Wdeprecated-copy-with-dtor]
        ~bad_lexical_cast() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE = default;
2023-06-02 13:20:24 +00:00
Antony Polukhin 35941953d1 update CI setup (1) 2023-05-21 12:42:50 +03:00
Antony Polukhin 4850d71673 update CI setup 2023-05-21 09:55:36 +03:00
Antony Polukhin 42518efe39 add C++03 deprecation warnings 2023-05-14 20:02:49 +03:00
Antony Polukhin 32e9b6d2a0 Update copyright years 2023-01-19 10:00:15 +03:00
Antony Polukhin 345e1549b4 Merge pull request #56 from mborland/develop
Fix for sprintf deprecation message
2023-01-17 15:25:15 +03:00
Matt Borland b7fd03b19d Replace sprintf with Boost.Core snprintf 2022-12-08 18:32:56 -08:00
Antony Polukhin 81148c50f7 Revert "Merge pull request #51 from biodranik/sprintf-warning-fix"
This reverts commit e67d186e0d, reversing
changes made to a9f2961159.
2022-09-03 07:57:49 +03:00
Antony Polukhin cfd466eacd Remove MacOS run from CI as it almost always hits CI limits 2022-09-02 19:17:08 +03:00
Antony Polukhin e49ad59570 Merge pull request #54 from boostorg/antoshkka/update-ci-win2022
Update CI
2022-09-02 17:34:52 +03:00
Antony Polukhin d54f16a0af update ci 2022-09-02 16:21:11 +03:00
Antony Polukhin 403d79edc7 fix compilation for casting volatile arithmetic types
Fixes #50
2022-09-01 13:53:46 +03:00
Antony Polukhin 9e287d6624 Merge pull request #53 from fanquake/core_noncopyable
refactor: use core/noncopyable over boost/noncopyable
2022-09-01 11:45:32 +03:00
Antony Polukhin e67d186e0d Merge pull request #51 from biodranik/sprintf-warning-fix
Replaced sprintf with snprintf to silent the security deprecated warning in Xcode 14
2022-08-31 21:27:53 +03:00
fanquake b302988907 refactor: use core/noncopyable over boost/noncopyable
The later is deprecated:
```cpp
// The header file at this path is deprecated;
// use boost/core/noncopyable.hpp instead.

include <boost/core/noncopyable.hpp>
```
2022-08-24 12:34:18 +01:00
Alexander Borsuk 3f0026eec0 Replaced sprintf with snprintf to silent the security deprecated warning in Xcode 14 2022-06-10 23:51:41 +02:00
Antony Polukhin a9f2961159 update copyright years 2022-01-30 13:03:00 +03:00
Antony Polukhin 00197e2f97 update CI setups: remove outdated and broken setups, avoid using TravisCI 2021-09-11 14:05:01 +03:00
Antony Polukhin a8e2a9458b Remove TravisCI runs 2021-09-11 12:43:43 +03:00
Antony Polukhin 934858fbdc do not gather coverage in GithubActions CI runs 2021-05-04 19:27:57 +03:00
Antony Polukhin b7a3039fa1 remove obsolete link from Readme 2021-05-04 11:29:13 +03:00
Antony Polukhin d47bbfc79b add GithubActions CI step to set up locaes 2021-05-04 11:28:57 +03:00
Antony Polukhin 650958a9da remove unused Drone CI 2021-05-04 10:11:42 +03:00
Antony Polukhin 2b37bce120 test the library with different locales in GithubActions CI 2021-05-04 10:11:07 +03:00
Antony Polukhin 17606ef8a6 update coverage logic in TravisCI script 2021-05-04 10:07:06 +03:00
Antony Polukhin f071fb83cf typo fix 2021-05-03 19:10:31 +03:00
Antony Polukhin 28a3b0e6f8 add new badges to Readme and use HTTPS links 2021-05-03 17:37:51 +03:00
Antony Polukhin ce73b6adfc do not test 128bit integral types on MacOs because of the Apple Clang issue 2021-05-03 17:36:53 +03:00
Antony Polukhin 7a4f79ed52 fix UB: assignemnt to an int of a floating point value that is out of representable range for int 2021-05-02 20:26:45 +03:00
Antony Polukhin 1f94291f4e do not run sanitizers on MAcOs because the CI run hangs 2021-05-02 20:22:51 +03:00
Antony Polukhin 88f5967805 fix tests compilation on C++20 (wide char operator<< overloads are deleted) 2021-05-02 17:38:32 +03:00
Antony Polukhin eb3bda9563 fixes for wide char tests 2021-05-02 13:13:30 +03:00
Antony Polukhin c95b9adbab fixes for CI runs 2021-04-26 20:56:15 +03:00
Antony Polukhin 945c095a4b do not use Boost.Math in tests 2021-04-26 10:44:22 +03:00
Antony Polukhin f0e2fa3dd3 make tests work in C++03 modes 2021-04-26 10:12:28 +03:00
Antony Polukhin 6e868f964d copy GithubActions from Boost.Conversion 2021-04-25 21:20:43 +03:00
Antony Polukhin f1453fb675 Merge pull request #44 from sdarwin/githubactions
GitHub Actions config
2021-04-18 14:10:46 +03:00
Peter Dimov 90e8812d59 Update CMakeLists.txt 2021-03-19 01:11:06 +02:00
sdarwin c797209351 Add GitHub Actions config [ci skip] 2021-03-04 18:22:53 +00:00
Antony Polukhin e6e9970234 Merge pull request #42 from sdarwin/drone
Drone config
2021-01-27 10:29:03 +03:00
Antony Polukhin 8a98d28ea0 Merge pull request #41 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-27 10:25:06 +03:00
sdarwin 937024f7a1 add drone config [ci skip] 2021-01-26 15:29:42 +00:00
Edward Diener 7803687303 [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-20 13:10:40 -05:00
Antony Polukhin 0d920e632f disable long double tests on mingw64 because of the issues with precision 2021-01-07 18:37:24 +03:00
Antony Polukhin 2993c99813 disable long double tests on MinGW because of the issues with precision 2021-01-06 21:25:31 +03:00
Antony Polukhin cb585ca6cb disable long double tests on mingw64 because of the issues with precision 2021-01-06 12:04:51 +03:00
Antony Polukhin 29ddb588b2 add missing header 2021-01-05 17:21:20 +03:00
Antony Polukhin 9c38b33f65 remove trailing whitespace 2021-01-05 12:25:39 +03:00
Antony Polukhin 745b4dc4ac workaround b2 issues with long filenames (again) 2021-01-05 12:21:37 +03:00
Antony Polukhin e677e3fc89 workaround b2 issues with long filenames 2021-01-04 22:10:48 +03:00
Antony Polukhin bd5843e9be fix coverage reports 2021-01-04 22:04:38 +03:00
Antony Polukhin 3dfb2a31ec Make tests for typedefed wchar_t more reliable 2021-01-04 18:41:45 +03:00
Antony Polukhin a96a262fdc Modern Appveyor file 2021-01-04 11:11:24 +03:00
Antony Polukhin 08bce247f0 update copyright years 2021-01-03 14:20:39 +03:00
Antony Polukhin b193e87c74 Merge pull request #38 from sdarwin/lcov
update lcov in .travis.yml
2021-01-02 17:07:16 +03:00
Antony Polukhin c025415629 Merge pull request #39 from boostorg/pr/use-core-cmath
Use boost/core/cmath.hpp
2021-01-02 17:04:45 +03:00
Peter Dimov d53e32372b Use boost/core/cmath.hpp 2020-12-27 05:57:13 +02:00
sdarwin 689bf3920d update lcov in .travis.yml 2020-12-24 19:25:31 +00:00
Antony Polukhin 95ca35890a Merge pull request #37 from boostorg/pr/no-boost-math
Remove use of Boost.Math, to avoid the dependency cycle
2020-12-15 17:42:22 +03:00
Peter Dimov 7ea0caa72c Use std:: <cmath> functions, except on msvc-11.0 and below 2020-11-23 05:20:28 +02:00
Peter Dimov 731ea46ba8 Fix signbit failures 2020-11-23 03:37:16 +02:00
Peter Dimov 8167506bb1 Remove using namespace std directives 2020-11-23 02:26:52 +02:00
Peter Dimov 873b34b610 Add emulation functions for msvc-11.0 and below 2020-11-23 01:03:10 +02:00
Peter Dimov b181fa495e Remove use of Boost.Math, to avoid the dependency cycle 2020-11-22 22:23:32 +02:00
Antony Polukhin bc87ec7942 Add another link 2020-08-24 10:47:43 +03:00
Antony Polukhin 9fdbf5ce67 Merge pull request #36 from vgvassilev/patch-1
Add missing include
2020-07-23 15:33:35 +03:00
Vassil Vassilev b5185ac5bf Add missing include
Allow header file to be built standalone, in a clang C++ modules context.
2020-07-17 01:37:10 +03:00
Antony Polukhin 1170484871 CI fix 2020-06-02 16:11:19 +03:00
Antony Polukhin 222ae3cbaa Merge pull request #35 from EugeneZelenko/use-boost-override
Use BOOST_OVERRIDE
2020-05-28 17:48:18 +03:00
Eugene Zelenko 2b6feb3282 Use BOOST_OVERRIDE to fix Clang-tidy modernize-use-override warnings.
Alphabetical order of STL headers.
2020-05-25 18:43:25 -07:00
Antony Polukhin 4280c94a1a Move Escape struct into a separate header and rename it to avoid collisions with Windows function name 2020-05-05 19:50:33 +03:00
Antony Polukhin fdca5084fe Merge branch 'develop' of github.com:eldiener/lexical_cast into develop 2020-05-05 19:31:52 +03:00
Antony Polukhin e89e81e568 Apply BOOST_OVERRIDE to bad_lexical_cast::what() (fixes #34) 2020-05-03 13:26:15 +03:00
Edward Diener e6c10ba7a2 Merge branch 'develop' of https://github.com/eldiener/lexical_cast into cppbuilder 2020-04-08 21:02:21 -04:00
Antony Polukhin 012f87e21b CI fixes 2020-04-06 18:46:05 +03:00
Edward Diener 8ffb03760f Avoid name conflict with Windows GDI function also called 'Escape' by referring specifically to struct type. 2020-04-04 04:50:01 -04:00
Edward Diener ddf96e0307 Fixed type as struct to avoid conflict with Windows function name. Specified FILE as std::FILE when cstdio is being included. 2020-04-03 20:48:24 -04:00
Edward Diener e81c6f02b4 Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-31 11:28:10 -04:00
Antony Polukhin 207d9845da update copyright year 2020-01-18 14:08:35 +03:00
Antony Polukhin 09e909ba2e Merge pull request #32 from Kojoley/no-typeinfo-in-std-namespace
Deal with `typeinfo` missing in `std` namespace
2019-12-03 07:57:54 +03:00
Nikita Kniazev b9a5808c00 No typeinfo in std namespace
Fixes https://svn.boost.org/trac10/ticket/4115 without relying on Boost.Config
to inject `::typeinfo` into `std` namespace.
2019-12-02 22:43:27 +03:00
Antony Polukhin 4b6cb2843d Merge pull request #31 from Kojoley/run-tests-with-truly-disabled-exceptions
Run test with truly disabled exceptions
2019-12-02 22:42:35 +03:00
Nikita Kniazev 87707d7fb9 Run test with truly disabled exceptions 2019-12-02 20:59:34 +03:00
Antony Polukhin c9b55cac39 Adjust coverage counting in CI 2019-11-16 09:09:18 +03:00
Antony Polukhin 1ae6b79699 CI fixes (2) 2019-11-15 20:42:19 +03:00
Antony Polukhin 813deb7cf2 CI workarounds 2019-11-15 19:16:58 +03:00
Antony Polukhin 7bcebb0bc2 inspect tool fixes 2019-11-15 13:35:57 +03:00
Antony Polukhin b79d03acb9 Update .travis.yml 2019-11-15 09:45:21 +03:00
Antony Polukhin b307e84693 CI fixes 2019-11-14 12:34:49 +03:00
Antony Polukhin 87ce721928 More tests and comments for fs::path conversions (refs #25) 2019-06-23 13:12:00 +03:00
Antony Polukhin 45eef91428 Tests for filesystem::path (refs #25) 2019-06-23 12:48:19 +03:00
Antony Polukhin f3d9f0d4cb Update README.md 2019-06-22 11:37:39 +03:00
Antony Polukhin 3786d41da0 Use lightweight testing in no_exception test 2019-06-22 11:30:18 +03:00
Antony Polukhin 8ce82bd55d Fix build 2019-06-21 23:46:36 +03:00
Antony Polukhin 0d35b567fa Fix links to CI 2019-06-21 23:44:28 +03:00
Antony Polukhin 55ddce9200 Fix the no_exceptions test (refs #28) 2019-06-21 23:22:10 +03:00
Antony Polukhin 4df6a9e96c Merge pull request #26 from samcday/basic-cmake
Add basic CMake build system
2019-04-30 09:31:05 +03:00
Sam Day 0a6921819b Add basic CMake support. 2019-04-28 17:49:06 +02:00
Antony Polukhin 8f5bcd0f5e Update copyright years 2019-01-30 23:26:35 +03:00
Antony Polukhin 5cd9771337 Drop dependency on MPL 2018-10-21 00:30:14 +03:00
Antony Polukhin 6cfa994a45 Fix the sign-conversion warnings 2018-09-25 11:48:22 +03:00
Antony Polukhin 251a3972b0 fix b2 warnings 2018-09-22 22:15:04 +03:00
Antony Polukhin 5bfe6672d4 Fix compilation 2018-04-27 11:25:23 +03:00
Antony Polukhin fb017f8b82 Fixes for clang-tidy warnings 2018-04-27 11:03:10 +03:00
Antony Polukhin 398b451036 Do not use variable names ending on underscore for input variables and simpler warning suppression for generic_stringize example 2017-09-26 22:29:11 +03:00
Antony Polukhin a0b5e8415d Do not use variable names ending on underscore for input variables and simpler warning suppression for generic_stringize example 2017-09-26 22:28:08 +03:00
Daniela Engert 34318690dd Fix compiler warning about narrowing.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-06-08 17:45:01 +02:00
Daniela Engert a05afbe012 fix compiler warnings about name hiding
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-06-08 17:45:01 +02:00
Antony Polukhin 4b423ae2c6 Fixed formatting in README and updated the AppveyorCI script 2017-05-20 12:34:20 +03:00
Antony Polukhin c519e65050 Fix warning suppression 2017-02-24 08:52:09 +03:00
Antony Polukhin 5787c093cc Disable MinGW runs in CI 2017-02-24 08:17:32 +03:00
Antony Polukhin bc77307ea0 Run MinGW tests too (thanks to Pavel Filinov for showing that appveyor apability) 2017-02-23 21:24:04 +03:00
Antony Polukhin ac4ab33e2f Remove unsupported on GCC warning suppression 2017-02-22 10:24:13 +03:00
Antony Polukhin c2f055ee5d Suppress more warnings and disable the -Wno-uninitialized suppression 2017-02-19 12:32:20 +03:00
Antony Polukhin c759ce3141 Fix more MSVC warnings 2017-02-15 17:32:34 +03:00
Antony Polukhin c8ce236302 Added a comment on warning suppression and slightly change one of the suppressions 2017-02-14 21:04:52 +03:00
Antony Polukhin f853b3760f Merge commit '804f6c24f081f78996e82502e765fecf87667856' into develop
Suppressing MSVC warning in test
2017-02-14 20:54:52 +03:00
Antony Polukhin d53933cd3b Fix warning reported in trac ticket 11842 2017-01-20 22:15:42 +03:00
Daniela Engert 804f6c24f0 Silence msvc compiler warnings about constant conditional expressions.
Signed-off-by: Daniela Engert <dani@ngrt.de>
(cherry picked from commit 9b7df2d7839240f9496aa6cc323de6bf7e688062)
2016-12-30 10:19:00 +01:00
Daniela Engert 608c8fb750 remove or silence compiler warnings about the use of unsafe library function, and unused variables
Signed-off-by: Daniela Engert <dani@ngrt.de>
(cherry picked from commit d09b5934fd7e0a8374a29536bc6df848beac538a)
2016-12-30 10:19:00 +01:00
Antony Polukhin 26681167c3 Ignore Boost.Filesystem files in CI coverage reports 2016-12-04 10:41:15 +03:00
Antony Polukhin 56e9b21ccc Update CI script version 2016-12-04 02:38:51 +03:00
Antony Polukhin dc97de95f7 Fix coverage info gathering in travisCI script for GCC-6 2016-12-04 02:26:56 +03:00
Antony Polukhin 0113689598 Disable char16_t and char32_t tests for MSVC 2016-11-18 23:49:33 +03:00
Antony Polukhin f0a25b43a1 CI bugfix 2016-11-18 22:17:58 +03:00
Antony Polukhin eefee8513d Update CI scripts and tests 2016-11-18 22:11:41 +03:00
Antony Polukhin cf5b7a70cd Fix github issue #21: UB during conversion using user-provides istream operators. Minor code cleanup 2016-11-18 22:00:45 +03:00
Rene Rivera d98ac08f0a Add, and update, documentation build targets. 2016-10-07 23:07:34 -05:00
Antony Polukhin c48e35f363 Regenerated perf tables 2016-09-05 21:39:11 +03:00
Antony Polukhin 0bfc6c2dce Fix incorrect static assertion (trac 11759) 2016-06-06 07:30:46 +03:00
Antony Polukhin 87afdf53c0 Merge pull request #19 from plopresti/gcc_warnings
Silence "may be used uninitialized" warnings from GCC 4.9.2 and others (again).
2016-04-01 22:12:29 +03:00
Patrick J. LoPresti e6adec1411 Silence "may be used uninitialized" warnings from GCC 4.9.2 and others.
Avoid boost::value_initialized<> since it does not work on move-only types.
2016-04-01 10:16:42 -07:00
Antony Polukhin ed798b6440 Merge pull request #16 from jzmaddock/patch-2
Remove use of deprecated header.
2016-03-13 10:35:52 +03:00
jzmaddock fd5fb23e62 Remove use of deprecated header.
This header appears to be unused in any case?
2016-03-12 18:33:54 +00:00
Antony Polukhin 38507ff9b1 Another workaround for Sun Studio from dariomt 2016-01-26 13:11:49 +03:00
Antony Polukhin abf7441dd4 Fix Sun Studio related issue, reported by dariomt via boost-users list 2016-01-17 13:35:12 +03:00
Antony Polukhin 038e80ec7a Attempt to supress warnings reported in track #11570 and #4946 2015-09-25 20:44:13 +03:00
Antony Polukhin 424320d9a1 Revert " Eliminate GCC 4.9.2 warning "Variable 'result' may be used uninitialized""
This reverts commit bdc355759e.
2015-09-25 20:35:11 +03:00
Antony Polukhin 0f2ce4ba7e Juan Alday's fix for track Ticket #11669: lexical_cast crashes on certain conditions for floating point types 2015-09-25 20:29:05 +03:00
Antony Polukhin 55b1b832bf Merge pull request #15 from eldiener/develop
Change to use operators rather than mpl equivalents for constant boolean...
2015-04-27 22:10:48 +04:00
Edward Diener c13adb683e Change to use operators rather than mpl equivalents for constant boolean values, in the replacements eliminating dependency on deprecated type_traits headers. 2015-04-27 12:59:35 -04:00
Antony Polukhin b8c8c32691 Merge pull request #11 from eldiener/develop
Remove use of ice_xxx.hpp headers
2015-04-16 10:42:13 +04:00
Antony Polukhin 7b581f6e00 Merge branch 'master' into develop (fixup things after accidental merge of pull request to master branch directly) 2015-04-15 10:12:47 +03:00
Antony Polukhin bdc355759e Eliminate GCC 4.9.2 warning "Variable 'result' may be used uninitialized"
This is a patch from https://github.com/plopresti
2015-04-15 10:09:20 +03:00
Antony Polukhin e1754bec99 Merge pull request #13 from boostorg/revert-12-gcc_warnings
Revert "Eliminate GCC 4.9.2 warning "'result' may be used uninitialized"...
2015-04-15 11:03:35 +04:00
Antony Polukhin ecca6da673 Revert "Eliminate GCC 4.9.2 warning "'result' may be used uninitialized"" 2015-04-15 10:01:30 +03:00
Antony Polukhin 3f923ea0f3 Merge pull request #12 from plopresti/gcc_warnings
Eliminate GCC 4.9.2 warning "'result' may be used uninitialized"
2015-04-15 11:01:13 +04:00
Patrick J. LoPresti 5229fa9d53 Eliminate GCC 4.9.2 warning "Variable 'result' may be used uninitialized" 2015-04-03 16:16:02 -07:00
Edward Diener 4db0362f61 Remove use of ice_xxx.hpp headers 2015-03-30 23:38:44 -04:00
Antony Polukhin 1be164691b Merge pull request #10 from akumta/patch-1
Update small_examples.cpp
2015-03-10 12:46:01 +04:00
akumta 4589828c1d Update small_examples.cpp 2015-03-09 14:17:16 -07:00
Antony Polukhin 73e23b9dfc Fix invalid definition of my_allocator (refs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64913) 2015-03-02 14:26:23 +03:00
Antony Polukhin 1405db211f Merge branch 'alexhenrie-master' into develop 2015-01-31 18:18:04 +03:00
Alex Henrie 0ddd80e8bf Correct spelling of "suppress" 2015-01-30 15:29:15 -07:00
Antony Polukhin ee077da230 Merge pull request #8 from jzmaddock/patch-1
Update converter_numeric.hpp
2015-01-22 13:04:20 +04:00
jzmaddock d8c4e4412a Update converter_numeric.hpp
This header uses is_float.hpp without including the needed header - detected while testing new type traits version.
2015-01-21 19:10:13 +00:00
Antony Polukhin 1e5f727067 Attempt to unificate travisci script between different libs: final polishing 2014-12-18 22:32:28 +03:00
Antony Polukhin 58c082c586 Attempt to unificate script between different libs: attempt to fix IGNORE_COVERAGE 2014-12-18 19:11:56 +03:00
Antony Polukhin 55a00ba6e3 Another update to travisci script (attempt to unificate script between different libs) 2014-12-18 18:54:34 +03:00
Antony Polukhin b6d797533d Travis and Coveralls integration 2014-12-18 17:45:42 +03:00
Antony Polukhin c4fcfc33af Remove naive float converter and use std::streams instead. This resolves issues noted at track: #5660, #6975, #10639 2014-10-14 16:05:31 +04:00
Daniel James c0848bd594 Fix the documentation location.
Just deleting the field as the default is fine.
2014-09-01 19:04:38 +01:00
Antony Polukhin 224e8b16bc Move low level float converter into a separate file 2014-08-22 16:00:58 +04:00
Antony Polukhin bda157d1cc Move all the fixed lexical streamers into a separate file 2014-08-22 15:05:22 +04:00
Antony Polukhin ebb4a99325 Lexical converter implementation moved to separate file in the detail folder. minor fixes and improvements 2014-08-22 14:09:02 +04:00
Antony Polukhin 3ac1859235 Nothrow nuneric converter moved to a separate file 2014-08-22 13:50:47 +04:00
Antony Polukhin 5323c2b08a Merge branch 'patch-1' into header_separation
Conflicts:
	include/boost/lexical_cast.hpp
2014-08-22 12:51:25 +04:00
Zoey Greer fb8cdc9dce Corrected spelling of "iteration" 2014-08-21 15:50:44 -04:00
Antony Polukhin 2e68c09658 Refactoring of lexical_cast: splitting into multiple headers 2 2014-08-11 20:06:57 +04:00
Antony Polukhin cde03e0a1d Refactoring of lexical_cast: splitting into multiple headers #1 2014-08-11 19:13:55 +04:00
Antony Polukhin d38f72c2c1 Merge branch 'master' into develop 2014-08-11 13:14:56 +04:00
Antony Polukhin 2cabcbdf0f Merge pull request #5 from ibmsoe/lexical_cast_fix
Replace std::numeric_limits<T>::epsilon calls with boost::math::tools::epsilon<T>
2014-07-04 11:01:46 +04:00
Harris Munir 699d31ce71 Replace numeric_limits epsilon function with boost::math epsilon function 2014-07-03 09:26:00 -05:00
Antony Polukhin 947420642e Merge pull request #2 from danieljames/fix-description
Remove author name from description.
2014-06-30 15:59:47 +04:00
Daniel James 66953f6fc2 Remove author name from description.
My mistake, it's in the authors field so it will end up being listed
twice if it's also in the description.
2014-06-30 12:27:00 +01:00
Antony Polukhin 60faed22fa Merge branch 'develop' 2014-06-10 13:38:17 +04:00
Antony Polukhin d77165c1bd Removed the polymorphic casts and implicit_cast 2014-06-09 12:44:31 +04:00
Antony Polukhin e459cd6a06 Merge pull request #1 from danieljames/metadata
Add metadata file
2014-06-09 11:50:03 +04:00
Daniel James 653f96e129 Add metadata file 2014-06-08 23:46:05 +01:00
Antony Polukhin e3e4d3836a Merge branch 'develop' 2014-03-14 23:47:58 +04:00
Antony Polukhin d1a51b897d Fix conversions to bool with leading zeros (refs #9659) 2014-03-05 14:48:21 +04:00
Antony Polukhin 9e6aa219d3 Merge branch 'develop' 2014-03-04 16:37:10 +04:00
Antony Polukhin 1e65265b8f Minor fixes in tests 2014-02-11 12:13:17 +04:00
Antony Polukhin 90b4286753 Because of the errors in MSVC with fowarding and static_casting arrays it was decided to drop minor optimization and do not perfect forward source types in try_lexical_convert 2014-02-06 11:22:40 +04:00
Antony Polukhin 5a757dcece Docs updated and minor fixes for MSVC2013 2014-02-04 13:13:33 +04:00
Antony Polukhin 36bc5aea44 Attempt to fix access violation during forwarding of arrays on MSVC 2014-02-03 16:22:27 +04:00
Antony Polukhin ac7da550b4 Attempt to revert incorrectly merged branches 2014-01-19 11:53:50 +04:00
Antony Polukhin e8954f3868 Added docs for try_lexical_convert 2014-01-04 20:26:19 +04:00
Antony Polukhin 1707131ac3 Added some tests for try_lexical_convert and fixed some issues. 2014-01-01 21:47:09 +04:00
Antony Polukhin 2f2c1a3443 Create first merge point for Git 2013-12-30 18:03:42 +04:00
Antony Polukhin 91b77e7373 Do forward input streamable parameter during lexical input streaming. 2013-12-16 19:05:43 +04:00
Antony Polukhin e3dec04dd5 Applied improvements from [boost] [conversion] try_lexical_cast discussion: function is called try_lexical_convert and now uses perfect forwardings when possible. 2013-12-16 18:47:41 +04:00
Antony Polukhin b40bc02f94 try_lexical_cast is now implemented in optimal way 2013-12-13 13:52:18 +04:00
Antony Polukhin 07082420b3 Sketch implementaion of try_lexical_cast 2013-12-12 18:41:51 +04:00
Antony Polukhin 57e4e87e3b Put tests to test folder, remove unrequired files, fix permissions 2013-12-09 11:27:27 +04:00
87 changed files with 7479 additions and 7103 deletions
+11
View File
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
+260
View File
@@ -0,0 +1,260 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-14 # Do not remove! It is the only toolset that tests CMake tests down below
cxxstd: "03,11,14,17,20"
os: ubuntu-24.04
compiler: g++-14
- toolset: gcc-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-12"
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.8"
- toolset: gcc-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
- toolset: clang
cxxstd: "11,14,17,20"
os: macos-latest
- toolset: clang-19
cxxstd: "20,23"
os: ubuntu-24.04
compiler: clang++-19
install: clang-19 llvm-19 libclang-rt-19-dev libc++-19-dev libc++abi-19-dev clang-tools-19
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init --depth 10 --jobs 2 tools/boostdep tools/inspect libs/filesystem
python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 3" filesystem
rm -rf libs/$LIBRARY/*
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
./bootstrap.sh
./b2 -j4 variant=debug tools/inspect
- name: Run modules tests without 'import std;'
if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/lexical_cast
cmake -S test/cmake_subdir_test -B build_module \
-GNinja \
-DBUILD_TESTING=1 \
-DBOOST_USE_MODULES=1 \
-DCMAKE_CXX_COMPILER=clang++-19 \
-DCMAKE_C_COMPILER=clang-19
cmake --build build_module
ctest --test-dir build_module -V --no-tests=error
rm -rf build_module
- name: Run modules tests
if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/lexical_cast
cmake -S test/cmake_subdir_test -B build_module \
-GNinja \
-DBUILD_TESTING=1 \
-DBOOST_USE_MODULES=1 \
-DCMAKE_CXX_COMPILER=clang++-19 \
-DCMAKE_C_COMPILER=clang-19 \
-DCMAKE_CXX_FLAGS=-stdlib=libc++ \
-DCMAKE_CXX_STANDARD=23 \
-DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 \
-DCMAKE_CXX_MODULE_STD=ON
cmake --build build_module
ctest --test-dir build_module -V --no-tests=error
rm -rf build_module
- name: Run CMake tests
if: ${{matrix.toolset == 'gcc-14' || matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/
cmake -S . -B __build \
-DBUILD_TESTING=1 \
-DBOOST_INCLUDE_LIBRARIES=lexical_cast \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_C_COMPILER=${{matrix.toolset}}
cmake --build __build --target tests
ctest --test-dir __build --output-on-failure --no-tests=error
rm -rf __build
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
dist/bin/inspect libs/$LIBRARY
- name: Prepare coverage data
if: matrix.gcov_tool
run: |
mkdir -p $GITHUB_WORKSPACE/coveralls
echo -e "#!/bin/bash\nexec ${{matrix.gcov_tool}} \"\$@\"" > $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
chmod +x $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
wget https://github.com/linux-test-project/lcov/archive/v1.16.zip
unzip v1.16.zip
LCOV="`pwd`/lcov-1.16/bin/lcov --gcov-tool $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh"
echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
cd ../boost-root
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
echo $OTHER_LIBS
eval "$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info $OTHER_LIBS -o $GITHUB_WORKSPACE/coveralls/coverage.info"
- name: Coveralls
uses: coverallsapp/github-action@master
if: matrix.gcov_tool
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coveralls/coverage.info
parallel: true
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: msvc
cxxstd: "14,17,latest"
addrmd: 64
os: windows-2025
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep libs/test
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
- name: Run CMake tests
if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/
mkdir __build
cd __build
cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=lexical_cast -G Ninja ..
cmake --build . --target tests --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Run modules tests
if: false
#if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/libs/lexical_cast
rm -rf build_module
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DCMAKE_CXX_STANDARD=23 -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 -G Ninja ../test/cmake_subdir_test/
cmake --build .
ctest --no-tests=error -V
- name: Run modules tests without 'import std;'
if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/libs/lexical_cast
rm -rf build_module
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DCMAKE_CXX_STANDARD=20 -G Ninja ../test/cmake_subdir_test/
cmake --build .
ctest --no-tests=error -V
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
finish:
if: false
needs: posix
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.github_token }}
parallel-finished: true
+46
View File
@@ -0,0 +1,46 @@
# Generated by `boostdep --cmake lexical_cast`
# Copyright 2020 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...4.0)
project(boost_lexical_cast VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
if (BOOST_USE_MODULES)
add_library(boost_lexical_cast)
target_sources(boost_lexical_cast PUBLIC
FILE_SET modules_public TYPE CXX_MODULES FILES
${CMAKE_CURRENT_LIST_DIR}/modules/boost_lexical_cast.cppm
)
target_compile_features(boost_lexical_cast PUBLIC cxx_std_20)
target_compile_definitions(boost_lexical_cast PUBLIC BOOST_USE_MODULES)
if (CMAKE_CXX_COMPILER_IMPORT_STD)
target_compile_definitions(boost_lexical_cast PRIVATE BOOST_LEXICAL_CAST_USE_STD_MODULE)
message(STATUS "Using `import std;`")
else()
message(STATUS "`import std;` is not available")
endif()
set(__scope PUBLIC)
else()
add_library(boost_lexical_cast INTERFACE)
set(__scope INTERFACE)
endif()
target_include_directories(boost_lexical_cast ${__scope} include)
target_link_libraries(boost_lexical_cast
${__scope}
Boost::config
Boost::container
Boost::core
Boost::throw_exception
)
add_library(Boost::lexical_cast ALIAS boost_lexical_cast)
if(BUILD_TESTING)
add_subdirectory(test)
endif()
+15
View File
@@ -0,0 +1,15 @@
# [Boost.LexicalCast](https://boost.org/libs/lexical_cast)
Boost.LexicalCast is one of the [Boost C++ Libraries](https://github.com/boostorg). This library is meant for general literal text conversions, such as an int represented a string, or vice-versa.
### Test results
@ | Build | Tests coverage | More info
----------------|-------------- | -------------- |-----------
Develop branch: | [![CI](https://github.com/boostorg/lexical_cast/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/lexical_cast/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/mwwanh1bpsnuv38h/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/lexical-cast/branch/develop) | [![Coverage Status](https://coveralls.io/repos/boostorg/lexical_cast/badge.png?branch=develop)](https://coveralls.io/r/boostorg/lexical_cast?branch=develop) | [details...](https://www.boost.org/development/tests/develop/developer/lexical_cast.html)
Master branch: | [![CI](https://github.com/boostorg/lexical_cast/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/lexical_cast/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/mwwanh1bpsnuv38h/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/lexical-cast/branch/master) | [![Coverage Status](https://coveralls.io/repos/boostorg/lexical_cast/badge.png?branch=master)](https://coveralls.io/r/boostorg/lexical_cast?branch=master) | [details...](https://www.boost.org/development/tests/master/developer/lexical_cast.html)
[Latest developer documentation](https://www.boost.org/doc/libs/develop/doc/html/boost_lexical_cast.html)
### License
Distributed under the [Boost Software License, Version 1.0](https://boost.org/LICENSE_1_0.txt).
+26
View File
@@ -0,0 +1,26 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/config//boost_config
/boost/container//boost_container
/boost/core//boost_core
/boost/throw_exception//boost_throw_exception ;
project /boost/lexical_cast
: common-requirements
<include>include
;
explicit
[ alias boost_lexical_cast : : : : <library>$(boost_dependencies) ]
[ alias all : boost_lexical_cast test ]
;
call-if : boost-library lexical_cast
;
-146
View File
@@ -1,146 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"Microsoft FrontPage 5.0">
<meta http-equiv="Content-Type" content=
"text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<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">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align=
"middle" width="277" height="86">Header <a href=
"../../boost/cast.hpp">boost/cast.hpp</a></h1>
<h2><a name="Cast Functions">Cast Functions</a></h2>
<p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides <code>
<a href="#Polymorphic_cast">polymorphic_cast</a> and</code> <a href=
"#Polymorphic_cast"><code>polymorphic_downcast</code></a> function templates designed to
complement the C++ built-in casts.</p>
<p>The program <a href="cast_test.cpp">cast_test.cpp</a> can be used to
verify these function templates work as expected.</p>
<h3><a name="Polymorphic_cast">Polymorphic casts</a></h3>
<p>Pointers to polymorphic objects (objects of classes which define at
least one virtual function) are sometimes downcast or crosscast.
Downcasting means casting from a base class to a derived class.
Crosscasting means casting across an inheritance hierarchy diagram, such
as from one base to the other in a <code>Y</code> diagram hierarchy.</p>
<p>Such casts can be done with old-style casts, but this approach is
never to be recommended. Old-style casts are sorely lacking in type
safety, suffer poor readability, and are difficult to locate with search
tools.</p>
<p>The C++ built-in <code>static_cast</code> can be used for efficiently
downcasting pointers to polymorphic objects, but provides no error
detection for the case where the pointer being cast actually points to
the wrong derived class. The <code>polymorphic_downcast</code> template retains
the efficiency of <code>static_cast</code> for non-debug compilations, but for
debug compilations adds safety via an assert() that a <code>dynamic_cast</code>
succeeds.</p>
<p>The C++ built-in <code>dynamic_cast</code> can be used for downcasts and
crosscasts of pointers to polymorphic objects, but error notification in
the form of a returned value of 0 is inconvenient to test, or worse yet,
easy to forget to test. The throwing form of <code>dynamic_cast</code>, which
works on references, can be used on pointers through the ugly expression
&amp;<code>dynamic_cast&lt;T&amp;&gt;(*p)</code>, which causes undefined
behavior if <code>p</code> is <code>0</code>. The <code>polymorphic_cast</code>
template performs a <code>dynamic_cast</code> on a pointer, and throws an
exception if the <code>dynamic_cast</code> returns 0.</p>
<p>A <code>polymorphic_downcast</code> should be used for
downcasts that you are certain should succeed. Error checking is
only performed in translation units where <code>NDEBUG</code> is
not defined, via
<pre> assert( dynamic_cast&lt;Derived&gt;(x) == x )
</pre> where <code>x</code> is the source pointer. This approach
ensures that not only is a non-zero pointer returned, but also
that it is correct in the presence of multiple inheritance.
Attempts to crosscast using <code>polymorphic_downcast</code> will
fail to compile.
<b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it
violates the One Definition Rule (ODR) if NDEBUG is inconsistently
defined across translation units. [See ISO Std 3.2]
</p><p>
For crosscasts, or when the success of a cast can only be known at
runtime, or when efficiency is not important,
<code>polymorphic_cast</code> is preferred. </p>
<p>The C++ built-in <code>dynamic_cast</code> must be used to cast references
rather than pointers. It is also the only cast that can be used to check
whether a given interface is supported; in that case a return of 0 isn't
an error condition.</p>
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
<blockquote>
<pre>namespace boost {
template &lt;class Derived, class Base&gt;
inline Derived polymorphic_cast(Base* x);
// Throws: std::bad_cast if ( dynamic_cast&lt;Derived&gt;(x) == 0 )
// Returns: dynamic_cast&lt;Derived&gt;(x)
template &lt;class Derived, class Base&gt;
inline Derived polymorphic_downcast(Base* x);
// Effects: assert( dynamic_cast&lt;Derived&gt;(x) == x );
// Returns: static_cast&lt;Derived&gt;(x)
}
</pre>
</blockquote>
<h3>polymorphic_downcast example</h3>
<blockquote>
<pre>#include &lt;boost/cast.hpp&gt;
...
class Fruit { public: virtual ~Fruit(){}; ... };
class Banana : public Fruit { ... };
...
void f( Fruit * fruit ) {
// ... logic which leads us to believe it is a Banana
Banana * banana = boost::polymorphic_downcast&lt;Banana*&gt;(fruit);
...
</pre>
</blockquote>
<h3>History</h3>
<p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
Programming Language".<br>
<code>polymorphic_downcast</code> was contributed by <a href=
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
An old
numeric_cast</code> that was contributed by <a href=
"http://www.boost.org/people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/html/index.html">Boost Numeric Conversion Library</a></p>
<hr>
<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">&copy; 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>
</body>
</html>
-91
View File
@@ -1,91 +0,0 @@
// boost utility cast test program -----------------------------------------//
// (C) Copyright Beman Dawes, Dave Abrahams 1999. 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)
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 28 Set 04 factored out numeric_cast<> test (Fernando Cacciola)
// 20 Jan 01 removed use of <limits> for portability to raw GCC (David Abrahams)
// 28 Jun 00 implicit_cast removed (Beman Dawes)
// 30 Aug 99 value_cast replaced by numeric_cast
// 3 Aug 99 Initial Version
#include <iostream>
#include <climits>
#include <cfloat> // for DBL_MAX (Peter Schmid)
#include <boost/cast.hpp>
# if SCHAR_MAX == LONG_MAX
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
# endif
using namespace boost;
using std::cout;
namespace
{
struct Base
{
virtual char kind() { return 'B'; }
};
struct Base2
{
virtual char kind2() { return '2'; }
};
struct Derived : public Base, Base2
{
virtual char kind() { return 'D'; }
};
}
int main( int argc, char * argv[] )
{
# ifdef NDEBUG
cout << "NDEBUG is defined\n";
# else
cout << "NDEBUG is not defined\n";
# endif
cout << "\nBeginning tests...\n";
// test polymorphic_cast ---------------------------------------------------//
// tests which should succeed
Base * base = new Derived;
Base2 * base2 = 0;
Derived * derived = 0;
derived = polymorphic_downcast<Derived*>( base ); // downcast
assert( derived->kind() == 'D' );
derived = 0;
derived = polymorphic_cast<Derived*>( base ); // downcast, throw on error
assert( derived->kind() == 'D' );
base2 = polymorphic_cast<Base2*>( base ); // crosscast
assert( base2->kind2() == '2' );
// tests which should result in errors being detected
int err_count = 0;
base = new Base;
if ( argc > 1 && *argv[1] == '1' )
{ derived = polymorphic_downcast<Derived*>( base ); } // #1 assert failure
bool caught_exception = false;
try { derived = polymorphic_cast<Derived*>( base ); }
catch (std::bad_cast)
{ cout<<"caught bad_cast\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
// the following is just so generated code can be inspected
if ( derived->kind() == 'B' ) ++err_count;
cout << err_count << " errors detected\nTest "
<< (err_count==0 ? "passed\n" : "failed\n");
return err_count;
} // main
+12 -1
View File
@@ -1,4 +1,6 @@
# Copyright Antony Polukhin 2011. Use, modification, and distribution are
# Copyright Antony Polukhin, 2011-2026.
#
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -14,3 +16,12 @@ boostbook standalone
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
;
###############################################################################
alias boostdoc
: lexical_cast
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;
+524 -618
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2013 Antony Polukhin
// Copyright Antony Polukhin, 2013-2026.
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@@ -7,9 +7,10 @@
//[lexical_cast_args_example
//`The following example treats command line arguments as a sequence of numeric data
#include <boost/lexical_cast.hpp>
#include <vector>
#include <boost/lexical_cast.hpp>
int main(int /*argc*/, char * argv[])
{
using boost::lexical_cast;
+23 -12
View File
@@ -1,21 +1,31 @@
// Copyright 2013 Antony Polukhin
// Copyright Antony Polukhin, 2013-2026.
// 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/config.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4512) // generic_stringize.cpp(37) : warning C4512: 'stringize_functor' : assignment operator could not be generated
#endif
//[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.
Example is based on the example from the Boost C++ Application Development Cookbook
by Antony Polukhin, ISBN 9781849514880. Russian translation: [@https://dmkpress.com/catalog/computer/programming/c/978-5-97060-868-5/ ISBN: 9785970608685].
Step 1: Making a functor that converts any type to a string and remembers result:
*/
#include <string>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/lexical_cast.hpp>
struct stringize_functor {
@@ -34,7 +44,6 @@ public:
};
//` 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;
@@ -43,16 +52,18 @@ std::string stringize(const Sequence& seq) {
}
//` 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::tuple<char, int, char, int> decim('-', 10, 'e', 5);
if (stringize(decim) != "-10e5") {
return 1;
}
std::pair<short, std::string> value_and_type(270, "Kelvin");
assert(stringize(value_and_type) == "270Kelvin");
std::pair<int, std::string> value_and_type(270, "Kelvin");
if (stringize(value_and_type) != "270Kelvin") {
return 2;
}
return 0;
}
//] [/lexical_cast_stringize]
+13 -6
View File
@@ -1,15 +1,22 @@
// Copyright 2013 Antony Polukhin
// Copyright Antony Polukhin, 2013-2026.
// 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 <array>
#include <string>
#include <string.h>
#include <cstdio>
#include <boost/lexical_cast.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4996) // `strerror` is not safe
#endif
//[lexical_cast_log_errno
//`The following example uses numeric data in a string expression:
//`The following example uses numeric data in a string expression:
void log_message(const std::string &);
@@ -24,11 +31,11 @@ void log_errno(int yoko)
//[lexical_cast_fixed_buffer
//`The following example converts some number and puts it to file:
void number_to_file(int number, FILE* file)
void number_to_file(int number, std::FILE* file)
{
typedef boost::array<char, 50> buf_t; // You can use std::array if your compiler supports it
using buf_t = std::array<char, 50>;
buf_t buffer = boost::lexical_cast<buf_t>(number); // No dynamic memory allocation
fputs(buffer.begin(), file);
std::fputs(buffer.data(), file);
}
//] [/lexical_cast_fixed_buffer]
+14 -7
View File
@@ -1,4 +1,4 @@
// Copyright 2013 Antony Polukhin
// Copyright Antony Polukhin, 2013-2026.
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@@ -10,15 +10,18 @@
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>
#ifdef BOOST_USE_MODULES
#include <compare>
#endif
#include <boost/variant.hpp>
#include <cassert>
#include <boost/lexical_cast.hpp>
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.
// 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);
}
};
@@ -32,8 +35,12 @@ long double to_long_double(const Variant& 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);
const long double sum = to_long_double(v1) + to_long_double(v2) + to_long_double(v3);
if (11 < sum && sum < 11.1) {
return 0; // OK, as expected
};
return 1; // FAIL
}
//] [/lexical_cast_variant_to_long_double]
-94
View File
@@ -1,94 +0,0 @@
// boost cast.hpp header file ----------------------------------------------//
// (C) Copyright Kevlin Henney and Dave Abrahams 1999.
// 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)
// See http://www.boost.org/libs/conversion for Documentation.
// Revision History
// 23 JUn 05 numeric_cast removed and redirected to the new verion (Fernando Cacciola)
// 02 Apr 01 Removed BOOST_NO_LIMITS workarounds and included
// <boost/limits.hpp> instead (the workaround did not
// actually compile when BOOST_NO_LIMITS was defined in
// any case, so we loose nothing). (John Maddock)
// 21 Jan 01 Undid a bug I introduced yesterday. numeric_cast<> never
// worked with stock GCC; trying to get it to do that broke
// vc-stlport.
// 20 Jan 01 Moved BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS to config.hpp.
// Removed unused BOOST_EXPLICIT_TARGET macro. Moved
// boost::detail::type to boost/type.hpp. Made it compile with
// stock gcc again (Dave Abrahams)
// 29 Nov 00 Remove nested namespace cast, cleanup spacing before Formal
// Review (Beman Dawes)
// 19 Oct 00 Fix numeric_cast for floating-point types (Dave Abrahams)
// 15 Jul 00 Suppress numeric_cast warnings for GCC, Borland and MSVC
// (Dave Abrahams)
// 30 Jun 00 More MSVC6 wordarounds. See comments below. (Dave Abrahams)
// 28 Jun 00 Removed implicit_cast<>. See comment below. (Beman Dawes)
// 27 Jun 00 More MSVC6 workarounds
// 15 Jun 00 Add workarounds for MSVC6
// 2 Feb 00 Remove bad_numeric_cast ";" syntax error (Doncho Angelov)
// 26 Jan 00 Add missing throw() to bad_numeric_cast::what(0 (Adam Levar)
// 29 Dec 99 Change using declarations so usages in other namespaces work
// correctly (Dave Abrahams)
// 23 Sep 99 Change polymorphic_downcast assert to also detect M.I. errors
// as suggested Darin Adler and improved by Valentin Bonnard.
// 2 Sep 99 Remove controversial asserts, simplify, rename.
// 30 Aug 99 Move to cast.hpp, replace value_cast with numeric_cast,
// place in nested namespace.
// 3 Aug 99 Initial version
#ifndef BOOST_CAST_HPP
#define BOOST_CAST_HPP
# include <boost/config.hpp>
# include <boost/assert.hpp>
# include <typeinfo>
# include <boost/type.hpp>
# include <boost/limits.hpp>
# include <boost/detail/select_type.hpp>
namespace boost
{
// See the documentation for descriptions of how to choose between
// static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<>
// polymorphic_cast --------------------------------------------------------//
// Runtime checked polymorphic downcasts and crosscasts.
// Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
// section 15.8 exercise 1, page 425.
template <class Target, class Source>
inline Target polymorphic_cast(Source* x)
{
Target tmp = dynamic_cast<Target>(x);
if ( tmp == 0 ) throw std::bad_cast();
return tmp;
}
// polymorphic_downcast ----------------------------------------------------//
// BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited.
// WARNING: Because this cast uses BOOST_ASSERT(), it violates
// the One Definition Rule if used in multiple translation units
// where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
// NDEBUG are defined inconsistently.
// Contributed by Dave Abrahams
template <class Target, class Source>
inline Target polymorphic_downcast(Source* x)
{
BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
return static_cast<Target>(x);
}
} // namespace boost
# include <boost/numeric/conversion/cast.hpp>
#endif // BOOST_CAST_HPP
+7 -12
View File
@@ -18,7 +18,8 @@
# pragma once
#endif
#include "boost/config.hpp"
#include <boost/config.hpp>
#include <streambuf>
namespace boost { namespace detail {
@@ -39,25 +40,20 @@ protected:
typedef typename base_type::off_type off_type;
public:
basic_pointerbuf() : base_type() { setbuf(0, 0); }
basic_pointerbuf() : base_type() { this_type::setbuf(0, 0); }
const charT* getnext() { return this->gptr(); }
#ifndef BOOST_NO_USING_TEMPLATE
using base_type::pptr;
using base_type::pbase;
#else
charT* pptr() const { return base_type::pptr(); }
charT* pbase() const { return base_type::pbase(); }
#endif
protected:
// VC mistakenly assumes that `setbuf` and other functions are not referenced.
// Marking those functions with `inline` suppresses the warnings.
// There must be no harm from marking virtual functions as inline: inline virtual
// call can be inlined ONLY when the compiler knows the "exact class".
inline base_type* setbuf(char_type* s, streamsize n);
inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
inline base_type* setbuf(char_type* s, streamsize n) BOOST_OVERRIDE;
inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) BOOST_OVERRIDE;
inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) BOOST_OVERRIDE;
private:
basic_pointerbuf& operator=(const basic_pointerbuf&);
@@ -76,7 +72,7 @@ template<class charT, class BufferT>
typename basic_pointerbuf<charT, BufferT>::pos_type
basic_pointerbuf<charT, BufferT>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
{
typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
typedef ::std::ios_base::seekdir cast_type;
if(which & ::std::ios_base::out)
return pos_type(off_type(-1));
@@ -136,4 +132,3 @@ basic_pointerbuf<charT, BufferT>::seekpos(pos_type sp, ::std::ios_base::openmode
}} // namespace boost::detail
#endif // BOOST_DETAIL_BASIC_POINTERBUF_HPP
-184
View File
@@ -1,184 +0,0 @@
// Copyright Alexander Nasonov & Paul A. Bristow 2006.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#include <climits>
#include <ios>
#include <limits>
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#ifndef BOOST_NO_IS_ABSTRACT
// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_abstract.hpp>
#endif
#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \
(defined(BOOST_MSVC) && (BOOST_MSVC<1310))
#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#endif
#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
#include <boost/assert.hpp>
#else
#include <boost/static_assert.hpp>
#endif
namespace boost { namespace detail {
class lcast_abstract_stub {};
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
// Calculate an argument to pass to std::ios_base::precision from
// lexical_cast. See alternative implementation for broken standard
// libraries in lcast_get_precision below. Keep them in sync, please.
template<class T>
struct lcast_precision
{
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_abstract<T>
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
BOOST_STATIC_CONSTANT(bool, use_default_precision =
!limits::is_specialized || limits::is_exact
);
BOOST_STATIC_CONSTANT(bool, is_specialized_bin =
!use_default_precision &&
limits::radix == 2 && limits::digits > 0
);
BOOST_STATIC_CONSTANT(bool, is_specialized_dec =
!use_default_precision &&
limits::radix == 10 && limits::digits10 > 0
);
BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max =
boost::integer_traits<std::streamsize>::const_max
);
BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U);
BOOST_STATIC_ASSERT(!is_specialized_dec ||
precision_dec <= streamsize_max + 0UL
);
BOOST_STATIC_CONSTANT(unsigned long, precision_bin =
2UL + limits::digits * 30103UL / 100000UL
);
BOOST_STATIC_ASSERT(!is_specialized_bin ||
(limits::digits + 0UL < ULONG_MAX / 30103UL &&
precision_bin > limits::digits10 + 0UL &&
precision_bin <= streamsize_max + 0UL)
);
BOOST_STATIC_CONSTANT(std::streamsize, value =
is_specialized_bin ? precision_bin
: is_specialized_dec ? precision_dec : 6
);
};
#endif
template<class T>
inline std::streamsize lcast_get_precision(T* = 0)
{
#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
return lcast_precision<T>::value;
#else // Follow lcast_precision algorithm at run-time:
#ifdef BOOST_NO_IS_ABSTRACT
typedef std::numeric_limits<T> limits; // No fix for SF:1358600.
#else
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
boost::is_abstract<T>
, std::numeric_limits<lcast_abstract_stub>
, std::numeric_limits<T>
>::type limits;
#endif
bool const use_default_precision =
!limits::is_specialized || limits::is_exact;
if(!use_default_precision)
{ // Includes all built-in floating-point types, float, double ...
// and UDT types for which digits (significand bits) is defined (not zero)
bool const is_specialized_bin =
limits::radix == 2 && limits::digits > 0;
bool const is_specialized_dec =
limits::radix == 10 && limits::digits10 > 0;
std::streamsize const streamsize_max =
(boost::integer_traits<std::streamsize>::max)();
if(is_specialized_bin)
{ // Floating-point types with
// limits::digits defined by the specialization.
unsigned long const digits = limits::digits;
unsigned long const precision = 2UL + digits * 30103UL / 100000UL;
// unsigned long is selected because it is at least 32-bits
// and thus ULONG_MAX / 30103UL is big enough for all types.
BOOST_ASSERT(
digits < ULONG_MAX / 30103UL &&
precision > limits::digits10 + 0UL &&
precision <= streamsize_max + 0UL
);
return precision;
}
else if(is_specialized_dec)
{ // Decimal Floating-point type, most likely a User Defined Type
// rather than a real floating-point hardware type.
unsigned int const precision = limits::digits10 + 1U;
BOOST_ASSERT(precision <= streamsize_max + 0UL);
return precision;
}
}
// Integral type (for which precision has no effect)
// or type T for which limits is NOT specialized,
// so assume stream precision remains the default 6 decimal digits.
// Warning: if your User-defined Floating-point type T is NOT specialized,
// then you may lose accuracy by only using 6 decimal digits.
// To avoid this, you need to specialize T with either
// radix == 2 and digits == the number of significand bits,
// OR
// radix = 10 and digits10 == the number of decimal digits.
return 6;
#endif
}
template<class T>
inline void lcast_set_precision(std::ios_base& stream, T*)
{
stream.precision(lcast_get_precision<T>());
}
template<class Source, class Target>
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
{
std::streamsize const s = lcast_get_precision(static_cast<Source*>(0));
std::streamsize const t = lcast_get_precision(static_cast<Target*>(0));
stream.precision(s > t ? s : t);
}
}}
#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
-29
View File
@@ -1,29 +0,0 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef IMPLICIT_CAST_DWA200356_HPP
# define IMPLICIT_CAST_DWA200356_HPP
# include <boost/mpl/identity.hpp>
namespace boost {
// implementation originally suggested by C. Green in
// http://lists.boost.org/MailArchives/boost/msg00886.php
// The use of identity creates a non-deduced form, so that the
// explicit template argument must be supplied
template <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x) {
return x;
}
// incomplete return type now is here
//template <typename T>
//void implicit_cast (...);
} // namespace boost
#endif // IMPLICIT_CAST_DWA200356_HPP
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,110 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP
#define BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <exception>
#include <typeinfo>
#include <boost/throw_exception.hpp>
#endif
namespace boost
{
BOOST_LEXICAL_CAST_BEGIN_MODULE_EXPORT
// exception used to indicate runtime lexical_cast failure
class BOOST_SYMBOL_VISIBLE bad_lexical_cast :
// workaround MSVC bug with std::bad_cast when _HAS_EXCEPTIONS == 0
#if defined(BOOST_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
public std::exception
#else
public std::bad_cast
#endif
{
public:
bad_lexical_cast() noexcept
#ifndef BOOST_NO_TYPEID
: source(&typeid(void)), target(&typeid(void))
#endif
{}
const char *what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {
return "bad lexical cast: "
"source type value could not be interpreted as target";
}
bad_lexical_cast(const bad_lexical_cast&) = default;
bad_lexical_cast& operator=(const bad_lexical_cast&) = default;
#ifndef BOOST_NO_TYPEID
private:
#ifdef BOOST_NO_STD_TYPEINFO
typedef ::type_info type_info_t;
#else
typedef ::std::type_info type_info_t;
#endif
public:
bad_lexical_cast(
const type_info_t &source_type_arg,
const type_info_t &target_type_arg) noexcept
: source(&source_type_arg), target(&target_type_arg)
{}
const type_info_t &source_type() const noexcept {
return *source;
}
const type_info_t &target_type() const noexcept {
return *target;
}
private:
const type_info_t *source;
const type_info_t *target;
#endif
};
BOOST_LEXICAL_CAST_END_MODULE_EXPORT
namespace conversion { namespace detail {
#ifdef BOOST_NO_TYPEID
template <class S, class T>
inline void throw_bad_cast() {
boost::throw_exception(bad_lexical_cast());
}
#else
template <class S, class T>
inline void throw_bad_cast() {
boost::throw_exception(bad_lexical_cast(typeid(S), typeid(T)));
}
#endif
}} // namespace conversion::detail
} // namespace boost
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP
@@ -0,0 +1,67 @@
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXICAL_CAST_DETAIL_BUFFER_VIEW_HPP
#define BOOST_LEXICAL_CAST_DETAIL_BUFFER_VIEW_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <iosfwd>
#endif
namespace boost { namespace conversion { namespace detail {
template < typename CharT >
struct buffer_view {
const CharT* begin;
const CharT* end;
};
template < typename CharT >
buffer_view<CharT> make_buffer_view(const CharT* begin, const CharT* end) {
return buffer_view<CharT>{begin, end};
}
inline buffer_view<char> make_buffer_view(const signed char* begin, const signed char* end) {
return buffer_view<char>{
reinterpret_cast<const char*>(begin),
reinterpret_cast<const char*>(end)
};
}
inline buffer_view<char> make_buffer_view(const unsigned char* begin, const unsigned char* end) {
return buffer_view<char>{
reinterpret_cast<const char*>(begin),
reinterpret_cast<const char*>(end)
};
}
template< typename CharT, typename Elem, typename Traits >
std::basic_ostream<Elem,Traits>& operator<<(
std::basic_ostream<Elem, Traits>& os,
buffer_view<CharT> r)
{
while (r.begin != r.end) {
os << r.begin[0];
++r.begin;
}
return os;
}
}}} // namespace boost::conversion::detail
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_BUFFER_VIEW_HPP
@@ -0,0 +1,22 @@
// Copyright Antony Polukhin, 2021-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONFIG_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONFIG_HPP
#ifdef BOOST_LEXICAL_CAST_INTERFACE_UNIT
# define BOOST_LEXICAL_CAST_BEGIN_MODULE_EXPORT export {
# define BOOST_LEXICAL_CAST_END_MODULE_EXPORT }
#else
# define BOOST_LEXICAL_CAST_BEGIN_MODULE_EXPORT
# define BOOST_LEXICAL_CAST_END_MODULE_EXPORT
#endif
#if defined(BOOST_USE_MODULES) && !defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
import boost.lexical_cast;
#endif
#endif // #ifndef BOOST_LEXICAL_CAST_DETAIL_CONFIG_HPP
@@ -0,0 +1,491 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <array>
#include <cstddef>
#include <string>
#include <type_traits>
#include <boost/limits.hpp>
#include <array>
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
#include <string_view>
#endif
#include <boost/container/container_fwd.hpp>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/lexical_cast/detail/lcast_precision.hpp>
#include <boost/lexical_cast/detail/widest_char.hpp>
#include <boost/lexical_cast/detail/is_character.hpp>
#include <boost/lexical_cast/detail/buffer_view.hpp>
#include <boost/lexical_cast/detail/converter_lexical_streams.hpp>
namespace boost {
// Forward declaration
template<class T, std::size_t N>
class array;
template<class IteratorT>
class iterator_range;
// Forward declaration of boost::basic_string_view from Utility
template<class Ch, class Tr> class basic_string_view;
namespace detail // normalize_single_byte_char<Char>
{
// Converts signed/unsigned char to char
template < class Char >
struct normalize_single_byte_char
{
using type = Char;
};
template <>
struct normalize_single_byte_char< signed char >
{
using type = char;
};
template <>
struct normalize_single_byte_char< unsigned char >
{
using type = char;
};
}
namespace detail // deduce_character_type_later<T>
{
// Helper type, meaning that stram character for T must be deduced
// at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
template < class T > struct deduce_character_type_later {};
}
namespace detail // stream_char_common<T>
{
// Selectors to choose stream character type (common for Source and Target)
// Returns one of char, wchar_t, char16_t, char32_t or deduce_character_type_later<T> types
// Executed on Stage 1 (See deduce_source_char<T> and deduce_target_char<T>)
template < typename Type >
struct stream_char_common: public std::conditional<
boost::detail::is_character< Type >::value,
Type,
boost::detail::deduce_character_type_later< Type >
> {};
template < typename Char >
struct stream_char_common< Char* >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< Char* >
> {};
template < typename Char >
struct stream_char_common< const Char* >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< const Char* >
> {};
template < typename Char >
struct stream_char_common< boost::conversion::detail::buffer_view< Char > >
{
using type = Char;
};
template < typename Char >
struct stream_char_common< boost::iterator_range< Char* > >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::iterator_range< Char* > >
> {};
template < typename Char >
struct stream_char_common< boost::iterator_range< const Char* > >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::iterator_range< const Char* > >
> {};
template < class Char, class Traits, class Alloc >
struct stream_char_common< std::basic_string< Char, Traits, Alloc > >
{
using type = Char;
};
template < class Char, class Traits, class Alloc >
struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
{
using type = Char;
};
template < typename Char, std::size_t N >
struct stream_char_common< boost::array< Char, N > >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::array< Char, N > >
> {};
template < typename Char, std::size_t N >
struct stream_char_common< boost::array< const Char, N > >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< boost::array< const Char, N > >
> {};
#ifndef BOOST_NO_CXX11_HDR_ARRAY
template < typename Char, std::size_t N >
struct stream_char_common< std::array<Char, N > >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< std::array< Char, N > >
> {};
template < typename Char, std::size_t N >
struct stream_char_common< std::array< const Char, N > >: public std::conditional<
boost::detail::is_character< Char >::value,
Char,
boost::detail::deduce_character_type_later< std::array< const Char, N > >
> {};
#endif
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
template < class Char, class Traits >
struct stream_char_common< std::basic_string_view< Char, Traits > >
{
using type = Char;
};
#endif
template < class Char, class Traits >
struct stream_char_common< boost::basic_string_view< Char, Traits > >
{
using type = Char;
};
#ifdef BOOST_HAS_INT128
template <> struct stream_char_common< boost::int128_type >
{
using type = char;
};
template <> struct stream_char_common< boost::uint128_type >
{
using type = char;
};
#endif
#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <>
struct stream_char_common< wchar_t >
{
using type = char;
};
#endif
}
namespace detail // deduce_source_char_impl<T>
{
// If type T is `deduce_character_type_later` type, then tries to deduce
// character type using streaming metafunctions.
// Otherwise supplied type T is a character type, that must be normalized
// using normalize_single_byte_char<Char>.
// Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
template < class Char >
struct deduce_source_char_impl
{
typedef typename boost::detail::normalize_single_byte_char< Char >::type type;
};
template < class T >
struct deduce_source_char_impl< deduce_character_type_later< 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)
template <class U>
static auto left_shift_type(int)
-> decltype( std::declval<std::basic_ostream< wchar_t >&>() << std::declval<const U&>(), wchar_t{});
#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
);
};
}
namespace detail // deduce_target_char_impl<T>
{
// If type T is `deduce_character_type_later` type, then tries to deduce
// character type using boost::has_right_shift<T> metafunction.
// Otherwise supplied type T is a character type, that must be normalized
// using normalize_single_byte_char<Char>.
// Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
template < class Char >
struct deduce_target_char_impl
{
typedef typename normalize_single_byte_char< Char >::type type;
};
template < class T >
struct deduce_target_char_impl< deduce_character_type_later<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)
template <class U>
static auto right_shift_type(int)
-> decltype( std::declval<std::basic_istream< wchar_t >&>() >> std::declval<U&>(), wchar_t{});
#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
);
};
}
namespace detail // deduce_target_char<T> and deduce_source_char<T>
{
// We deduce stream character types in two stages.
//
// Stage 1 is common for Target and Source. At Stage 1 we get
// non normalized character type (may contain unsigned/signed char)
// or deduce_character_type_later<T> where T is the original type.
// Stage 1 is executed by stream_char_common<T>
//
// At Stage 2 we normalize character types or try to deduce character
// type using metafunctions.
// Stage 2 is executed by deduce_target_char_impl<T> and
// deduce_source_char_impl<T>
//
// deduce_target_char<T> and deduce_source_char<T> functions combine
// both stages
template < class T >
struct deduce_target_char
{
typedef typename stream_char_common< T >::type stage1_type;
typedef typename deduce_target_char_impl< stage1_type >::type type;
};
template < class T >
struct deduce_source_char
{
typedef typename stream_char_common< T >::type stage1_type;
typedef typename deduce_source_char_impl< stage1_type >::type type;
};
}
namespace detail // array_to_pointer_decay<T>
{
template<class T>
struct array_to_pointer_decay
{
typedef T type;
};
template<class T, std::size_t N>
struct array_to_pointer_decay<T[N]>
{
typedef const T * type;
};
}
namespace detail // lcast_src_length
{
// Return max. length of string representation of Source;
template< class Source, // Source type of lexical_cast.
class Enable = void // helper type
>
struct lcast_src_length
{
BOOST_STATIC_CONSTANT(std::size_t, value = 1);
};
// Helper for integral types.
// Notes on length calculation:
// Max length for 32bit int with grouping "\1" and thousands_sep ',':
// "-2,1,4,7,4,8,3,6,4,7"
// ^ - is_signed
// ^ - 1 digit not counted by digits10
// ^^^^^^^^^^^^^^^^^^ - digits10 * 2
//
// Constant is_specialized is used instead of constant 1
// to prevent buffer overflow in a rare case when
// <boost/limits.hpp> doesn't add missing specialization for
// numeric_limits<T> for some integral type T.
// When is_specialized is false, the whole expression is 0.
template <class Source>
struct lcast_src_length<
Source, typename std::enable_if<boost::detail::lcast::is_integral<Source>::value >::type
>
{
BOOST_STATIC_CONSTANT(std::size_t, value =
std::numeric_limits<Source>::is_signed +
std::numeric_limits<Source>::is_specialized + /* == 1 */
std::numeric_limits<Source>::digits10 * 2
);
};
// Helper for floating point types.
// -1.23456789e-123456
// ^ sign
// ^ leading digit
// ^ decimal point
// ^^^^^^^^ lcast_precision<Source>::value
// ^ "e"
// ^ exponent sign
// ^^^^^^ exponent (assumed 6 or less digits)
// sign + leading digit + decimal point + "e" + exponent sign == 5
template<class Source>
struct lcast_src_length<
Source, typename std::enable_if<std::is_floating_point<Source>::value >::type
>
{
static_assert(
std::numeric_limits<Source>::max_exponent10 <= 999999L &&
std::numeric_limits<Source>::min_exponent10 >= -999999L
, "");
BOOST_STATIC_CONSTANT(std::size_t, value =
5 + lcast_precision<Source>::value + 6
);
};
}
namespace detail // lexical_cast_stream_traits<Source, Target>
{
template <class Source, class Target>
struct lexical_cast_stream_traits {
typedef typename boost::detail::array_to_pointer_decay<Source>::type src;
typedef typename std::remove_cv<src>::type no_cv_src;
typedef boost::detail::deduce_source_char<no_cv_src> deduce_src_char_metafunc;
typedef typename deduce_src_char_metafunc::type src_char_t;
typedef typename boost::detail::deduce_target_char<Target>::type target_char_t;
typedef typename boost::detail::widest_char<
target_char_t, src_char_t
>::type char_type;
#if !defined(BOOST_NO_CXX11_CHAR16_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
static_assert(!std::is_same<char16_t, src_char_t>::value
&& !std::is_same<char16_t, target_char_t>::value,
"Your compiler does not have full support for char16_t" );
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
static_assert(!std::is_same<char32_t, src_char_t>::value
&& !std::is_same<char32_t, target_char_t>::value,
"Your compiler does not have full support for char32_t" );
#endif
typedef std::char_traits<char_type> traits;
typedef boost::detail::lcast_src_length<no_cv_src> len_t;
};
}
namespace detail
{
template<typename Target, typename Source>
struct lexical_converter_impl
{
typedef lexical_cast_stream_traits<Source, Target> stream_trait;
typedef detail::lcast::optimized_src_stream<
typename stream_trait::char_type,
typename stream_trait::traits,
stream_trait::len_t::value + 1
> optimized_src_stream;
template <class T>
static auto detect_type(int)
-> decltype(std::declval<optimized_src_stream&>().stream_in(std::declval<lcast::exact<T>>()), optimized_src_stream{});
template <class T>
static lcast::ios_src_stream<typename stream_trait::char_type, typename stream_trait::traits> detect_type(...);
using from_src_stream = decltype(detect_type<Source>(1));
typedef detail::lcast::to_target_stream<
typename stream_trait::char_type,
typename stream_trait::traits
> to_target_stream;
static inline bool try_convert(const Source& arg, Target& result) {
from_src_stream src_stream;
if (!src_stream.stream_in(lcast::exact<Source>{arg}))
return false;
to_target_stream out(src_stream.cbegin(), src_stream.cend());
if (!out.stream_out(result))
return false;
return true;
}
};
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
@@ -0,0 +1,763 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014, Nowember 2016
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <cstddef>
#include <string>
#include <cstring>
#include <cstdio>
#include <type_traits>
#include <boost/limits.hpp>
#include <boost/config/workaround.hpp>
#include <boost/core/snprintf.hpp>
#ifndef BOOST_NO_STD_LOCALE
# include <locale>
#else
# ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
// Getting error at this point means, that your STL library is old/lame/misconfigured.
// If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
// but beware: lexical_cast will understand only 'C' locale delimeters and thousands
// separators.
# error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
# error "boost::lexical_cast to use only 'C' locale during conversions."
# endif
#endif
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif
#include <array>
#ifndef BOOST_NO_CWCHAR
# include <cwchar>
#endif
#include <istream>
#include <boost/container/container_fwd.hpp>
#ifndef BOOST_NO_CWCHAR
# include <cwchar>
#endif
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/lexical_cast/detail/buffer_view.hpp>
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
#include <boost/lexical_cast/detail/lcast_unsigned_converters.hpp>
#include <boost/lexical_cast/detail/lcast_basic_unlockedbuf.hpp>
#include <boost/lexical_cast/detail/inf_nan.hpp>
#include <boost/lexical_cast/detail/lcast_precision.hpp>
#include <boost/lexical_cast/detail/type_traits.hpp>
// Forward declarations
namespace boost {
template<class T, std::size_t N>
class array;
template<class IteratorT>
class iterator_range;
// forward declaration of boost::basic_string_view from Utility
template<class Ch, class Tr> class basic_string_view;
}
namespace boost { namespace detail { namespace lcast {
template <typename T>
struct exact {
static_assert(!std::is_const<T>::value, "");
static_assert(!std::is_reference<T>::value, "");
const T& payload;
};
template< class CharT // a result of widest_char transformation
, class Traits
, std::size_t CharacterBufferSize
>
class optimized_src_stream {
CharT buffer[CharacterBufferSize];
// After the `stream_in(` finishes, `[start, finish)` is
// the range to output by `operator >>`
const CharT* start;
const CharT* finish;
public:
optimized_src_stream(optimized_src_stream&&) = delete;
optimized_src_stream(const optimized_src_stream&) = delete;
optimized_src_stream& operator=(optimized_src_stream&&) = delete;
optimized_src_stream& operator=(const optimized_src_stream&) = delete;
optimized_src_stream() noexcept
: start(buffer)
, finish(buffer + CharacterBufferSize)
{}
const CharT* cbegin() const noexcept {
return start;
}
const CharT* cend() const noexcept {
return finish;
}
private:
bool shl_char(CharT ch) noexcept {
Traits::assign(buffer[0], ch);
finish = start + 1;
return true;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
template <class T>
bool shl_char(T ch) {
static_assert(sizeof(T) <= sizeof(CharT),
"boost::lexical_cast does not support narrowing of char types."
"Use boost::locale instead" );
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
std::locale loc;
CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
#else
CharT const w = static_cast<CharT>(ch);
#endif
Traits::assign(buffer[0], w);
finish = start + 1;
return true;
}
#endif
bool shl_char_array(CharT const* str_value) noexcept {
start = str_value;
finish = start + Traits::length(str_value);
return true;
}
bool shl_char_array_limited(CharT const* str, std::size_t max_size) noexcept {
start = str;
finish = start;
const auto zero = Traits::to_char_type(0);
while (finish < start + max_size && zero != *finish) {
++ finish;
}
return true;
}
template <class T>
inline bool shl_unsigned(const T n) {
CharT* tmp_finish = buffer + CharacterBufferSize;
start = lcast_put_unsigned<Traits, T, CharT>(n, tmp_finish).convert();
finish = tmp_finish;
return true;
}
template <class T>
inline bool shl_signed(const T n) {
CharT* tmp_finish = buffer + CharacterBufferSize;
typedef typename boost::detail::lcast::make_unsigned<T>::type utype;
CharT* tmp_start = lcast_put_unsigned<Traits, utype, CharT>(lcast_to_unsigned(n), tmp_finish).convert();
if (n < 0) {
--tmp_start;
CharT const minus = lcast_char_constants<CharT>::minus;
Traits::assign(*tmp_start, minus);
}
start = tmp_start;
finish = tmp_finish;
return true;
}
bool shl_real_type(lcast::exact<float> val, char* begin) {
const double val_as_double = static_cast<double>(val.payload);
finish = start +
boost::core::snprintf(begin, CharacterBufferSize,
"%.*g", static_cast<int>(boost::detail::lcast_precision<float>::value), val_as_double);
return finish > start;
}
bool shl_real_type(lcast::exact<double> val, char* begin) {
finish = start +
boost::core::snprintf(begin, CharacterBufferSize,
"%.*g", static_cast<int>(boost::detail::lcast_precision<double>::value), val.payload);
return finish > start;
}
#ifndef __MINGW32__
bool shl_real_type(lcast::exact<long double> val, char* begin) {
finish = start +
boost::core::snprintf(begin, CharacterBufferSize,
"%.*Lg", static_cast<int>(boost::detail::lcast_precision<long double>::value), val.payload );
return finish > start;
}
#else
bool shl_real_type(lcast::exact<long double> val, char* begin) {
return shl_real_type(lcast::exact<double>{static_cast<double>(val.payload)}, begin);
}
#endif
#if !defined(BOOST_LCAST_NO_WCHAR_T)
bool shl_real_type(lcast::exact<float> val, wchar_t* begin) {
const double val_as_double = static_cast<double>(val.payload);
finish = start + boost::core::swprintf(
begin, CharacterBufferSize, L"%.*g",
static_cast<int>(boost::detail::lcast_precision<float>::value),
val_as_double
);
return finish > start;
}
bool shl_real_type(lcast::exact<double> val, wchar_t* begin) {
finish = start + boost::core::swprintf(
begin, CharacterBufferSize, L"%.*g",
static_cast<int>(boost::detail::lcast_precision<double>::value),
val.payload
);
return finish > start;
}
bool shl_real_type(lcast::exact<long double> val, wchar_t* begin) {
finish = start + boost::core::swprintf(
begin, CharacterBufferSize, L"%.*Lg",
static_cast<int>(boost::detail::lcast_precision<long double>::value),
val.payload
);
return finish > start;
}
#endif
public:
template <class C>
using enable_if_compatible_char_t = typename std::enable_if<
std::is_same<const C, const CharT>::value || (
std::is_same<const char, const CharT>::value && (
std::is_same<const C, const unsigned char>::value ||
std::is_same<const C, const signed char>::value
)
), bool
>::type;
template<class CharTraits, class Alloc>
bool stream_in(lcast::exact<std::basic_string<CharT,CharTraits,Alloc>> x) noexcept {
start = x.payload.data();
finish = start + x.payload.length();
return true;
}
template<class CharTraits, class Alloc>
bool stream_in(lcast::exact<boost::container::basic_string<CharT,CharTraits,Alloc>> x) noexcept {
start = x.payload.data();
finish = start + x.payload.length();
return true;
}
bool stream_in(lcast::exact<bool> x) noexcept {
CharT const czero = lcast_char_constants<CharT>::zero;
Traits::assign(buffer[0], Traits::to_char_type(czero + x.payload));
finish = start + 1;
return true;
}
bool stream_in(lcast::exact<boost::conversion::detail::buffer_view<CharT>> x) noexcept {
start = x.payload.begin;
finish = x.payload.end;
return true;
}
template <class C>
enable_if_compatible_char_t<C>
stream_in(lcast::exact<boost::iterator_range<C*>> x) noexcept {
auto buf = boost::conversion::detail::make_buffer_view(x.payload.begin(), x.payload.end());
return stream_in(lcast::exact<decltype(buf)>{buf});
}
bool stream_in(lcast::exact<char> x) { return shl_char(x.payload); }
bool stream_in(lcast::exact<unsigned char> x) { return shl_char(static_cast<char>(x.payload)); }
bool stream_in(lcast::exact<signed char> x) { return shl_char(static_cast<char>(x.payload)); }
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <class C>
typename std::enable_if<boost::detail::is_character<C>::value, bool>::type
stream_in(lcast::exact<C> x) { return shl_char(x.payload); }
#endif
template <class Type>
enable_if_compatible_char_t<Type>
stream_in(lcast::exact<Type*> x) { return shl_char_array(reinterpret_cast<CharT const*>(x.payload)); }
template <class Type>
typename std::enable_if<!std::is_floating_point<Type>::value && boost::detail::lcast::is_signed<Type>::value && !std::is_enum<Type>::value, bool>::type
stream_in(lcast::exact<Type> x) { return shl_signed(x.payload); }
template <class Type>
typename std::enable_if<boost::detail::lcast::is_unsigned<Type>::value && !std::is_enum<Type>::value, bool>::type
stream_in(lcast::exact<Type> x) { return shl_unsigned(x.payload); }
template <class Type>
auto stream_in(lcast::exact<Type> x) -> decltype(shl_real_type(x, buffer)) {
const CharT* inf_nan = detail::get_inf_nan(x.payload, CharT());
if (inf_nan) {
start = inf_nan;
finish = start + Traits::length(inf_nan);
return true;
}
return shl_real_type(x, buffer);
}
template <class C, std::size_t N>
enable_if_compatible_char_t<C>
stream_in(lcast::exact<boost::array<C, N>> x) noexcept {
return shl_char_array_limited(reinterpret_cast<const CharT*>(x.payload.data()), N);
}
template <class C, std::size_t N>
enable_if_compatible_char_t<C>
stream_in(lcast::exact<std::array<C, N>> x) noexcept {
return shl_char_array_limited(reinterpret_cast<const CharT*>(x.payload.data()), N);
}
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
template <class C, class CharTraits>
enable_if_compatible_char_t<C>
stream_in(lcast::exact<std::basic_string_view<C, CharTraits>> x) noexcept {
start = reinterpret_cast<const CharT*>(x.payload.data());
finish = start + x.payload.size();
return true;
}
#endif
template <class C, class CharTraits>
enable_if_compatible_char_t<C>
stream_in(lcast::exact<boost::basic_string_view<C, CharTraits>> x) noexcept {
start = reinterpret_cast<const CharT*>(x.payload.data());
finish = start + x.payload.size();
return true;
}
};
template <class CharT, class Traits>
class ios_src_stream {
typedef detail::lcast::out_stream_t<CharT, Traits> deduced_out_stream_t;
typedef detail::lcast::stringbuffer_t<CharT, Traits> deduced_out_buffer_t;
deduced_out_buffer_t out_buffer;
deduced_out_stream_t out_stream;
const CharT* start = nullptr;
const CharT* finish = nullptr;
public:
ios_src_stream(ios_src_stream&&) = delete;
ios_src_stream(const ios_src_stream&) = delete;
ios_src_stream& operator=(ios_src_stream&&) = delete;
ios_src_stream& operator=(const ios_src_stream&) = delete;
ios_src_stream(): out_buffer(), out_stream(&out_buffer) {}
const CharT* cbegin() const noexcept {
return start;
}
const CharT* cend() const noexcept {
return finish;
}
private:
const deduced_out_buffer_t* get_rdbuf() const {
return static_cast<deduced_out_buffer_t*>(
out_stream.rdbuf()
);
}
template<typename InputStreamable>
bool shl_input_streamable(InputStreamable& input) {
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
// If you have compilation error at this point, than your STL library
// does not support such conversions. Try updating it.
static_assert(std::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 auto* const p = get_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>
bool shl_char_array(T const* str_value) {
static_assert(sizeof(T) <= sizeof(CharT),
"boost::lexical_cast does not support narrowing of char types."
"Use boost::locale instead" );
return shl_input_streamable(str_value);
}
template <class T>
bool shl_real(T val) {
const CharT* inf_nan = detail::get_inf_nan(val, CharT());
if (inf_nan) {
start = inf_nan;
finish = start + Traits::length(inf_nan);
return true;
}
boost::detail::lcast_set_precision(out_stream, &val);
return shl_input_streamable(val);
}
public:
template <class Type>
typename std::enable_if<boost::detail::is_character<Type>::value && sizeof(char) == sizeof(Type), bool>::type
stream_in(lcast::exact<const Type*> x) { return shl_char_array(reinterpret_cast<char const*>(x.payload)); }
template <class Type>
typename std::enable_if<boost::detail::is_character<Type>::value && sizeof(char) != sizeof(Type), bool>::type
stream_in(lcast::exact<const Type*> x) { return shl_char_array(x.payload); }
bool stream_in(lcast::exact<float> x) { return shl_real(x.payload); }
bool stream_in(lcast::exact<double> x) { return shl_real(x.payload); }
bool stream_in(lcast::exact<long double> x) {
#ifndef __MINGW32__
return shl_real(x.payload);
#else
return shl_real(static_cast<double>(x.payload));
#endif
}
template <class C>
typename std::enable_if<boost::detail::is_character<C>::value, bool>::type
stream_in(lcast::exact<iterator_range<C*>> x) noexcept {
auto buf = boost::conversion::detail::make_buffer_view(x.payload.begin(), x.payload.end());
return stream_in(lcast::exact<decltype(buf)>{buf});
}
template <class C>
typename std::enable_if<boost::detail::is_character<C>::value, bool>::type
stream_in(lcast::exact<iterator_range<const C*>> x) noexcept {
auto buf = boost::conversion::detail::make_buffer_view(x.payload.begin(), x.payload.end());
return stream_in(lcast::exact<decltype(buf)>{buf});
}
template <class InStreamable>
bool stream_in(lcast::exact<InStreamable> x) { return shl_input_streamable(x.payload); }
};
template <class CharT, class Traits>
class to_target_stream {
//`[start, finish)` is the range to output by `operator >>`
const CharT* start;
const CharT* const finish;
public:
to_target_stream(to_target_stream&&) = delete;
to_target_stream(const to_target_stream&) = delete;
to_target_stream& operator=(to_target_stream&&) = delete;
to_target_stream& operator=(const to_target_stream&) = delete;
to_target_stream(const CharT* begin, const CharT* end) noexcept
: start(begin)
, finish(end)
{}
private:
template <typename Type>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
bool shr_unsigned(Type& output) {
if (start == finish) return false;
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
bool const has_minus = Traits::eq(minus, *start);
/* We won`t use `start' any more, so no need in decrementing it after */
if (has_minus || Traits::eq(plus, *start)) {
++start;
}
bool const succeed = lcast_ret_unsigned<Traits, Type, CharT>(output, start, finish).convert();
if (has_minus) {
output = static_cast<Type>(0u - output);
}
return succeed;
}
template <typename Type>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
bool shr_signed(Type& output) {
if (start == finish) return false;
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
typedef typename boost::detail::lcast::make_unsigned<Type>::type utype;
utype out_tmp = 0;
bool const has_minus = Traits::eq(minus, *start);
/* We won`t use `start' any more, so no need in decrementing it after */
if (has_minus || Traits::eq(plus, *start)) {
++start;
}
bool succeed = lcast_ret_unsigned<Traits, utype, CharT>(out_tmp, start, finish).convert();
if (has_minus) {
utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
succeed = succeed && out_tmp<=comp_val;
output = static_cast<Type>(0u - out_tmp);
} else {
utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
succeed = succeed && out_tmp<=comp_val;
output = static_cast<Type>(out_tmp);
}
return succeed;
}
template<typename InputStreamable>
bool shr_using_base_class(InputStreamable& output)
{
static_assert(
!std::is_pointer<InputStreamable>::value,
"boost::lexical_cast can not convert to pointers"
);
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
static_assert(std::is_same<char, CharT>::value,
"boost::lexical_cast can not convert, because your STL library does not "
"support such conversions. Try updating it."
);
#endif
#if defined(BOOST_NO_STRINGSTREAM)
std::istrstream stream(start, static_cast<std::istrstream::streamsize>(finish - start));
#else
typedef detail::lcast::buffer_t<CharT, Traits> buffer_t;
buffer_t buf;
// Usually `istream` and `basic_istream` do not modify
// content of buffer; `buffer_t` assures that this is true
buf.setbuf(const_cast<CharT*>(start), static_cast<typename buffer_t::streamsize>(finish - start));
#if defined(BOOST_NO_STD_LOCALE)
std::istream stream(&buf);
#else
std::basic_istream<CharT, Traits> stream(&buf);
#endif // BOOST_NO_STD_LOCALE
#endif // BOOST_NO_STRINGSTREAM
#ifndef BOOST_NO_EXCEPTIONS
stream.exceptions(std::ios::badbit);
try {
#endif
stream.unsetf(std::ios::skipws);
boost::detail::lcast_set_precision(stream, static_cast<InputStreamable*>(0));
return (stream >> output)
&& (stream.get() == Traits::eof());
#ifndef BOOST_NO_EXCEPTIONS
} catch (const ::std::ios_base::failure& /*f*/) {
return false;
}
#endif
}
template<class T>
inline bool shr_xchar(T& output) noexcept {
static_assert(sizeof(CharT) == sizeof(T),
"boost::lexical_cast does not support narrowing of character types."
"Use boost::locale instead" );
bool const ok = (finish - start == 1);
if (ok) {
CharT out;
Traits::assign(out, *start);
output = static_cast<T>(out);
}
return ok;
}
template <std::size_t N, class ArrayT>
bool shr_std_array(ArrayT& output) noexcept {
const std::size_t size = static_cast<std::size_t>(finish - start);
if (size > N - 1) { // `-1` because we need to store \0 at the end
return false;
}
std::memcpy(&output[0], start, size * sizeof(CharT));
output[size] = Traits::to_char_type(0);
return true;
}
public:
bool stream_out(unsigned short& output) { return shr_unsigned(output); }
bool stream_out(unsigned int& output) { return shr_unsigned(output); }
bool stream_out(unsigned long int& output) { return shr_unsigned(output); }
bool stream_out(short& output) { return shr_signed(output); }
bool stream_out(int& output) { return shr_signed(output); }
bool stream_out(long int& output) { return shr_signed(output); }
#if defined(BOOST_HAS_LONG_LONG)
bool stream_out(boost::ulong_long_type& output) { return shr_unsigned(output); }
bool stream_out(boost::long_long_type& output) { return shr_signed(output); }
#elif defined(BOOST_HAS_MS_INT64)
bool stream_out(unsigned __int64& output) { return shr_unsigned(output); }
bool stream_out(__int64& output) { return shr_signed(output); }
#endif
#ifdef BOOST_HAS_INT128
bool stream_out(boost::uint128_type& output) { return shr_unsigned(output); }
bool stream_out(boost::int128_type& output) { return shr_signed(output); }
#endif
bool stream_out(char& output) { return shr_xchar(output); }
bool stream_out(unsigned char& output) { return shr_xchar(output); }
bool stream_out(signed char& output) { return shr_xchar(output); }
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
bool stream_out(wchar_t& output) { return shr_xchar(output); }
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
bool stream_out(char16_t& output) { return shr_xchar(output); }
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
bool stream_out(char32_t& output) { return shr_xchar(output); }
#endif
template<class CharTraits, class Alloc>
bool stream_out(std::basic_string<CharT,CharTraits,Alloc>& str) {
str.assign(start, finish); return true;
}
template<class CharTraits, class Alloc>
bool stream_out(boost::container::basic_string<CharT,CharTraits,Alloc>& str) {
str.assign(start, finish); return true;
}
template <class C, std::size_t N>
bool stream_out(std::array<C, N>& output) noexcept {
static_assert(sizeof(C) == sizeof(CharT), "");
return shr_std_array<N>(output);
}
template <class C, std::size_t N>
bool stream_out(boost::array<C, N>& output) noexcept {
static_assert(sizeof(C) == sizeof(CharT), "");
return shr_std_array<N>(output);
}
bool stream_out(bool& output) noexcept {
output = false; // Suppress warning about uninitalized variable
if (start == finish) return false;
CharT const zero = lcast_char_constants<CharT>::zero;
CharT const plus = lcast_char_constants<CharT>::plus;
CharT const minus = lcast_char_constants<CharT>::minus;
const CharT* const dec_finish = finish - 1;
output = Traits::eq(*dec_finish, zero + 1);
if (!output && !Traits::eq(*dec_finish, zero)) {
return false; // Does not ends on '0' or '1'
}
if (start == dec_finish) return true;
// We may have sign at the beginning
if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
++ start;
}
// Skipping zeros
while (start != dec_finish) {
if (!Traits::eq(zero, *start)) {
return false; // Not a zero => error
}
++ start;
}
return true;
}
private:
// Not optimised converter
template <class T>
bool float_types_converter_internal(T& output) {
if (parse_inf_nan(start, finish, output)) return true;
bool const return_value = shr_using_base_class(output);
/* Some compilers and libraries successfully
* parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
* We are trying to provide a unified behaviour,
* so we just forbid such conversions (as some
* of the most popular compilers/libraries do)
* */
CharT const minus = lcast_char_constants<CharT>::minus;
CharT const plus = lcast_char_constants<CharT>::plus;
CharT const capital_e = lcast_char_constants<CharT>::capital_e;
CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
if ( return_value &&
(
Traits::eq(*(finish-1), lowercase_e) // 1.0e
|| Traits::eq(*(finish-1), capital_e) // 1.0E
|| Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E-
|| Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+
)
) return false;
return return_value;
}
public:
bool stream_out(float& output) { return float_types_converter_internal(output); }
bool stream_out(double& output) { return float_types_converter_internal(output); }
bool stream_out(long double& output) { return float_types_converter_internal(output); }
// Generic istream-based algorithm.
// lcast_streambuf_for_target<InputStreamable>::value is true.
template <typename InputStreamable>
bool stream_out(InputStreamable& output) {
return shr_using_base_class(output);
}
};
}}} // namespace boost::detail::lcast
#undef BOOST_LCAST_NO_WCHAR_T
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
@@ -0,0 +1,190 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2016
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_NUMERIC_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_NUMERIC_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <type_traits>
#include <boost/core/cmath.hpp>
#include <boost/limits.hpp>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/lexical_cast/detail/type_traits.hpp>
namespace boost { namespace detail {
template <class Source, class Target>
bool ios_numeric_comparer_float(Source x, Source y) noexcept {
return x == y
|| (boost::core::isnan(x) && boost::core::isnan(y))
|| (x < (std::numeric_limits<Target>::min)())
;
}
template <class RangeType, class T>
constexpr bool is_out_of_range_for(T value) noexcept {
return value > static_cast<T>((std::numeric_limits<RangeType>::max)())
|| value < static_cast<T>((std::numeric_limits<RangeType>::min)())
|| boost::core::isnan(value);
}
// integral -> integral
template <typename Target, typename Source>
typename std::enable_if<
!std::is_floating_point<Source>::value && !std::is_floating_point<Target>::value, bool
>::type noexcept_numeric_convert(Source arg, Target& result) noexcept {
const Target target_tmp = static_cast<Target>(arg);
const Source arg_restored = static_cast<Source>(target_tmp);
if (arg == arg_restored) {
result = target_tmp;
return true;
}
return false;
}
// integral -> floating point
template <typename Target, typename Source>
typename std::enable_if<
!std::is_floating_point<Source>::value && std::is_floating_point<Target>::value, bool
>::type noexcept_numeric_convert(Source arg, Target& result) noexcept {
const Target target_tmp = static_cast<Target>(arg);
result = target_tmp;
return true;
}
// floating point -> floating point
template <typename Target, typename Source>
typename std::enable_if<
std::is_floating_point<Source>::value && std::is_floating_point<Target>::value, bool
>::type noexcept_numeric_convert(Source arg, Target& result) noexcept {
const Target target_tmp = static_cast<Target>(arg);
const Source arg_restored = static_cast<Source>(target_tmp);
if (detail::ios_numeric_comparer_float<Source, Target>(arg, arg_restored)) {
result = target_tmp;
return true;
}
return false;
}
// floating point -> integral
template <typename Target, typename Source>
typename std::enable_if<
std::is_floating_point<Source>::value && !std::is_floating_point<Target>::value, bool
>::type noexcept_numeric_convert(Source arg, Target& result) noexcept {
if (detail::is_out_of_range_for<Target>(arg)) {
return false;
}
const Target target_tmp = static_cast<Target>(arg);
const Source arg_restored = static_cast<Source>(target_tmp);
if (arg == arg_restored /* special values are handled in detail::is_out_of_range_for */) {
result = target_tmp;
return true;
}
return false;
}
struct lexical_cast_dynamic_num_not_ignoring_minus
{
template <typename Target, typename Source>
static inline bool try_convert(Source arg, Target& result) noexcept {
return boost::detail::noexcept_numeric_convert<Target, Source >(arg, result);
}
};
struct lexical_cast_dynamic_num_ignoring_minus
{
template <typename Target, typename Source>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
static inline bool try_convert(Source arg, Target& result) noexcept {
typedef typename std::conditional<
std::is_floating_point<Source>::value,
std::conditional<true, Source, Source>, // std::type_identity emulation
boost::detail::lcast::make_unsigned<Source>
>::type usource_lazy_t;
typedef typename usource_lazy_t::type usource_t;
if (arg < 0) {
const bool res = boost::detail::noexcept_numeric_convert<Target, usource_t>(
static_cast<usource_t>(0u - static_cast<usource_t>(arg)), result
);
result = static_cast<Target>(0u - result);
return res;
} else {
return boost::detail::noexcept_numeric_convert<Target, usource_t>(arg, result);
}
}
};
/*
* dynamic_num_converter_impl follows the rules:
* 1) If Source can be converted to Target without precision loss and
* without overflows, then assign Source to Target and return
*
* 2) If Source is less than 0 and Target is an unsigned integer,
* then negate Source, check the requirements of rule 1) and if
* successful, assign static_casted Source to Target and return
*
* 3) Otherwise throw a bad_lexical_cast exception
*
*
* Rule 2) required because boost::lexical_cast has the behavior of
* stringstream, which uses the rules of scanf for conversions. And
* in the C99 standard for unsigned input value minus sign is
* optional, so if a negative number is read, no errors will arise
* and the result will be the two's complement.
*/
template <typename Target, typename Source>
struct dynamic_num_converter_impl
{
static inline bool try_convert(Source arg, Target& result) noexcept {
typedef typename std::conditional<
boost::detail::lcast::is_unsigned<Target>::value &&
(boost::detail::lcast::is_signed<Source>::value || std::is_floating_point<Source>::value) &&
!(std::is_same<Source, bool>::value) &&
!(std::is_same<Target, bool>::value),
lexical_cast_dynamic_num_ignoring_minus,
lexical_cast_dynamic_num_not_ignoring_minus
>::type caster_type;
return caster_type::try_convert(arg, result);
}
};
}} // namespace boost::detail
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_NUMERIC_HPP
@@ -0,0 +1,195 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
#define BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <boost/limits.hpp>
#include <boost/config/workaround.hpp>
#include <boost/core/cmath.hpp>
#include <cstddef>
#include <cstring>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
namespace boost {
namespace detail
{
template <class CharT>
bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) noexcept {
for( unsigned int i=0; i < len; ++i ) {
if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false;
}
return true;
}
/* Returns true and sets the correct value if found NaN or Inf. */
template <class CharT, class T>
inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
, const CharT* lc_NAN, const CharT* lc_nan
, const CharT* lc_INFINITY, const CharT* lc_infinity
, const CharT opening_brace, const CharT closing_brace) noexcept
{
if (begin == end) return false;
const CharT minus = lcast_char_constants<CharT>::minus;
const CharT plus = lcast_char_constants<CharT>::plus;
const int inifinity_size = 8; // == sizeof("infinity") - 1
/* Parsing +/- */
bool const has_minus = (*begin == minus);
if (has_minus || *begin == plus) {
++ begin;
}
if (end - begin < 3) return false;
if (lc_iequal(begin, lc_nan, lc_NAN, 3)) {
begin += 3;
if (end != begin) {
/* It is 'nan(...)' or some bad input*/
if (end - begin < 2) return false; // bad input
-- end;
if (*begin != opening_brace || *end != closing_brace) return false; // bad input
}
if( !has_minus ) value = std::numeric_limits<T>::quiet_NaN();
else value = boost::core::copysign(std::numeric_limits<T>::quiet_NaN(), static_cast<T>(-1));
return true;
} else if (
( /* 'INF' or 'inf' */
end - begin == 3 // 3 == sizeof('inf') - 1
&& lc_iequal(begin, lc_infinity, lc_INFINITY, 3)
)
||
( /* 'INFINITY' or 'infinity' */
end - begin == inifinity_size
&& lc_iequal(begin, lc_infinity, lc_INFINITY, inifinity_size)
)
)
{
if( !has_minus ) value = std::numeric_limits<T>::infinity();
else value = -std::numeric_limits<T>::infinity();
return true;
}
return false;
}
template <class CharT, class T>
const CharT* get_inf_nan_impl(T value
, const CharT* lc_nan
, const CharT* lc_minus_nan
, const CharT* lc_infinity
, const CharT* lc_minus_infinity) noexcept
{
if (boost::core::isnan(value)) {
if (boost::core::signbit(value)) {
return lc_minus_nan;
}
return lc_nan;
} else if (boost::core::isinf(value)) {
if (boost::core::signbit(value)) {
return lc_minus_infinity;
}
return lc_infinity;
}
return nullptr;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
template <class T>
bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) noexcept {
return parse_inf_nan_impl(begin, end, value
, L"NAN", L"nan"
, L"INFINITY", L"infinity"
, L'(', L')');
}
template <class T>
const wchar_t* get_inf_nan(T value, wchar_t) noexcept {
return detail::get_inf_nan_impl(value, L"nan", L"-nan", L"inf", L"-inf");
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
template <class T>
bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) noexcept {
return parse_inf_nan_impl(begin, end, value
, u"NAN", u"nan"
, u"INFINITY", u"infinity"
, u'(', u')');
}
template <class T>
const char16_t* get_inf_nan(T value, char16_t) noexcept {
return detail::get_inf_nan_impl(value, u"nan", u"-nan", u"inf", u"-inf");
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
template <class T>
bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) noexcept {
return parse_inf_nan_impl(begin, end, value
, U"NAN", U"nan"
, U"INFINITY", U"infinity"
, U'(', U')');
}
template <class T>
const char32_t* get_inf_nan(T value, char32_t) noexcept {
return detail::get_inf_nan_impl(value, U"nan", U"-nan", U"inf", U"-inf");
}
#endif
template <class CharT, class T>
bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) noexcept {
return parse_inf_nan_impl(begin, end, value
, "NAN", "nan"
, "INFINITY", "infinity"
, '(', ')');
}
template <class T>
const char* get_inf_nan(T value, char) noexcept {
return detail::get_inf_nan_impl(value, "nan", "-nan", "inf", "-inf");
}
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_INF_NAN_HPP
@@ -0,0 +1,60 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP
#define BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <type_traits>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
namespace boost { namespace detail {
// returns true, if T is one of the character types
template < typename T >
using is_character = std::integral_constant<
bool,
std::is_same< T, char >::value ||
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
std::is_same< T, wchar_t >::value ||
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
std::is_same< T, char16_t >::value ||
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
std::is_same< T, char32_t >::value ||
#endif
std::is_same< T, unsigned char >::value ||
std::is_same< T, signed char >::value
>;
}}
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_IS_CHARACTER_HPP
@@ -0,0 +1,82 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_BASIC_UNLOCKEDBUF_HPP
#define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_BASIC_UNLOCKEDBUF_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif
#include <boost/detail/basic_pointerbuf.hpp>
#ifndef BOOST_NO_CWCHAR
# include <cwchar>
#endif
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
namespace boost { namespace detail { namespace lcast {
// acts as a stream buffer which wraps around a pair of pointers
// and gives acces to internals
template <class BufferType, class CharT>
class basic_unlockedbuf : public basic_pointerbuf<CharT, BufferType> {
public:
typedef basic_pointerbuf<CharT, BufferType> base_type;
typedef typename base_type::streamsize streamsize;
using base_type::pptr;
using base_type::pbase;
using base_type::setbuf;
};
#if defined(BOOST_NO_STRINGSTREAM)
template <class CharT, class Traits>
using out_stream_t = std::ostream;
template <class CharT, class Traits>
using stringbuffer_t = basic_unlockedbuf<std::strstreambuf, char>;
#elif defined(BOOST_NO_STD_LOCALE)
template <class CharT, class Traits>
using out_stream_t = std::ostream;
template <class CharT, class Traits>
using stringbuffer_t = basic_unlockedbuf<std::stringbuf, char>;
template <class CharT, class Traits>
using buffer_t = basic_unlockedbuf<std::streambuf, char>;
#else
template <class CharT, class Traits>
using out_stream_t = std::basic_ostream<CharT, Traits>;
template <class CharT, class Traits>
using stringbuffer_t = basic_unlockedbuf<std::basic_stringbuf<CharT, Traits>, CharT>;
template <class CharT, class Traits>
using buffer_t = basic_unlockedbuf<std::basic_streambuf<CharT, Traits>, CharT>;
#endif
}}} // namespace boost::detail::lcast
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_BASIC_UNLOCKEDBUF_HPP
@@ -0,0 +1,53 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_LCAST_CHAR_CONSTANTS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_LCAST_CHAR_CONSTANTS_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
namespace boost
{
namespace detail // '0', '-', '+', 'e', 'E' and '.' constants
{
template < typename Char >
struct lcast_char_constants {
// We check in tests assumption that static casted character is
// equal to correctly written C++ literal: U'0' == static_cast<char32_t>('0')
BOOST_STATIC_CONSTANT(Char, zero = static_cast<Char>('0'));
BOOST_STATIC_CONSTANT(Char, minus = static_cast<Char>('-'));
BOOST_STATIC_CONSTANT(Char, plus = static_cast<Char>('+'));
BOOST_STATIC_CONSTANT(Char, lowercase_e = static_cast<Char>('e'));
BOOST_STATIC_CONSTANT(Char, capital_e = static_cast<Char>('E'));
BOOST_STATIC_CONSTANT(Char, c_decimal_separator = static_cast<Char>('.'));
};
}
} // namespace boost
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_LCAST_CHAR_CONSTANTS_HPP
@@ -0,0 +1,95 @@
// Copyright Alexander Nasonov & Paul A. Bristow 2006.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <climits>
#include <ios>
#include <limits>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
namespace boost { namespace detail {
// Calculate an argument to pass to std::ios_base::precision from
// lexical_cast.
template<class T>
struct lcast_precision
{
using limits = std::numeric_limits<T>;
static constexpr bool use_default_precision =
!limits::is_specialized || limits::is_exact
;
static constexpr bool is_specialized_bin =
!use_default_precision &&
limits::radix == 2 && limits::digits > 0
;
static constexpr bool is_specialized_dec =
!use_default_precision &&
limits::radix == 10 && limits::digits10 > 0
;
static constexpr std::streamsize streamsize_max =
(std::numeric_limits<std::streamsize>::max)()
;
static constexpr unsigned int precision_dec = limits::digits10 + 1U;
static_assert(!is_specialized_dec ||
precision_dec <= streamsize_max + 0UL
, "");
static constexpr unsigned long precision_bin =
2UL + limits::digits * 30103UL / 100000UL
;
static_assert(!is_specialized_bin ||
(limits::digits + 0UL < ULONG_MAX / 30103UL &&
precision_bin > limits::digits10 + 0UL &&
precision_bin <= streamsize_max + 0UL)
, "");
static constexpr std::streamsize value =
is_specialized_bin ? precision_bin
: is_specialized_dec ? precision_dec : 6
;
};
template<class T>
inline void lcast_set_precision(std::ios_base& stream, T*)
{
stream.precision(lcast_precision<T>::value);
}
template<class Source, class Target>
inline void lcast_set_precision(std::ios_base& stream, Source*, Target*)
{
std::streamsize const s = lcast_precision<Source>::value;
std::streamsize const t = lcast_precision<Target*>::value;
stream.precision(s > t ? s : t);
}
}}
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED
@@ -0,0 +1,308 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_LCAST_UNSIGNED_CONVERTERS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_LCAST_UNSIGNED_CONVERTERS_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <climits>
#include <cstddef>
#include <string>
#include <cstring>
#include <cstdio>
#include <type_traits>
#include <boost/limits.hpp>
#include <boost/config/workaround.hpp>
#include <boost/lexical_cast/detail/type_traits.hpp>
#ifndef BOOST_NO_STD_LOCALE
# include <locale>
#else
# ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
// Getting error at this point means, that your STL library is old/lame/misconfigured.
// If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
// but beware: lexical_cast will understand only 'C' locale delimeters and thousands
// separators.
# error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
# error "boost::lexical_cast to use only 'C' locale during conversions."
# endif
#endif
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
#include <boost/core/noncopyable.hpp>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
namespace boost
{
namespace detail // lcast_to_unsigned
{
template<class T>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
inline
typename boost::detail::lcast::make_unsigned<T>::type lcast_to_unsigned(const T value) noexcept {
typedef typename boost::detail::lcast::make_unsigned<T>::type result_type;
return value < 0
? static_cast<result_type>(0u - static_cast<result_type>(value))
: static_cast<result_type>(value);
}
}
namespace detail // lcast_put_unsigned
{
template <class Traits, class T, class CharT>
class lcast_put_unsigned: boost::noncopyable {
typedef typename Traits::int_type int_type;
typename std::conditional<
(sizeof(unsigned) > sizeof(T))
, unsigned
, T
>::type m_value;
CharT* m_finish;
CharT const m_czero;
int_type const m_zero;
public:
lcast_put_unsigned(const T n_param, CharT* finish) noexcept
: m_value(n_param), m_finish(finish)
, m_czero(lcast_char_constants<CharT>::zero), m_zero(Traits::to_int_type(m_czero))
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
static_assert(!std::numeric_limits<T>::is_signed, "");
#endif
}
CharT* convert() {
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
std::locale loc;
if (loc == std::locale::classic()) {
return main_convert_loop();
}
typedef std::numpunct<CharT> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, loc);
std::string const grouping = np.grouping();
std::string::size_type const grouping_size = grouping.size();
if (!grouping_size || grouping[0] <= 0) {
return main_convert_loop();
}
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
// Check that ulimited group is unreachable:
static_assert(std::numeric_limits<T>::digits10 < CHAR_MAX, "");
#endif
CharT const thousands_sep = np.thousands_sep();
std::string::size_type group = 0; // current group number
char last_grp_size = grouping[0];
char left = last_grp_size;
do {
if (left == 0) {
++group;
if (group < grouping_size) {
char const grp_size = grouping[group];
last_grp_size = (grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size);
}
left = last_grp_size;
--m_finish;
Traits::assign(*m_finish, thousands_sep);
}
--left;
} while (main_convert_iteration());
return m_finish;
#else
return main_convert_loop();
#endif
}
private:
inline bool main_convert_iteration() noexcept {
--m_finish;
int_type const digit = static_cast<int_type>(m_value % 10U);
Traits::assign(*m_finish, Traits::to_char_type(m_zero + digit));
m_value /= 10;
return !!m_value; // suppressing warnings
}
inline CharT* main_convert_loop() noexcept {
while (main_convert_iteration());
return m_finish;
}
};
}
namespace detail // lcast_ret_unsigned
{
template <class Traits, class T, class CharT>
class lcast_ret_unsigned: boost::noncopyable {
bool m_multiplier_overflowed;
T m_multiplier;
T& m_value;
const CharT* const m_begin;
const CharT* m_end;
public:
lcast_ret_unsigned(T& value, const CharT* const begin, const CharT* end) noexcept
: m_multiplier_overflowed(false), m_multiplier(1), m_value(value), m_begin(begin), m_end(end)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
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
static_assert(std::numeric_limits<T>::is_specialized,
"std::numeric_limits are not specialized for integral type passed to boost::lexical_cast"
);
#endif
}
inline bool convert() {
CharT const czero = lcast_char_constants<CharT>::zero;
--m_end;
m_value = static_cast<T>(0);
if (m_begin > m_end || *m_end < czero || *m_end >= czero + 10)
return false;
m_value = static_cast<T>(*m_end - czero);
--m_end;
#ifdef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
return main_convert_loop();
#else
std::locale loc;
if (loc == std::locale::classic()) {
return main_convert_loop();
}
typedef std::numpunct<CharT> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, loc);
std::string const& grouping = np.grouping();
std::string::size_type const grouping_size = grouping.size();
/* According to Programming languages - C++
* we MUST check for correct grouping
*/
if (!grouping_size || grouping[0] <= 0) {
return main_convert_loop();
}
unsigned char current_grouping = 0;
CharT const thousands_sep = np.thousands_sep();
char remained = static_cast<char>(grouping[current_grouping] - 1);
for (;m_end >= m_begin; --m_end)
{
if (remained) {
if (!main_convert_iteration()) {
return false;
}
--remained;
} else {
if ( !Traits::eq(*m_end, thousands_sep) ) //|| begin == end ) return false;
{
/*
* According to Programming languages - C++
* Digit grouping is checked. That is, the positions of discarded
* separators is examined for consistency with
* use_facet<numpunct<charT> >(loc ).grouping()
*
* BUT what if there is no separators at all and grouping()
* is not empty? Well, we have no extraced separators, so we
* won`t check them for consistency. This will allow us to
* work with "C" locale from other locales
*/
return main_convert_loop();
} else {
if (m_begin == m_end) return false;
if (current_grouping < grouping_size - 1) ++current_grouping;
remained = grouping[current_grouping];
}
}
} /*for*/
return true;
#endif
}
private:
// Iteration that does not care about grouping/separators and assumes that all
// input characters are digits
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
inline bool main_convert_iteration() noexcept {
CharT const czero = lcast_char_constants<CharT>::zero;
T const maxv = (std::numeric_limits<T>::max)();
m_multiplier_overflowed = m_multiplier_overflowed || (maxv/10 < m_multiplier);
m_multiplier = static_cast<T>(m_multiplier * 10);
T const dig_value = static_cast<T>(*m_end - czero);
T const new_sub_value = static_cast<T>(m_multiplier * dig_value);
// We must correctly handle situations like `000000000000000000000000000001`.
// So we take care of overflow only if `dig_value` is not '0'.
if (*m_end < czero || *m_end >= czero + 10 // checking for correct digit
|| (dig_value && ( // checking for overflow of ...
m_multiplier_overflowed // ... multiplier
|| static_cast<T>(maxv / dig_value) < m_multiplier // ... subvalue
|| static_cast<T>(maxv - new_sub_value) < m_value // ... whole expression
))
) return false;
m_value = static_cast<T>(m_value + new_sub_value);
return true;
}
bool main_convert_loop() noexcept {
for ( ; m_end >= m_begin; --m_end) {
if (!main_convert_iteration()) {
return false;
}
}
return true;
}
};
}
} // namespace boost
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_LCAST_UNSIGNED_CONVERTERS_HPP
@@ -0,0 +1,81 @@
// Copyright Peter Dimov, 2025.
// Copyright Romain Geissler, 2025.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXICAL_CAST_DETAIL_TYPE_TRAITS_HPP
#define BOOST_LEXICAL_CAST_DETAIL_TYPE_TRAITS_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <type_traits>
namespace boost { namespace detail { namespace lcast {
// libstdc++ from gcc <= 15 doesn't provide support for __int128 in the standard traits,
// so define them explicitly.
// This was fixed with gcc >= 16, so we may eventually remove this workaround and use
// directly the standard type_traits.
template<class T> struct is_integral: public std::is_integral<T>
{
};
template<class T> struct is_signed: public std::is_signed<T>
{
};
template<class T> struct is_unsigned: public std::is_unsigned<T>
{
};
template<class T> struct make_unsigned: public std::make_unsigned<T>
{
};
#if defined(__SIZEOF_INT128__)
template<> struct is_integral<__int128_t>: public std::true_type
{
};
template<> struct is_integral<__uint128_t>: public std::true_type
{
};
template<> struct is_signed<__int128_t>: public std::true_type
{
};
template<> struct is_signed<__uint128_t>: public std::false_type
{
};
template<> struct is_unsigned<__int128_t>: public std::false_type
{
};
template<> struct is_unsigned<__uint128_t>: public std::true_type
{
};
template<> struct make_unsigned<__int128_t>
{
typedef __uint128_t type;
};
template<> struct make_unsigned<__uint128_t>
{
typedef __uint128_t type;
};
#endif
}}} // namespace boost::detail::lcast
#endif // BOOST_LEXICAL_CAST_DETAIL_TYPE_TRAITS_HPP
@@ -0,0 +1,49 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_DETAIL_WIDEST_CHAR_HPP
#define BOOST_LEXICAL_CAST_DETAIL_WIDEST_CHAR_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <type_traits>
#endif // #ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
namespace boost { namespace detail {
template <typename TargetChar, typename SourceChar>
using widest_char = std::conditional<
(sizeof(TargetChar) > sizeof(SourceChar))
, TargetChar
, SourceChar
>;
}} // namespace boost::detail
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_DETAIL_WIDEST_CHAR_HPP
@@ -0,0 +1,105 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP
#define BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP
#include <boost/lexical_cast/detail/config.hpp>
#if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#ifndef BOOST_LEXICAL_CAST_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <type_traits>
#endif
#include <boost/lexical_cast/detail/buffer_view.hpp>
#include <boost/lexical_cast/detail/is_character.hpp>
#include <boost/lexical_cast/detail/converter_numeric.hpp>
#include <boost/lexical_cast/detail/converter_lexical.hpp>
namespace boost {
namespace detail
{
template<typename Target, typename Source>
using is_arithmetic_and_not_xchars = std::integral_constant<
bool,
!(boost::detail::is_character<Target>::value) &&
!(boost::detail::is_character<Source>::value) &&
std::is_arithmetic<Source>::value &&
std::is_arithmetic<Target>::value
>;
}
namespace conversion { namespace detail {
BOOST_LEXICAL_CAST_BEGIN_MODULE_EXPORT
template <typename Target, typename Source>
inline bool try_lexical_convert(const Source& arg, Target& result)
{
static_assert(
!std::is_volatile<Source>::value,
"Boost.LexicalCast does not support volatile input");
typedef typename boost::detail::array_to_pointer_decay<Source>::type src;
typedef boost::detail::is_arithmetic_and_not_xchars<Target, src >
shall_we_copy_with_dynamic_check_t;
typedef typename std::conditional<
shall_we_copy_with_dynamic_check_t::value,
boost::detail::dynamic_num_converter_impl<Target, src >,
boost::detail::lexical_converter_impl<Target, src >
>::type caster_type;
return caster_type::try_convert(arg, result);
}
template <typename Target, typename CharacterT>
inline bool try_lexical_convert(const CharacterT* chars, std::size_t count, Target& result)
{
static_assert(
boost::detail::is_character<CharacterT>::value,
"This overload of try_lexical_convert is meant to be used only with arrays of characters."
);
return ::boost::conversion::detail::try_lexical_convert(
::boost::conversion::detail::make_buffer_view(chars, chars + count),
result
);
}
BOOST_LEXICAL_CAST_END_MODULE_EXPORT
}} // namespace conversion::detail
namespace conversion {
BOOST_LEXICAL_CAST_BEGIN_MODULE_EXPORT
// ADL barrier
using ::boost::conversion::detail::try_lexical_convert;
BOOST_LEXICAL_CAST_END_MODULE_EXPORT
}
} // namespace boost
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_LEXICAL_CAST_INTERFACE_UNIT)
#endif // BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP
+11 -44
View File
@@ -1,49 +1,16 @@
<!--
Copyright 2005-2007 Daniel James.
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)
-->
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<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>
<meta http-equiv="refresh" content="0; URL=../../doc/html/boost_lexical_cast.html">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img border="0" src="../../boost.png" align="center" width="277" height="86">Boost
Conversion Library</h1>
<p>The Conversion Library improves program safety and clarity by performing
otherwise messy conversions.&nbsp; It includes cast-style function templates designed to complement the C++
Standard's built-in casts.</p>
<p>To reduce coupling, particularly to standard library IOStreams, the Boost
Conversion Library is
supplied by several headers:</p>
<ul>
<li>The <a href="cast.htm">boost/cast</a> header provides <b>polymorphic_cast&lt;&gt;</b>
and <b>polymorphic_downcast&lt;&gt;</b> to perform safe casting between
polymorphic types.<br>
</li>
<li>The <a href="../../doc/html/boost_lexical_cast.html">boost/lexical_cast</a> header provides <b>lexical_cast&lt;&gt;</b>
general literal text conversions, such as an <code>int</code> represented as
a <code>string</code>, or vice-versa.</li>
</ul>
<hr>
<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>
Automatic redirection failed, please go to
<a href="../../doc/html/boost_lexical_cast.html">../../doc/html/boost_lexical_cast.html</a>
</body>
</html>
-16
View File
@@ -1,16 +0,0 @@
<!--
Copyright 2005-2007 Daniel James.
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)
-->
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../doc/html/boost_lexical_cast.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="../../doc/html/boost_lexical_cast.html">../../doc/html/boost_lexical_cast.html</a>
</body>
</html>
-622
View File
@@ -1,622 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Terje Sletteb and Kevlin Henney, 2005.
// Copyright Alexander Nasonov, 2006.
// Copyright Antony Polukhin, 2011-2012.
//
// 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).
//
// Note: The unit test no longer compile on MSVC 6, but lexical_cast itself works for it.
//
// We need this #define before any #includes: otherwise msvc will emit warnings
// deep within std::string, resulting from our (perfectly legal) use of basic_string
// with a custom traits class:
//
#define _SCL_SECURE_NO_WARNINGS
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/cstdint.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#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)) \
&& !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
#define LCAST_TEST_LONGLONG
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
template<class CharT>
struct my_traits : std::char_traits<CharT>
{
};
template<class CharT>
struct my_allocator : std::allocator<CharT>
{
};
using namespace boost;
void test_conversion_to_char();
void test_conversion_to_int();
void test_conversion_to_double();
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_from_wchar_t();
void test_conversion_to_wchar_t();
void test_conversion_from_wstring();
void test_conversion_to_wstring();
void test_bad_lexical_cast();
void test_no_whitespace_stripping();
void test_volatile_types_conversions();
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
void test_traits();
void test_wtraits();
void test_allocator();
void test_wallocator();
#endif
void test_char_types_conversions();
void operators_overload_test();
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
void test_char16_conversions();
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
void test_char32_conversions();
#endif
void test_getting_pointer_to_function();
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_conversion_to_char));
suite->add(BOOST_TEST_CASE(test_conversion_to_int));
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_string));
suite->add(BOOST_TEST_CASE(test_conversion_with_nonconst_char));
#ifndef BOOST_LCAST_NO_WCHAR_T
suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t));
suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t));
suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
#endif
suite->add(BOOST_TEST_CASE(test_bad_lexical_cast));
suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping));
suite->add(BOOST_TEST_CASE(test_volatile_types_conversions));
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
suite->add(BOOST_TEST_CASE(&test_traits));
suite->add(BOOST_TEST_CASE(&test_wtraits));
suite->add(BOOST_TEST_CASE(&test_allocator));
suite->add(BOOST_TEST_CASE(&test_wallocator));
#endif
suite->add(BOOST_TEST_CASE(&test_char_types_conversions));
suite->add(BOOST_TEST_CASE(&operators_overload_test));
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
suite->add(BOOST_TEST_CASE(&test_char16_conversions));
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
suite->add(BOOST_TEST_CASE(&test_char32_conversions));
#endif
suite->add(BOOST_TEST_CASE(&test_getting_pointer_to_function));
return suite;
}
void test_conversion_to_char()
{
BOOST_CHECK_EQUAL('A', lexical_cast<char>('A'));
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(' '));
BOOST_CHECK_EQUAL('1', lexical_cast<char>(1));
BOOST_CHECK_EQUAL('0', lexical_cast<char>(0));
BOOST_CHECK_THROW(lexical_cast<char>(123), bad_lexical_cast);
BOOST_CHECK_EQUAL('1', lexical_cast<char>(1.0));
BOOST_CHECK_EQUAL('1', lexical_cast<char>(true));
BOOST_CHECK_EQUAL('0', lexical_cast<char>(false));
BOOST_CHECK_EQUAL('A', lexical_cast<char>("A"));
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(" "));
BOOST_CHECK_THROW(lexical_cast<char>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<char>("Test"), bad_lexical_cast);
BOOST_CHECK_EQUAL('A', lexical_cast<char>(std::string("A")));
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(std::string(" ")));
BOOST_CHECK_THROW(
lexical_cast<char>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<char>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_to_int()
{
BOOST_CHECK_EQUAL(1, lexical_cast<int>('1'));
BOOST_CHECK_EQUAL(0, lexical_cast<int>('0'));
BOOST_CHECK_THROW(lexical_cast<int>('A'), bad_lexical_cast);
BOOST_CHECK_EQUAL(1, lexical_cast<int>(1));
BOOST_CHECK_EQUAL(1, lexical_cast<int>(1.0));
BOOST_CHECK_EQUAL(
(std::numeric_limits<int>::max)(),
lexical_cast<int>((std::numeric_limits<int>::max)()));
BOOST_CHECK_EQUAL(
(std::numeric_limits<int>::min)(),
lexical_cast<int>((std::numeric_limits<int>::min)()));
BOOST_CHECK_THROW(lexical_cast<int>(1.23), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(1e20), bad_lexical_cast);
BOOST_CHECK_EQUAL(1, lexical_cast<int>(true));
BOOST_CHECK_EQUAL(0, lexical_cast<int>(false));
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
BOOST_CHECK_THROW(
lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>("Test"), bad_lexical_cast);
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::string("123")));
BOOST_CHECK_THROW(
lexical_cast<int>(std::string(" 123")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_with_nonconst_char()
{
std::vector<char> buffer;
buffer.push_back('1');
buffer.push_back('\0');
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer[0]), 1);
std::vector<unsigned char> buffer2;
buffer2.push_back('1');
buffer2.push_back('\0');
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer2[0]), 1);
std::vector<unsigned char> buffer3;
buffer3.push_back('1');
buffer3.push_back('\0');
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer3[0]), 1);
#ifndef BOOST_LCAST_NO_WCHAR_T
std::vector<wchar_t> buffer4;
buffer4.push_back(L'1');
buffer4.push_back(L'\0');
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(&buffer4[0]), 1);
#endif
}
void test_conversion_to_double()
{
BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>('1'), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_THROW(lexical_cast<double>('A'), bad_lexical_cast);
BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>(1), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>(1.23), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE_FRACTION(1.234567890, lexical_cast<double>(1.234567890), std::numeric_limits<double>::epsilon());
BOOST_CHECK_CLOSE_FRACTION(1.234567890, lexical_cast<double>("1.234567890"), std::numeric_limits<double>::epsilon());
BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<double>(true), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE_FRACTION(0.0, lexical_cast<double>(false), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>("1.23"), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_THROW(lexical_cast<double>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>("Test"), bad_lexical_cast);
BOOST_CHECK_CLOSE_FRACTION(1.23, lexical_cast<double>(std::string("1.23")), (std::numeric_limits<double>::epsilon()));
BOOST_CHECK_THROW(
lexical_cast<double>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<double>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_to_bool()
{
BOOST_CHECK_EQUAL(true, lexical_cast<bool>('1'));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>('0'));
BOOST_CHECK_THROW(lexical_cast<bool>('A'), bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0));
BOOST_CHECK_THROW(lexical_cast<bool>(123), bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1.0));
BOOST_CHECK_THROW(lexical_cast<bool>(-123), bad_lexical_cast);
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0.0));
BOOST_CHECK_THROW(lexical_cast<bool>(1234), bad_lexical_cast);
#if !defined(_CRAYC)
// Looks like a bug in CRAY compiler (throws bad_lexical_cast)
// TODO: localize the bug and report it to developers.
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(true));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(false));
#endif
BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
BOOST_CHECK_THROW(lexical_cast<bool>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("Test"), bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
BOOST_CHECK_THROW(lexical_cast<bool>(1.0001L), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(2), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(2u), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(-1), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(-2), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
BOOST_CHECK(lexical_cast<bool>("+1") == true );
BOOST_CHECK(lexical_cast<bool>("+0") == false );
BOOST_CHECK(lexical_cast<bool>("-0") == false );
BOOST_CHECK_THROW(lexical_cast<bool>("--0"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>("-+-0"), bad_lexical_cast);
}
void test_conversion_to_string()
{
char buf[] = "hello";
char* str = buf;
BOOST_CHECK_EQUAL(str, lexical_cast<std::string>(str));
BOOST_CHECK_EQUAL("A", lexical_cast<std::string>('A'));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(' '));
BOOST_CHECK_EQUAL("123", lexical_cast<std::string>(123));
BOOST_CHECK_EQUAL("1.23", lexical_cast<std::string>(1.23));
BOOST_CHECK_EQUAL("1.111111111", lexical_cast<std::string>(1.111111111));
BOOST_CHECK_EQUAL("1", lexical_cast<std::string>(true));
BOOST_CHECK_EQUAL("0", lexical_cast<std::string>(false));
BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>("Test"));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(" "));
BOOST_CHECK_EQUAL("", lexical_cast<std::string>(""));
BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>(std::string("Test")));
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(std::string(" ")));
BOOST_CHECK_EQUAL("", lexical_cast<std::string>(std::string("")));
}
void test_conversion_from_to_wchar_t_alias()
{
BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned short>("123"));
BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned int>("123"));
BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned long>("123"));
BOOST_CHECK_EQUAL(std::string("123"),
lexical_cast<std::string>(static_cast<unsigned short>(123)));
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123u));
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123ul));
}
void test_conversion_from_wchar_t()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
BOOST_CHECK_THROW(lexical_cast<int>(L'A'), bad_lexical_cast);
#endif
BOOST_CHECK_EQUAL(123, lexical_cast<int>(L"123"));
BOOST_CHECK_THROW(lexical_cast<int>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>(L"Test"), bad_lexical_cast);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(L'1'));
BOOST_CHECK_THROW(lexical_cast<double>(L'A'), bad_lexical_cast);
#endif
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(L"1.23"));
BOOST_CHECK_THROW(lexical_cast<double>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<double>(L"Test"), bad_lexical_cast);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L'1'));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L'0'));
BOOST_CHECK_THROW(lexical_cast<bool>(L'A'), bad_lexical_cast);
#endif
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L"1"));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L"0"));
BOOST_CHECK_THROW(lexical_cast<bool>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<bool>(L"Test"), bad_lexical_cast);
#endif
}
void test_conversion_to_wchar_t()
{
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0));
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>('1'));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>('0'));
BOOST_CHECK_THROW(lexical_cast<wchar_t>(123), bad_lexical_cast);
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1.0));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0.0));
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(true));
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(false));
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L'A'));
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L' '));
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L"A"));
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L" "));
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L"Test"), bad_lexical_cast);
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(std::wstring(L"A")));
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(std::wstring(L" ")));
BOOST_CHECK_THROW(
lexical_cast<wchar_t>(std::wstring(L"")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<wchar_t>(std::wstring(L"Test")), bad_lexical_cast);
#endif
BOOST_CHECK(true);
}
void test_conversion_from_wstring()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
BOOST_CHECK_THROW(
lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<int>(std::wstring(L"Test")), bad_lexical_cast);
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::wstring(L"1")));
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::wstring(L"0")));
BOOST_CHECK_THROW(
lexical_cast<bool>(std::wstring(L"")), bad_lexical_cast);
BOOST_CHECK_THROW(
lexical_cast<bool>(std::wstring(L"Test")), bad_lexical_cast);
#endif
BOOST_CHECK(true);
}
void test_conversion_to_wstring()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
wchar_t buf[] = L"hello";
wchar_t* str = buf;
BOOST_CHECK(str == lexical_cast<std::wstring>(str));
BOOST_CHECK(L"123" == lexical_cast<std::wstring>(123));
BOOST_CHECK(L"1.23" == lexical_cast<std::wstring>(1.23));
BOOST_CHECK(L"1" == lexical_cast<std::wstring>(true));
BOOST_CHECK(L"0" == lexical_cast<std::wstring>(false));
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
BOOST_CHECK(L"A" == lexical_cast<std::wstring>('A'));
#endif
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(L"Test"));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L" "));
BOOST_CHECK(L"" == lexical_cast<std::wstring>(L""));
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
BOOST_CHECK(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
#endif
BOOST_CHECK(true);
}
void test_bad_lexical_cast()
{
try
{
lexical_cast<int>(std::string("Test"));
BOOST_CHECK(false); // Exception expected
}
catch(const bad_lexical_cast &e)
{
BOOST_CHECK(e.source_type() == typeid(std::string));
BOOST_CHECK(e.target_type() == typeid(int));
}
}
void test_no_whitespace_stripping()
{
BOOST_CHECK_THROW(lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<int>("123 "), bad_lexical_cast);
}
void test_volatile_types_conversions()
{
volatile int i1 = 100000;
BOOST_CHECK_EQUAL("100000", boost::lexical_cast<std::string>(i1));
volatile const int i2 = 100000;
BOOST_CHECK_EQUAL("100000", boost::lexical_cast<std::string>(i2));
volatile const long int i3 = 1000000;
BOOST_CHECK_EQUAL("1000000", boost::lexical_cast<std::string>(i3));
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
void test_traits()
{
typedef std::basic_string<char, my_traits<char> > my_string;
my_string const s("s");
BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
BOOST_CHECK(boost::lexical_cast<my_string>(-1) == "-1");
}
void test_wtraits()
{
typedef std::basic_string<wchar_t, my_traits<wchar_t> > my_string;
my_string const s(L"s");
BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
//BOOST_CHECK(boost::lexical_cast<my_string>(-1) == L"-1");
// Commented out because gcc 3.3 doesn't support this:
// basic_ostream<wchar_t, my_traits<wchar_t> > o; o << -1;
}
void test_allocator()
{
// Following test cause compilation error on MSVC2012:
// (Reason: cannot convert from 'std::_Wrap_alloc<_Alloc>' to 'const my_allocator<CharT>')
//
// MSVC developer is notified about this issue
#if !defined(_MSC_VER) || (_MSC_VER < 1700)
typedef std::basic_string< char
, std::char_traits<char>
, my_allocator<char>
> my_string;
my_string s("s");
BOOST_CHECK(boost::lexical_cast<char>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<std::string>(s) == "s");
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
BOOST_CHECK(boost::lexical_cast<my_string>(1) == "1");
BOOST_CHECK(boost::lexical_cast<my_string>("s") == s);
BOOST_CHECK(boost::lexical_cast<my_string>(std::string("s")) == s);
#endif
}
void test_wallocator()
{
// Following test cause compilation error on MSVC2012:
// (Reason: cannot convert from 'std::_Wrap_alloc<_Alloc>' to 'const my_allocator<CharT>')
//
// MSVC developer is notified about this issue
#if !defined(_MSC_VER) || (_MSC_VER < 1700)
typedef std::basic_string< wchar_t
, std::char_traits<wchar_t>
, my_allocator<wchar_t>
> my_string;
my_string s(L"s");
BOOST_CHECK(boost::lexical_cast<wchar_t>(s) == s[0]);
BOOST_CHECK(boost::lexical_cast<std::wstring>(s) == L"s");
BOOST_CHECK(boost::lexical_cast<my_string>(s) == s);
BOOST_CHECK(boost::lexical_cast<my_string>(1) == L"1");
BOOST_CHECK(boost::lexical_cast<my_string>(L"s") == s);
BOOST_CHECK(boost::lexical_cast<my_string>(std::wstring(L"s")) == s);
#endif
}
#endif
void test_char_types_conversions()
{
const char c_arr[] = "Test array of chars";
const unsigned char uc_arr[] = "Test array of chars";
const signed char sc_arr[] = "Test array of chars";
BOOST_CHECK(boost::lexical_cast<std::string>(c_arr) == std::string(c_arr));
BOOST_CHECK(boost::lexical_cast<std::string>(uc_arr) == std::string(c_arr));
BOOST_CHECK(boost::lexical_cast<std::string>(sc_arr) == std::string(c_arr));
BOOST_CHECK(boost::lexical_cast<char>(c_arr[0]) == c_arr[0]);
BOOST_CHECK(boost::lexical_cast<char>(uc_arr[0]) == c_arr[0]);
BOOST_CHECK(boost::lexical_cast<char>(sc_arr[0]) == c_arr[0]);
BOOST_CHECK(boost::lexical_cast<unsigned char>(c_arr[0]) == uc_arr[0]);
BOOST_CHECK(boost::lexical_cast<unsigned char>(uc_arr[0]) == uc_arr[0]);
BOOST_CHECK(boost::lexical_cast<unsigned char>(sc_arr[0]) == uc_arr[0]);
BOOST_CHECK(boost::lexical_cast<signed char>(c_arr[0]) == sc_arr[0]);
BOOST_CHECK(boost::lexical_cast<signed char>(uc_arr[0]) == sc_arr[0]);
BOOST_CHECK(boost::lexical_cast<signed char>(sc_arr[0]) == sc_arr[0]);
#ifndef BOOST_LCAST_NO_WCHAR_T
const wchar_t wc_arr[]=L"Test array of chars";
BOOST_CHECK(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
BOOST_CHECK(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
#endif
}
struct foo_operators_test
{
foo_operators_test() : f(2) {}
int f;
};
template <typename OStream>
OStream& operator<<(OStream& ostr, const foo_operators_test& foo)
{
ostr << foo.f;
return ostr;
}
template <typename IStream>
IStream& operator>>(IStream& istr, foo_operators_test& foo)
{
istr >> foo.f;
return istr;
}
void operators_overload_test()
{
foo_operators_test foo;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(foo), "2");
BOOST_CHECK_EQUAL((boost::lexical_cast<foo_operators_test>("2")).f, 2);
// Must compile
(void)boost::lexical_cast<foo_operators_test>(foo);
}
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
void test_char16_conversions()
{
BOOST_CHECK(u"100" == lexical_cast<std::u16string>(u"100"));
BOOST_CHECK(u"1" == lexical_cast<std::u16string>(u'1'));
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
void test_char32_conversions()
{
BOOST_CHECK(U"100" == lexical_cast<std::u32string>(U"100"));
BOOST_CHECK(U"1" == lexical_cast<std::u32string>(U'1'));
}
#endif
void test_getting_pointer_to_function()
{
// Just checking that &lexical_cast<To, From> is not ambiguous
typedef char char_arr[4];
typedef int(*f1)(const char_arr&);
f1 p1 = &boost::lexical_cast<int, char_arr>;
BOOST_CHECK(p1);
typedef int(*f2)(const std::string&);
f2 p2 = &boost::lexical_cast<int, std::string>;
BOOST_CHECK(p2);
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>);
}
+16
View File
@@ -0,0 +1,16 @@
{
"key": "lexical_cast",
"name": "Lexical Cast",
"authors": [
"Kevlin Henney"
],
"description": "General literal text conversions, such as an int represented a string, or vice-versa.",
"category": [
"Miscellaneous",
"String"
],
"maintainers": [
"Antony Polukhin <antoshkka -at- gmail.com>"
],
"cxxstd": "11"
}
+57
View File
@@ -0,0 +1,57 @@
// Copyright (c) 2016-2025 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)
// To compile manually use a command like the folowing:
// clang++ -I ../include -std=c++20 --precompile -x c++-module boost_lexical_cast.cppm
module;
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/core/cmath.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/core/snprintf.hpp>
#include <boost/limits.hpp>
#include <boost/throw_exception.hpp>
#include <boost/detail/basic_pointerbuf.hpp>
#ifndef BOOST_LEXICAL_CAST_USE_STD_MODULE
#include <array>
#include <climits>
#include <cstddef>
#include <cstdio>
#include <cstring>
#ifndef BOOST_NO_CWCHAR
# include <cwchar>
#endif
#include <exception>
#include <iosfwd>
#include <istream>
#ifndef BOOST_NO_STD_LOCALE
# include <locale>
#endif
#include <sstream>
#include <string>
#include <string_view>
#include <typeinfo>
#include <type_traits>
#endif
#define BOOST_LEXICAL_CAST_INTERFACE_UNIT
export module boost.lexical_cast;
#ifdef BOOST_LEXICAL_CAST_USE_STD_MODULE
import std;
#endif
#ifdef __clang__
# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview"
#endif
#include <boost/lexical_cast.hpp>
+16
View File
@@ -0,0 +1,16 @@
// Copyright (c) 2024-2025 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)
// To compile manually use a command like the following:
// clang++ -std=c++20 -fmodule-file=lexical_cast.pcm lexical_cast.pcm usage_sample.cpp
//[lexical_cast_module_example
import boost.lexical_cast;
int main() {
return boost::lexical_cast<int>("0");
}
//]
-101
View File
@@ -1,101 +0,0 @@
// boost utility cast test program -----------------------------------------//
// (C) Copyright Beman Dawes, Dave Abrahams 1999. 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)
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 28 Set 04 factored out numeric_cast<> test (Fernando Cacciola)
// 20 Jan 01 removed use of <limits> for portability to raw GCC (David Abrahams)
// 28 Jun 00 implicit_cast removed (Beman Dawes)
// 30 Aug 99 value_cast replaced by numeric_cast
// 3 Aug 99 Initial Version
#include <iostream>
#include <climits>
#include <cfloat> // for DBL_MAX (Peter Schmid)
#include <boost/cast.hpp>
#include "boost/test/minimal.hpp"
# if SCHAR_MAX == LONG_MAX
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
# endif
using namespace boost;
using std::cout;
int test_main( int , char * [] )
{
# ifdef NDEBUG
cout << "NDEBUG is defined\n";
# else
cout << "NDEBUG is not defined\n";
# endif
cout << "\nBeginning tests...\n";
// test implicit_cast and numeric_cast -------------------------------------//
// tests which should succeed
long small_value = 1;
long small_negative_value = -1;
long large_value = LONG_MAX;
long large_negative_value = LONG_MIN;
signed char c = 0;
c = static_cast<signed char>(large_value);
c = numeric_cast<signed char>( small_value );
BOOST_CHECK( c == 1 );
c = 0;
c = numeric_cast<signed char>( small_value );
BOOST_CHECK( c == 1 );
c = 0;
c = numeric_cast<signed char>( small_negative_value );
BOOST_CHECK( c == -1 );
// These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@usace.army.mil>
BOOST_CHECK( 0.0f == numeric_cast<float>( 0.0 ) );
BOOST_CHECK( 0.0 == numeric_cast<double>( 0.0 ) );
// tests which should result in errors being detected
bool caught_exception = false;
try { c = numeric_cast<signed char>( large_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; }
BOOST_CHECK ( caught_exception );
caught_exception = false;
try { c = numeric_cast<signed char>( large_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; }
BOOST_CHECK ( caught_exception );
unsigned long ul;
caught_exception = false;
try { ul = numeric_cast<unsigned long>( large_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; }
BOOST_CHECK ( caught_exception );
caught_exception = false;
try { ul = numeric_cast<unsigned long>( small_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; }
BOOST_CHECK ( caught_exception );
caught_exception = false;
try { numeric_cast<int>( DBL_MAX ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
BOOST_CHECK ( caught_exception );
(void)ul; // Supressing GCC warning about set but unused wariable
return 0 ;
}
+1 -1
View File
@@ -1,5 +1,5 @@
#==============================================================================
# Copyright (c) 2012 Antony Polukhin
# Copyright Antony Polukhin, 2012-2026.
#
# 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)
+27 -3
View File
@@ -1,4 +1,4 @@
// (C) Copyright Antony Polukhin 2012.
// (C) Copyright Antony Polukhin, 2012-2026.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -14,10 +14,15 @@
#include <boost/lexical_cast.hpp>
#include <boost/chrono.hpp>
#include <fstream>
#include <cstring>
#include <string_view>
#include <type_traits>
#include <boost/array.hpp>
#include <boost/chrono.hpp>
#include <boost/container/string.hpp>
#include <boost/range/iterator_range.hpp>
// File to output data
std::fstream fout;
@@ -91,6 +96,12 @@ struct structure_sprintf {
sprintf(buffer, conv, in_val.c_str());
OutT out_val(buffer);
}
template <class OutT, class BufferT>
static inline void test(BufferT* buffer, std::string_view in_val, const char* const conv) {
sprintf(buffer, conv, in_val.data()); // in_val is zero terminated in this program
OutT out_val(buffer);
}
};
struct structure_sscanf {
@@ -117,6 +128,12 @@ struct structure_sscanf {
OutT out_val;
sscanf(in_val.begin(), conv, &out_val);
}
template <class OutT, class BufferT>
static inline void test(BufferT* /*buffer*/, std::string_view in_val, const char* const conv) {
OutT out_val;
sscanf(in_val.data(), conv, &out_val); // in_val is zero terminated in this program
}
};
struct structure_fake {
@@ -226,7 +243,7 @@ static inline void perf_test_impl(const FromT& in_val, const char* const conv) {
lexical_cast_time.count(),
ss_constr_time.count(),
ss_noconstr_time.count(),
boost::is_same<SprintfT, structure_fake>::value ? fake_test_value : printf_time.count()
std::is_same<SprintfT, structure_fake>::value ? fake_test_value : printf_time.count()
);
}
@@ -312,6 +329,12 @@ struct to_array_50 {
}
};
struct to_string_view {
std::string_view operator()(const char* const c) const {
return std::string_view{c};
}
};
int main(int argc, char** argv) {
BOOST_ASSERT(argc >= 2);
std::string output_path(argv[1]);
@@ -354,6 +377,7 @@ int main(int argc, char** argv) {
string_like_test_set<to_uchar_conv>("unsigned char*");
string_like_test_set<to_schar_conv>("signed char*");
string_like_test_set<to_iterator_range>("iterator_range<char*>");
string_like_test_set<to_string_view>("std::string_view");
string_like_test_set<to_array_50>("array<char, 50>");
perf_test<int, structure_fake>("int->int", 100, "");
-308
View File
@@ -1,308 +0,0 @@
// what: simple unit test framework
// who: developed by Kevlin Henney
// when: November 2000
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91
//
// ChangeLog:
// 20 Jan 2001 - Fixed a warning for MSVC (Dave Abrahams)
#ifndef TEST_INCLUDED
#define TEST_INCLUDED
#include <exception>
#include <iostream>
#include <strstream> // for out-of-the-box g++
#include <string>
namespace test // test tuple comprises name and nullary function (object)
{
template<typename string_type, typename function_type>
struct test
{
string_type name;
function_type action;
static test make(string_type name, function_type action)
{
test result; // MSVC aggreggate initializer bugs
result.name = name;
result.action = action;
return result;
}
};
}
namespace test // failure exception used to indicate checked test failures
{
class failure : public std::exception
{
public: // struction (default cases are OK)
failure(const std::string & why)
: reason(why)
{
}
// std::~string has no exception-specification (could throw anything),
// but we need to be compatible with std::~exception's empty one
// see std::15.4p13 and std::15.4p3
~failure() throw()
{
}
public: // usage
virtual const char * what() const throw()
{
return reason.c_str();
}
private: // representation
std::string reason;
};
}
namespace test // not_implemented exception used to mark unimplemented tests
{
class not_implemented : public std::exception
{
public: // usage (default ctor and dtor are OK)
virtual const char * what() const throw()
{
return "not implemented";
}
};
}
namespace test // test utilities
{
inline void check(bool condition, const std::string & description)
{
if(!condition)
{
throw failure(description);
}
}
inline void check_true(bool value, const std::string & description)
{
check(value, "expected true: " + description);
}
inline void check_false(bool value, const std::string & description)
{
check(!value, "expected false: " + description);
}
template<typename lhs_type, typename rhs_type>
void check_equal(
const lhs_type & lhs, const rhs_type & rhs,
const std::string & description)
{
check(lhs == rhs, "expected equal values: " + description);
}
template<typename lhs_type, typename rhs_type>
void check_unequal(
const lhs_type & lhs, const rhs_type & rhs,
const std::string & description)
{
check(lhs != rhs, "expected unequal values: " + description);
}
inline void check_null(const void* ptr, const std::string & description)
{
check(!ptr, "expected null pointer: " + description);
}
inline void check_non_null(const void* ptr, const std::string & description)
{
check(ptr != 0, "expected non-null pointer: " + description);
}
}
#define TEST_CHECK_THROW(expression, exception, description) \
try \
{ \
expression; \
throw ::test::failure(description); \
} \
catch(exception &) \
{ \
}
namespace test // memory tracking (enabled if test new and delete linked in)
{
class allocations
{
public: // singleton access
static allocations & instance()
{
static allocations singleton;
return singleton;
}
public: // logging
void clear()
{
alloc_count = dealloc_count = 0;
}
void allocation()
{
++alloc_count;
}
void deallocation()
{
++dealloc_count;
}
public: // reporting
unsigned long allocated() const
{
return alloc_count;
}
unsigned long deallocated() const
{
return dealloc_count;
}
bool balanced() const
{
return alloc_count == dealloc_count;
}
private: // structors (default dtor is fine)
allocations()
: alloc_count(0), dealloc_count(0)
{
}
private: // prevention
allocations(const allocations &);
allocations & operator=(const allocations &);
private: // state
unsigned long alloc_count, dealloc_count;
};
}
namespace test // tester is the driver class for a sequence of tests
{
template<typename test_iterator>
class tester
{
public: // structors (default destructor is OK)
tester(test_iterator first_test, test_iterator after_last_test)
: begin(first_test), end(after_last_test)
{
}
public: // usage
bool operator()(); // returns true if all tests passed
private: // representation
test_iterator begin, end;
private: // prevention
tester(const tester &);
tester &operator=(const tester &);
};
template<typename test_iterator>
bool tester<test_iterator>::operator()()
{
using namespace std;
unsigned long passed = 0, failed = 0, unimplemented = 0;
for(test_iterator current = begin; current != end; ++current)
{
cerr << "[" << current->name << "] " << flush;
string result = "passed"; // optimistic
try
{
allocations::instance().clear();
current->action();
if(!allocations::instance().balanced())
{
unsigned long allocated = allocations::instance().allocated();
unsigned long deallocated = allocations::instance().deallocated();
ostrstream report;
report << "new/delete ("
<< allocated << " allocated, "
<< deallocated << " deallocated)"
<< ends;
const char * text = report.str();
report.freeze(false);
throw failure(text);
}
++passed;
}
catch(const failure & caught)
{
(result = "failed: ") += caught.what();
++failed;
}
catch(const not_implemented &)
{
result = "not implemented";
++unimplemented;
}
catch(const exception & caught)
{
(result = "exception: ") += caught.what();
++failed;
}
catch(...)
{
result = "failed with unknown exception";
++failed;
}
cerr << result << endl;
}
cerr << passed + failed << " tests: "
<< passed << " passed, "
<< failed << " failed";
if(unimplemented)
{
cerr << " (" << unimplemented << " not implemented)";
}
cerr << endl;
return failed == 0;
}
}
#endif
// Copyright Kevlin Henney, 2000. All rights reserved.
//
// 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)
+84
View File
@@ -0,0 +1,84 @@
# Copyright Antony Polukhin, 2021-2026.
#
# 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
if(NOT TARGET tests)
add_custom_target(tests)
endif()
function(boost_lexical_cast_add_test_impl test_name test_file libs)
add_executable(${test_name} ${test_file})
target_link_libraries(${test_name} PRIVATE ${libs})
add_test(NAME ${test_name} COMMAND ${test_name})
add_dependencies(tests ${test_name})
endfunction()
function(boost_lexical_cast_add_test name libs)
set(test_name lexical_cast_${name})
set(test_file ${name}.cpp)
boost_lexical_cast_add_test_impl(${test_name} ${test_file} "Boost::lexical_cast;${libs}")
endfunction()
boost_lexical_cast_add_test(lexical_cast_test Boost::type_traits)
boost_lexical_cast_add_test(loopback_test "")
boost_lexical_cast_add_test(abstract_test "")
boost_lexical_cast_add_test(noncopyable_test "")
boost_lexical_cast_add_test(vc8_bug_test "")
boost_lexical_cast_add_test(implicit_convert "")
boost_lexical_cast_add_test(wchars_test "")
boost_lexical_cast_add_test(float_types_test "")
if(NOT MSVC)
# Make sure that LexicalCast works the same way as some of the C++ Standard Libraries
boost_lexical_cast_add_test_impl(lexical_cast_float_types_non_opt float_types_test.cpp Boost::lexical_cast)
target_compile_definitions(lexical_cast_float_types_non_opt PRIVATE BOOST_LEXICAL_CAST_DETAIL_TEST_ON_OLD)
endif()
boost_lexical_cast_add_test(inf_nan_test "")
boost_lexical_cast_add_test(containers_test "")
boost_lexical_cast_add_test(empty_input_test Boost::range)
boost_lexical_cast_add_test(pointers_test "")
if(MSVC)
add_executable(lexical_cast_typedefed_wchar_test_compile typedefed_wchar_test.cpp)
target_compile_options(lexical_cast_typedefed_wchar_test_compile PRIVATE "/Zc:wchar_t-")
boost_lexical_cast_add_test(typedefed_wchar_test_runtime "")
target_compile_options(lexical_cast_typedefed_wchar_test_runtime PRIVATE "/Zc:wchar_t-")
endif()
boost_lexical_cast_add_test(no_locale_test Boost::range)
target_compile_definitions(lexical_cast_no_locale_test
PRIVATE
BOOST_NO_STD_LOCALE
BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
)
boost_lexical_cast_add_test_impl(lexical_cast_no_exceptions_test no_exceptions_test.cpp "Boost::container;Boost::range")
target_include_directories(lexical_cast_no_exceptions_test PRIVATE ../include)
target_compile_definitions(lexical_cast_no_exceptions_test
PRIVATE
_HAS_EXCEPTIONS=0 # MSVC stdlib
_STLP_NO_EXCEPTIONS # STLPort
)
if(MSVC)
target_compile_definitions(lexical_cast_no_exceptions_test PRIVATE BOOST_NO_EXCEPTIONS)
endif()
target_compile_options(lexical_cast_no_exceptions_test PRIVATE "-fno-exceptions")
boost_lexical_cast_add_test(iterator_range_test Boost::range)
boost_lexical_cast_add_test(string_view_test Boost::utility)
boost_lexical_cast_add_test(arrays_test Boost::array)
boost_lexical_cast_add_test(integral_types_test Boost::type_traits)
boost_lexical_cast_add_test(stream_detection_test "")
boost_lexical_cast_add_test(stream_traits_test "Boost::array;Boost::range;Boost::utility")
boost_lexical_cast_add_test(filesystem_test Boost::filesystem)
boost_lexical_cast_add_test(try_lexical_convert "")
file(GLOB EXAMPLE_FILES "../example/*.cpp")
foreach (testsourcefile ${EXAMPLE_FILES})
get_filename_component(testname ${testsourcefile} NAME_WE)
boost_lexical_cast_add_test_impl(lexical_cast_example_${testname} ${testsourcefile} "Boost::variant;Boost::date_time")
endforeach()
+59 -39
View File
@@ -1,16 +1,20 @@
# Copyright (C) 2001-2003 Douglas Gregor
# Copyright (C) 2011-2013 Antony Polukhin
# Copyright Antony Polukhin, 2011-2026.
#
# 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)
#
require-b2 5.0.1 ;
import-search /boost/config/checks ;
import config : requires ;
import testing ;
import feature ;
project
: requirements
<library>/boost/test//boost_unit_test_framework
<library>/boost/lexical_cast//boost_lexical_cast
[ requires cxx11_rvalue_references cxx11_static_assert cxx11_template_aliases ]
<link>static
<toolset>gcc-4.7:<cxxflags>-ftrapv
<toolset>gcc-4.6:<cxxflags>-ftrapv
@@ -19,55 +23,71 @@ project
<warnings>all
# set warnings as errors for those compilers we know we get warning free:
<toolset>gcc:<cxxflags>-Wextra
<toolset>gcc:<cxxflags>-Wno-uninitialized
# Not a lexical_cast related warning: boost/preprocessor/variadic/elem.hpp:29:46: warning: variadic macros are a C99 feature
<toolset>clang:<cxxflags>-Wno-variadic-macros
<toolset>gcc:<cxxflags>-Wno-variadic-macros
# Not a lexical_cast related warning: boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp:78:1: warning: empty macro arguments are a C99 feature [-Wc99-extensions]
# boost/mpl/iter_fold.hpp:45:1: warning: empty macro arguments are a C99 feature [-Wc99-extensions]
<toolset>clang:<cxxflags>-Wno-c99-extensions
<library>/boost/array//boost_array
<library>/boost/range//boost_range
<library>/boost/utility//boost_utility
;
# Thanks to Steven Watanabe for helping with <nowchar> feature
feature.feature nowchar : on :
composite optional propagated link-incompatible ;
feature.compose <nowchar>on : <cxxflags>/Zc:wchar_t- ;
feature.compose <nowchar>on : <cxxflags>"/Zc:wchar_t-" ;
test-suite conversion
: [ run implicit_cast.cpp ]
[ compile-fail implicit_cast_fail.cpp ]
[ run ../cast_test.cpp ]
[ run ../numeric_cast_test.cpp ]
[ run ../lexical_cast_test.cpp ]
[ run lexical_cast_loopback_test.cpp ]
[ run lexical_cast_abstract_test.cpp ]
[ run lexical_cast_noncopyable_test.cpp ]
[ run lexical_cast_vc8_bug_test.cpp ]
[ 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_empty_input_test.cpp ]
[ run lexical_cast_pointers_test.cpp ]
[ compile lexical_cast_typedefed_wchar_test.cpp : <toolset>msvc:<nowchar>on ]
[ run lexical_cast_typedefed_wchar_test_runtime.cpp : : : <toolset>msvc:<nowchar>on <toolset>msvc,<stdlib>stlport:<build>no ]
[ run lexical_cast_no_locale_test.cpp : : : <define>BOOST_NO_STD_LOCALE <define>BOOST_LEXICAL_CAST_ASSUME_C_LOCALE ]
[ run lexical_cast_no_exceptions_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
<toolset>gcc-4.3:<cxxflags>-fno-exceptions
<toolset>gcc-4.4:<cxxflags>-fno-exceptions
<toolset>gcc-4.5:<cxxflags>-fno-exceptions
<toolset>gcc-4.6:<cxxflags>-fno-exceptions
<toolset>gcc-4.7:<cxxflags>-fno-exceptions
<toolset>gcc-4.8:<cxxflags>-fno-exceptions
<toolset>clang:<cxxflags>-fno-exceptions
: [ run lexical_cast_test.cpp ]
[ run loopback_test.cpp ]
[ run abstract_test.cpp ]
[ run noncopyable_test.cpp ]
[ run vc8_bug_test.cpp ]
[ run implicit_convert.cpp ]
[ run wchars_test.cpp ]
[ run float_types_test.cpp ]
# Make sure that LexicalCast works the same way as some of the C++ Standard Libraries
[ run float_types_test.cpp : : : <define>BOOST_LEXICAL_CAST_DETAIL_TEST_ON_OLD
<toolset>msvc:<build>no # could have outdated behavior in some border cases
<target-os>darwin:<build>no # may have outdated behavior in some border cases
: float_types_non_opt
]
[ run lexical_cast_iterator_range_test.cpp ]
[ run lexical_cast_arrays_test.cpp ]
[ 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 ]
[ run inf_nan_test.cpp ]
[ run containers_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-long-long <toolset>clang:<cxxflags>-Wno-long-long ]
[ run empty_input_test.cpp ]
[ run pointers_test.cpp ]
[ compile typedefed_wchar_test.cpp : <toolset>msvc:<nowchar>on <library>/boost/date_time//boost_date_time ]
[ run typedefed_wchar_test_runtime.cpp : : : <toolset>msvc:<nowchar>on <toolset>msvc,<stdlib>stlport:<build>no ]
[ run no_locale_test.cpp : : : <define>BOOST_NO_STD_LOCALE <define>BOOST_LEXICAL_CAST_ASSUME_C_LOCALE ]
[ run no_exceptions_test.cpp : : : <exception-handling>off
<define>_HAS_EXCEPTIONS=0 # MSVC stdlib
<define>_STLP_NO_EXCEPTIONS # STLPort
]
[ run iterator_range_test.cpp ]
[ run string_view_test.cpp ]
[ run arrays_test.cpp : : :
<toolset>msvc:<cxxflags>/wd4512 # assignment operator could not be generated
]
[ run integral_types_test.cpp ]
[ run stream_detection_test.cpp ]
[ run stream_traits_test.cpp ]
[ compile-fail to_pointer_test.cpp ]
[ compile-fail from_volatile.cpp ]
[ run filesystem_test.cpp /boost/filesystem//boost_filesystem : : : <toolset>gcc,<target-os>windows:<build>no ] # Boost.Atomic no longer supports MinGW
[ run try_lexical_convert.cpp ]
;
# Assuring that examples compile and run. Adding sources from `example` directory to the `conversion` test suite.
# 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) ] ;
conversion += [ run $(p) : : : <library>/boost/variant//boost_variant <library>/boost/date_time//boost_date_time ] ;
}
@@ -3,6 +3,7 @@
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Sergey Shandar 2005, Alexander Nasonov, 2007.
// Copyright Antony Polukhin, 2023-2026.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -11,34 +12,15 @@
// Test abstract class. Bug 1358600:
// http://sf.net/tracker/?func=detail&aid=1358600&group_id=7586&atid=107586
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_abstract();
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_abstract));
return suite;
}
class A
{
public:
virtual void out(std::ostream &) const = 0;
virtual ~A() {}
};
class B: public A
@@ -56,6 +38,12 @@ std::ostream &operator<<(std::ostream &O, const A &a)
void test_abstract()
{
const A &a = B();
BOOST_CHECK(boost::lexical_cast<std::string>(a) == "B");
BOOST_TEST(boost::lexical_cast<std::string>(a) == "B");
}
int main()
{
test_abstract();
return boost::report_errors();
}
+100
View File
@@ -0,0 +1,100 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Copyright Antony Polukhin, 2016-2026.
#
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
# and how it can be used with Boost libraries.
#
# File revision #6
init:
# boost-local/libs/ folder to put this library into. This may be useful, if you're for example running Travis
# from `Boost.DLL` repo while Boost already has `dll` and with to replace `dll` with content of`Boost.DLL`.
#
# Otherwise just leave the default value - set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
- set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
###############################################################################################################
# From this point and below code is same for all the Boost libs
###############################################################################################################
version: 1.74.{build}-{branch}
# branches to build
branches:
except:
- gh-pages
skip_tags: true
environment:
matrix:
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
# TOOLSET: msvc # TODO: clang-win ???
# ADDRMD: 32,64
# CXXSTD: 17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correclty use std::tuple_size
ADDRMD: 32,64
CXXSTD: 17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correclty use std::tuple_size
ADDRMD: 32,64
CXXSTD: 17,latest
CXXFLAGS: /permissive-
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc # clang-win has problems with structured bindings - it can not correclty use std::tuple_size
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 14,1z
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ADDPATH: C:\mingw\bin;
# TOOLSET: gcc
# CXXSTD: 14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 14,1z
before_build:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- echo "Testing %BOOST_LIBS_FOLDER%"
# Cloning Boost libraries (fast nondeep cloning)
- set BOOST=C:/boost-local
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %BOOST%
- cd %BOOST%
- git submodule update --init --depth 10 tools/build tools/boostdep
- echo "rm -rf %BOOST%/libs/%BOOST_LIBS_FOLDER%"
- rm -rf %BOOST%/libs/%BOOST_LIBS_FOLDER%
- mv %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%BOOST_LIBS_FOLDER%
- python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 2" -I example -I examples %BOOST_LIBS_FOLDER%
build_script:
- cmd /c bootstrap
- b2.exe headers
- cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test
after_build:
before_test:
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- echo "Running command ..\..\..\b2 -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release"
- ..\..\..\b2.exe -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release cxxflags="-DBOOST_TRAVISCI_BUILD %CXXFLAGS%"
after_test:
on_success:
on_failure:
on_finish:
@@ -2,49 +2,30 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012.
// Copyright Antony Polukhin, 2012-2026.
//
// 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/core/lightweight_test.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/array.hpp>
void testing_boost_array_output_conversion();
void testing_std_array_output_conversion();
void testing_boost_array_input_conversion();
void testing_std_array_input_conversion();
#include <boost/lexical_cast.hpp>
using namespace boost;
#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) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
#define BOOST_LC_RUNU16
#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) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
#define BOOST_LC_RUNU32
#endif
boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("Testing boost::lexical_cast with boost::array and std::array");
suite->add(BOOST_TEST_CASE(testing_boost_array_output_conversion));
suite->add(BOOST_TEST_CASE(testing_std_array_output_conversion));
suite->add(BOOST_TEST_CASE(testing_boost_array_input_conversion));
suite->add(BOOST_TEST_CASE(testing_std_array_input_conversion));
return suite;
}
template <template <class, std::size_t> class ArrayT, class T>
static void testing_template_array_output_on_spec_value(T val)
static void testing_template_array_output_on_spec_value(T val)
{
typedef ArrayT<char, 300> arr_type;
typedef ArrayT<char, 1> short_arr_type;
@@ -58,44 +39,44 @@ static void testing_template_array_output_on_spec_value(T val)
{
arr_type res1 = lexical_cast<arr_type>(val);
BOOST_CHECK_EQUAL(&res1[0], ethalon);
BOOST_TEST_EQ(&res1[0], ethalon);
const arr_type res2 = lexical_cast<arr_type>(val);
BOOST_CHECK_EQUAL(&res2[0], ethalon);
BOOST_CHECK_THROW(lexical_cast<short_arr_type>(val), boost::bad_lexical_cast);
}
{
uarr_type res1 = lexical_cast<uarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
const uarr_type res2 = lexical_cast<uarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_CHECK_THROW(lexical_cast<ushort_arr_type>(val), boost::bad_lexical_cast);
}
{
sarr_type res1 = lexical_cast<sarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
const sarr_type res2 = lexical_cast<sarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_CHECK_THROW(lexical_cast<sshort_arr_type>(val), boost::bad_lexical_cast);
BOOST_TEST_EQ(&res2[0], ethalon);
BOOST_TEST_THROWS(lexical_cast<short_arr_type>(val), boost::bad_lexical_cast);
}
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
{
uarr_type res1 = lexical_cast<uarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<char*>(&res1[0]), ethalon);
const uarr_type res2 = lexical_cast<uarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_TEST_THROWS(lexical_cast<ushort_arr_type>(val), boost::bad_lexical_cast);
}
{
sarr_type res1 = lexical_cast<sarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<char*>(&res1[0]), ethalon);
const sarr_type res2 = lexical_cast<sarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_TEST_THROWS(lexical_cast<sshort_arr_type>(val), boost::bad_lexical_cast);
}
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING) && !defined(_LIBCPP_VERSION)
typedef ArrayT<wchar_t, 300> warr_type;
typedef ArrayT<wchar_t, 3> wshort_arr_type;
std::wstring wethalon(L"100");
{
warr_type res = lexical_cast<warr_type>(val);
BOOST_CHECK(&res[0] == wethalon);
BOOST_TEST(&res[0] == wethalon);
}
{
const warr_type res = lexical_cast<warr_type>(val);
BOOST_CHECK(&res[0] == wethalon);
BOOST_TEST(&res[0] == wethalon);
}
BOOST_CHECK_THROW(lexical_cast<wshort_arr_type>(val), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<wshort_arr_type>(val), boost::bad_lexical_cast);
#endif
@@ -106,15 +87,15 @@ static void testing_template_array_output_on_spec_value(T val)
{
u16arr_type res = lexical_cast<u16arr_type>(val);
BOOST_CHECK(&res[0] == u16ethalon);
BOOST_TEST(&res[0] == u16ethalon);
}
{
const u16arr_type res = lexical_cast<u16arr_type>(val);
BOOST_CHECK(&res[0] == u16ethalon);
BOOST_TEST(&res[0] == u16ethalon);
}
BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<u16short_arr_type>(val), boost::bad_lexical_cast);
#endif
#ifdef BOOST_LC_RUNU32
@@ -124,21 +105,21 @@ static void testing_template_array_output_on_spec_value(T val)
{
u32arr_type res = lexical_cast<u32arr_type>(val);
BOOST_CHECK(&res[0] == u32ethalon);
BOOST_TEST(&res[0] == u32ethalon);
}
{
const u32arr_type res = lexical_cast<u32arr_type>(val);
BOOST_CHECK(&res[0] == u32ethalon);
BOOST_TEST(&res[0] == u32ethalon);
}
BOOST_CHECK_THROW(lexical_cast<u32short_arr_type>(val), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<u32short_arr_type>(val), boost::bad_lexical_cast);
#endif
}
template <template <class, std::size_t> class ArrayT>
static void testing_template_array_output_on_char_value()
static void testing_template_array_output_on_char_value()
{
typedef ArrayT<char, 300> arr_type;
typedef ArrayT<char, 1> short_arr_type;
@@ -153,48 +134,48 @@ static void testing_template_array_output_on_char_value()
{
arr_type res1 = lexical_cast<arr_type>(val);
BOOST_CHECK_EQUAL(&res1[0], ethalon);
BOOST_TEST_EQ(&res1[0], ethalon);
const arr_type res2 = lexical_cast<arr_type>(val);
BOOST_CHECK_EQUAL(&res2[0], ethalon);
BOOST_CHECK_THROW(lexical_cast<short_arr_type>(val), boost::bad_lexical_cast);
}
{
uarr_type res1 = lexical_cast<uarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
const uarr_type res2 = lexical_cast<uarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_CHECK_THROW(lexical_cast<ushort_arr_type>(val), boost::bad_lexical_cast);
}
{
sarr_type res1 = lexical_cast<sarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<char*>(&res1[0]), ethalon);
const sarr_type res2 = lexical_cast<sarr_type>(val);
BOOST_CHECK_EQUAL(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_CHECK_THROW(lexical_cast<sshort_arr_type>(val), boost::bad_lexical_cast);
BOOST_TEST_EQ(&res2[0], ethalon);
BOOST_TEST_THROWS(lexical_cast<short_arr_type>(val), boost::bad_lexical_cast);
}
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
{
uarr_type res1 = lexical_cast<uarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<char*>(&res1[0]), ethalon);
const uarr_type res2 = lexical_cast<uarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_TEST_THROWS(lexical_cast<ushort_arr_type>(val), boost::bad_lexical_cast);
}
{
sarr_type res1 = lexical_cast<sarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<char*>(&res1[0]), ethalon);
const sarr_type res2 = lexical_cast<sarr_type>(val);
BOOST_TEST_EQ(reinterpret_cast<const char*>(&res2[0]), ethalon);
BOOST_TEST_THROWS(lexical_cast<sshort_arr_type>(val), boost::bad_lexical_cast);
}
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING) && !defined(_LIBCPP_VERSION)
typedef ArrayT<wchar_t, 4> warr_type;
typedef ArrayT<wchar_t, 3> wshort_arr_type;
std::wstring wethalon(L"100");
{
warr_type res = lexical_cast<warr_type>(val);
BOOST_CHECK(&res[0] == wethalon);
BOOST_TEST(&res[0] == wethalon);
warr_type res3 = lexical_cast<warr_type>(wethalon);
BOOST_CHECK(&res3[0] == wethalon);
BOOST_TEST(&res3[0] == wethalon);
}
{
const warr_type res = lexical_cast<warr_type>(val);
BOOST_CHECK(&res[0] == wethalon);
BOOST_TEST(&res[0] == wethalon);
const warr_type res3 = lexical_cast<warr_type>(wethalon);
BOOST_CHECK(&res3[0] == wethalon);
BOOST_TEST(&res3[0] == wethalon);
}
BOOST_CHECK_THROW(lexical_cast<wshort_arr_type>(val), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<wshort_arr_type>(val), boost::bad_lexical_cast);
#endif
@@ -206,24 +187,24 @@ static void testing_template_array_output_on_char_value()
{
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
u16arr_type res = lexical_cast<u16arr_type>(val);
BOOST_CHECK(&res[0] == u16ethalon);
BOOST_TEST(&res[0] == u16ethalon);
#endif
u16arr_type res3 = lexical_cast<u16arr_type>(u16ethalon);
BOOST_CHECK(&res3[0] == u16ethalon);
BOOST_TEST(&res3[0] == u16ethalon);
}
{
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
const u16arr_type res = lexical_cast<u16arr_type>(val);
BOOST_CHECK(&res[0] == u16ethalon);
BOOST_TEST(&res[0] == u16ethalon);
#endif
const u16arr_type res3 = lexical_cast<u16arr_type>(u16ethalon);
BOOST_CHECK(&res3[0] == u16ethalon);
BOOST_TEST(&res3[0] == u16ethalon);
}
// Some compillers may throw std::bad_alloc here
BOOST_CHECK_THROW(lexical_cast<u16short_arr_type>(val), std::exception);
BOOST_TEST_THROWS(lexical_cast<u16short_arr_type>(val), std::exception);
#endif
#ifdef BOOST_LC_RUNU32
@@ -234,34 +215,36 @@ static void testing_template_array_output_on_char_value()
{
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
u32arr_type res = lexical_cast<u32arr_type>(val);
BOOST_CHECK(&res[0] == u32ethalon);
BOOST_TEST(&res[0] == u32ethalon);
#endif
u32arr_type res3 = lexical_cast<u32arr_type>(u32ethalon);
BOOST_CHECK(&res3[0] == u32ethalon);
BOOST_TEST(&res3[0] == u32ethalon);
}
{
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
const u32arr_type res = lexical_cast<u32arr_type>(val);
BOOST_CHECK(&res[0] == u32ethalon);
BOOST_TEST(&res[0] == u32ethalon);
#endif
const u32arr_type res3 = lexical_cast<u32arr_type>(u32ethalon);
BOOST_CHECK(&res3[0] == u32ethalon);
BOOST_TEST(&res3[0] == u32ethalon);
}
// Some compillers may throw std::bad_alloc here
BOOST_CHECK_THROW(lexical_cast<u32short_arr_type>(val), std::exception);
BOOST_TEST_THROWS(lexical_cast<u32short_arr_type>(val), std::exception);
#endif
}
void testing_boost_array_output_conversion()
{
{
#ifndef _LIBCPP_VERSION
testing_template_array_output_on_char_value<boost::array>();
testing_template_array_output_on_spec_value<boost::array>(100);
testing_template_array_output_on_spec_value<boost::array>(static_cast<short>(100));
testing_template_array_output_on_spec_value<boost::array>(static_cast<unsigned short>(100));
testing_template_array_output_on_spec_value<boost::array>(static_cast<unsigned int>(100));
#endif
}
void testing_std_array_output_conversion()
@@ -274,96 +257,99 @@ void testing_std_array_output_conversion()
testing_template_array_output_on_spec_value<std::array>(static_cast<unsigned int>(100));
#endif
BOOST_CHECK(true);
BOOST_TEST(true);
}
template <template <class, std::size_t> class ArrayT>
static void testing_generic_array_input_conversion()
{
{
ArrayT<char, 4> var_zero_terminated = {{ '1', '0', '0', '\0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated), "100");
BOOST_CHECK_EQUAL(lexical_cast<int>(var_zero_terminated), 100);
ArrayT<char, 4> var_zero_terminated = {{ '1', '0', '0', '\0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_zero_terminated), "100");
BOOST_TEST_EQ(lexical_cast<int>(var_zero_terminated), 100);
ArrayT<char, 3> var_none_terminated = {{ '1', '0', '0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated), "100");
BOOST_CHECK_EQUAL(lexical_cast<short>(var_none_terminated), static_cast<short>(100));
ArrayT<char, 3> var_none_terminated = {{ '1', '0', '0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_none_terminated), "100");
BOOST_TEST_EQ(lexical_cast<short>(var_none_terminated), static_cast<short>(100));
ArrayT<const char, 4> var_zero_terminated_const_char = {{ '1', '0', '0', '\0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_char), "100");
ArrayT<const char, 4> var_zero_terminated_const_char = {{ '1', '0', '0', '\0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_zero_terminated_const_char), "100");
ArrayT<const char, 3> var_none_terminated_const_char = {{ '1', '0', '0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_char), "100");
ArrayT<const char, 3> var_none_terminated_const_char = {{ '1', '0', '0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_none_terminated_const_char), "100");
const ArrayT<char, 4> var_zero_terminated_const_var = {{ '1', '0', '0', '\0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var), "100");
const ArrayT<char, 4> var_zero_terminated_const_var = {{ '1', '0', '0', '\0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_zero_terminated_const_var), "100");
const ArrayT<char, 3> var_none_terminated_const_var = {{ '1', '0', '0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var), "100");
const ArrayT<char, 3> var_none_terminated_const_var = {{ '1', '0', '0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_none_terminated_const_var), "100");
const ArrayT<const char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
const ArrayT<const char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
const ArrayT<const char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
BOOST_CHECK_EQUAL(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
const ArrayT<const char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
BOOST_TEST_EQ(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
}
{
const ArrayT<const unsigned char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
const ArrayT<const unsigned char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
const ArrayT<const unsigned char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
const ArrayT<const unsigned char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
}
{
const ArrayT<const signed char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
const ArrayT<const signed char, 4> var_zero_terminated_const_var_const_char = {{ '1', '0', '0', '\0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_zero_terminated_const_var_const_char), "100");
const ArrayT<const signed char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
BOOST_CHECK_EQUAL(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(var_none_terminated_const_var_const_char), 100u);
const ArrayT<const signed char, 3> var_none_terminated_const_var_const_char = {{ '1', '0', '0'}};
BOOST_TEST_EQ(lexical_cast<std::string>(var_none_terminated_const_var_const_char), "100");
BOOST_TEST_EQ(lexical_cast<unsigned int>(var_none_terminated_const_var_const_char), 100u);
}
#if !defined(BOOST_NO_STRINGSTREAM) && !defined(BOOST_NO_STD_WSTRING)
{
const ArrayT<const wchar_t, 4> var_zero_terminated_const_var_const_char = {{ L'1', L'0', L'0', L'\0'}};
BOOST_CHECK(lexical_cast<std::wstring>(var_zero_terminated_const_var_const_char) == L"100");
const ArrayT<const wchar_t, 4> var_zero_terminated_const_var_const_char = {{ L'1', L'0', L'0', L'\0'}};
BOOST_TEST(lexical_cast<std::wstring>(var_zero_terminated_const_var_const_char) == L"100");
const ArrayT<const wchar_t, 3> var_none_terminated_const_var_const_char = {{ L'1', L'0', L'0'}};
BOOST_CHECK(lexical_cast<std::wstring>(var_none_terminated_const_var_const_char) == L"100");
BOOST_CHECK_EQUAL(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
const ArrayT<const wchar_t, 3> var_none_terminated_const_var_const_char = {{ L'1', L'0', L'0'}};
BOOST_TEST(lexical_cast<std::wstring>(var_none_terminated_const_var_const_char) == L"100");
BOOST_TEST_EQ(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
}
#endif
#ifdef BOOST_LC_RUNU16
{
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");
BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(var_zero_terminated_const_var_const_char), static_cast<unsigned short>(100));
const ArrayT<const char16_t, 4> var_zero_terminated_const_var_const_char = {{ u'1', u'0', u'0', u'\0'}};
BOOST_TEST(lexical_cast<std::u16string>(var_zero_terminated_const_var_const_char) == u"100");
BOOST_TEST_EQ(lexical_cast<unsigned short>(var_zero_terminated_const_var_const_char), static_cast<unsigned short>(100));
const ArrayT<const char16_t, 3> var_none_terminated_const_var_const_char = {{ u'1', u'0', u'0'}};
BOOST_CHECK(lexical_cast<std::u16string>(var_none_terminated_const_var_const_char) == u"100");
const ArrayT<const char16_t, 3> var_none_terminated_const_var_const_char = {{ u'1', u'0', u'0'}};
BOOST_TEST(lexical_cast<std::u16string>(var_none_terminated_const_var_const_char) == u"100");
}
#endif
#ifdef BOOST_LC_RUNU32
{
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");
const ArrayT<const char32_t, 4> var_zero_terminated_const_var_const_char = {{ U'1', U'0', U'0', U'\0'}};
BOOST_TEST(lexical_cast<std::u32string>(var_zero_terminated_const_var_const_char) == U"100");
const ArrayT<const char32_t, 3> var_none_terminated_const_var_const_char = {{ U'1', U'0', U'0'}};
BOOST_CHECK(lexical_cast<std::u32string>(var_none_terminated_const_var_const_char) == U"100");
BOOST_CHECK_EQUAL(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
const ArrayT<const char32_t, 3> var_none_terminated_const_var_const_char = {{ U'1', U'0', U'0'}};
BOOST_TEST(lexical_cast<std::u32string>(var_none_terminated_const_var_const_char) == U"100");
BOOST_TEST_EQ(lexical_cast<int>(var_none_terminated_const_var_const_char), 100);
}
#endif
}
void testing_boost_array_input_conversion()
{
#ifndef _LIBCPP_VERSION
testing_generic_array_input_conversion<boost::array>();
#endif
BOOST_TEST(true);
}
void testing_std_array_input_conversion()
@@ -372,6 +358,16 @@ void testing_std_array_input_conversion()
testing_generic_array_input_conversion<std::array>();
#endif
BOOST_CHECK(true);
BOOST_TEST(true);
}
int main()
{
testing_boost_array_output_conversion();
testing_std_array_output_conversion();
testing_boost_array_input_conversion();
testing_std_array_input_conversion();
return boost::report_errors();
}
+80
View File
@@ -0,0 +1,80 @@
# Copyright (c) 2016-2025 Antony Polukhin
# Copyright (c) 2025-2026 Fedor Osetrov
# 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
cmake_minimum_required(VERSION 3.5...4.0)
project(lexical_cast_subdir_test LANGUAGES CXX)
set(deps
# Library dependencies
config
container
core
throw_exception
# Test dependencies
algorithm
array
align
assert
atomic
bind
compat
concept_check
container_hash
conversion
date_time
describe
detail
exception
filesystem
function
function_types
functional
fusion
integer
intrusive
io
iterator
move
mp11
mpl
numeric/conversion
optional
predef
preprocessor
range
regex
scope
smart_ptr
static_assert
system
test
tokenizer
tuple
type_index
type_traits
typeof
unordered
utility
variant
variant2
winapi
)
foreach(dep IN LISTS deps)
add_subdirectory(../../../${dep} boostorg/${dep})
endforeach()
enable_testing()
add_subdirectory(../../ boostorg/lexical_cast)
if (BOOST_USE_MODULES)
add_executable(boost_lexical_cast_module_usage ../modules/usage_sample.cpp)
target_link_libraries(boost_lexical_cast_module_usage PRIVATE Boost::lexical_cast)
add_test(NAME boost_lexical_cast_module_usage COMMAND boost_lexical_cast_module_usage)
endif()
+77
View File
@@ -0,0 +1,77 @@
// Testing boost::lexical_cast with boost::container::string.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2026.
//
// 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/core/lightweight_test.hpp>
#include <boost/container/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace boost;
void testing_boost_containers_basic_string()
{
BOOST_TEST("100" == lexical_cast<boost::container::string>("100"));
BOOST_TEST(L"100" == lexical_cast<boost::container::wstring>(L"100"));
BOOST_TEST("100" == lexical_cast<boost::container::string>(100));
boost::container::string str("1000");
BOOST_TEST(1000 == lexical_cast<int>(str));
}
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
void testing_boost_containers_string_std_string()
{
std::string std_str("std_str");
boost::container::string boost_str("boost_str");
BOOST_TEST(boost::lexical_cast<std::string>(boost_str) == "boost_str");
BOOST_TEST(boost::lexical_cast<boost::container::string>(std_str) == "std_str");
#ifndef BOOST_LCAST_NO_WCHAR_T
std::wstring std_wstr(L"std_wstr");
boost::container::wstring boost_wstr(L"boost_wstr");
BOOST_TEST(boost::lexical_cast<std::wstring>(boost_wstr) == L"boost_wstr");
BOOST_TEST(boost::lexical_cast<boost::container::wstring>(std_wstr) == L"std_wstr");
#endif
}
void testing_boost_containers_string_widening()
{
const char char_array[] = "Test string";
#ifndef BOOST_LCAST_NO_WCHAR_T
const wchar_t wchar_array[] = L"Test string";
BOOST_TEST(boost::lexical_cast<boost::container::wstring>(char_array) == wchar_array);
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
const char16_t char16_array[] = u"Test string";
BOOST_TEST(boost::lexical_cast<boost::container::basic_string<char16_t> >(char_array) == char16_array);
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
const char32_t char32_array[] = U"Test string";
BOOST_TEST(boost::lexical_cast<boost::container::basic_string<char32_t> >(char_array) == char32_array);
#endif
}
int main()
{
testing_boost_containers_basic_string();
testing_boost_containers_string_std_string();
testing_boost_containers_string_widening();
return boost::report_errors();
}
+150
View File
@@ -0,0 +1,150 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2026.
//
// 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/range/iterator_range.hpp>
#include <boost/core/lightweight_test.hpp>
#include <vector>
#include <boost/lexical_cast.hpp>
#include "escape_struct.hpp"
using namespace boost;
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
template <class T>
void do_test_on_empty_input(T& v)
{
BOOST_TEST_THROWS(lexical_cast<int>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<float>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<double>(v), bad_lexical_cast);
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
BOOST_TEST_THROWS(lexical_cast<long double>(v), bad_lexical_cast);
#endif
BOOST_TEST_THROWS(lexical_cast<unsigned int>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned short>(v), bad_lexical_cast);
#if defined(BOOST_HAS_LONG_LONG)
BOOST_TEST_THROWS(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<boost::long_long_type>(v), bad_lexical_cast);
#elif defined(BOOST_HAS_MS_INT64)
BOOST_TEST_THROWS(lexical_cast<unsigned __int64>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<__int64>(v), bad_lexical_cast);
#endif
}
void test_empty_iterator_range()
{
boost::iterator_range<char*> v;
do_test_on_empty_input(v);
BOOST_TEST_EQ(lexical_cast<std::string>(v), std::string());
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
boost::iterator_range<const char*> cv;
do_test_on_empty_input(cv);
BOOST_TEST_EQ(lexical_cast<std::string>(cv), std::string());
BOOST_TEST_THROWS(lexical_cast<char>(cv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(cv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(cv), bad_lexical_cast);
const boost::iterator_range<const char*> ccv;
do_test_on_empty_input(ccv);
BOOST_TEST_EQ(lexical_cast<std::string>(ccv), std::string());
BOOST_TEST_THROWS(lexical_cast<char>(ccv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(ccv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(ccv), bad_lexical_cast);
}
void test_empty_string()
{
std::string v;
do_test_on_empty_input(v);
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
#ifndef BOOST_LCAST_NO_WCHAR_T
std::wstring vw;
do_test_on_empty_input(vw);
BOOST_TEST_THROWS(lexical_cast<wchar_t>(vw), bad_lexical_cast);
#endif
// Currently, no compiler and STL library fully support char16_t and char32_t
//#ifndef BOOST_NO_CXX11_CHAR16_T
// std::basic_string<char16_t> v16w;
// do_test_on_empty_input(v16w);
// BOOST_TEST_THROWS(lexical_cast<char16_t>(v16w), bad_lexical_cast);
//#endif
//#ifndef BOOST_NO_CXX11_CHAR32_T
// std::basic_string<char32_t> v32w;
// do_test_on_empty_input(v32w);
// BOOST_TEST_THROWS(lexical_cast<char32_t>(v32w), bad_lexical_cast);
//#endif
}
void test_empty_user_class()
{
EscapeStruct v("");
do_test_on_empty_input(v);
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
}
namespace std {
inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v)
{
std::ostream_iterator<long> it(out);
std::copy(v.begin(), v.end(), it);
BOOST_TEST(out);
return out;
}
}
void test_empty_vector()
{
std::vector<long> v;
do_test_on_empty_input(v);
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
}
struct my_string {
friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) {
return sout << "";
}
};
void test_empty_zero_terminated_string()
{
my_string st;
BOOST_TEST_EQ(boost::lexical_cast<std::string>(st), std::string());;
}
int main()
{
test_empty_iterator_range();
test_empty_string();
test_empty_user_class();
test_empty_vector();
test_empty_zero_terminated_string();
return boost::report_errors();
}
+36
View File
@@ -0,0 +1,36 @@
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2020-2026.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
#ifndef BOOST_LEXICAL_CAST_TEST_ESCAPE_STRUCT_HPP_
#define BOOST_LEXICAL_CAST_TEST_ESCAPE_STRUCT_HPP_
#include <istream>
#include <ostream>
struct EscapeStruct
{
EscapeStruct() {}
EscapeStruct(const std::string& s)
: str_(s)
{}
std::string str_;
};
inline std::ostream& operator<< (std::ostream& o, const EscapeStruct& rhs)
{
return o << rhs.str_;
}
inline std::istream& operator>> (std::istream& i, EscapeStruct& rhs)
{
return i >> rhs.str_;
}
#endif // BOOST_LEXICAL_CAST_TEST_ESCAPE_STRUCT_HPP_
+60
View File
@@ -0,0 +1,60 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2013-2026.
//
// 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/core/lightweight_test.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/lexical_cast.hpp>
void test_filesystem()
{
boost::filesystem::path p;
std::string s1 = "aaaaaaaaaaaaaaaaaaaaaaa";
p = boost::lexical_cast<boost::filesystem::path>(s1);
BOOST_TEST(!p.empty());
BOOST_TEST_EQ(p, s1);
p.clear();
const char ab[] = "aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
p = boost::lexical_cast<boost::filesystem::path>(ab);
BOOST_TEST(!p.empty());
BOOST_TEST_EQ(p, ab);
// Tests for
// https://github.com/boostorg/lexical_cast/issues/25
const char quoted_path[] = "\"/home/my user\"";
p = boost::lexical_cast<boost::filesystem::path>(quoted_path);
BOOST_TEST(!p.empty());
const char unquoted_path[] = "/home/my user";
BOOST_TEST_EQ(p, boost::filesystem::path(unquoted_path));
// Converting back to std::string gives the initial string
BOOST_TEST_EQ(boost::lexical_cast<std::string>(p), quoted_path);
try {
// Without quotes the path will have only `/home/my` in it.
// `user` remains in the stream, so an exception must be thrown.
p = boost::lexical_cast<boost::filesystem::path>(unquoted_path);
BOOST_TEST(false);
} catch (const boost::bad_lexical_cast& ) {
// Exception is expected
}
}
int main()
{
test_filesystem();
return boost::report_errors();
}
+604
View File
@@ -0,0 +1,604 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2026.
//
// 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 <sstream>
#include <type_traits>
#include <boost/cstdint.hpp>
#include <boost/core/lightweight_test.hpp>
#ifndef BOOST_LEXICAL_CAST_DETAIL_TEST_ON_OLD
#include <boost/lexical_cast/detail/type_traits.hpp>
#include <boost/lexical_cast.hpp>
#else
// Make sure that tests work the same way on non-optimized version
#include "lexical_cast_old.hpp"
#include <boost/lexical_cast/detail/type_traits.hpp>
#endif
#ifndef BOOST_TEST_CLOSE_FRACTION
// Naiive, but works for most tests in this file
#define BOOST_TEST_CLOSE_FRACTION(x, y, eps) \
BOOST_TEST(x - y + eps <= eps * 2); \
BOOST_TEST(y - x + eps <= eps * 2);
#endif
#if (defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__NetBSD__) \
|| (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \
|| defined(__MINGW64__)
# define BOOST_LEXICAL_CAST_NO_LONG_DOUBLE_MATH_FUNCTIONS
#endif
using namespace boost;
// Replace "-,999" with "-999".
template<class CharT>
std::basic_string<CharT> to_str_gcc_workaround(std::basic_string<CharT> str)
{
std::locale loc;
std::numpunct<CharT> const& np = BOOST_USE_FACET(std::numpunct<CharT>, loc);
std::ctype<CharT> const& ct = BOOST_USE_FACET(std::ctype<CharT>, loc);
if(np.grouping().empty())
return str;
CharT prefix[3] = { ct.widen('-'), np.thousands_sep(), CharT() };
if(str.find(prefix) != 0)
return str;
prefix[1] = CharT();
str.replace(0, 2, prefix);
return str;
}
template<class CharT, class T>
std::basic_string<CharT> to_str(T t)
{
std::basic_ostringstream<CharT> o;
o << t;
return to_str_gcc_workaround(o.str());
}
template<class T>
void test_conversion_from_to_float_for_locale()
{
std::locale current_locale;
typedef std::numpunct<char> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, current_locale);
if ( !np.grouping().empty() )
{
BOOST_TEST_THROWS(
lexical_cast<T>( std::string("100") + np.thousands_sep() + np.thousands_sep() + "0" )
, bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( std::string("1") + np.thousands_sep() + np.decimal_point() + "e10" ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( std::string("1e10") + np.thousands_sep() ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( std::string("1") + np.thousands_sep() + "e10" ), bad_lexical_cast);
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( to_str< char >(100000) ), 100000, (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( to_str< char >(10000000u) ), 10000000u, (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( to_str< char >(100) ), 100, (std::numeric_limits<T>::epsilon()) );
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( to_str< wchar_t >(100000) ), 100000, (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( to_str< wchar_t >(10000000u) ), 10000000u, (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( to_str< wchar_t >(100) ), 100, (std::numeric_limits<T>::epsilon()) );
#endif
// Exception must not be thrown, when we are using no separators at all
BOOST_TEST_CLOSE_FRACTION( lexical_cast<T>("30000"), static_cast<T>(30000), (std::numeric_limits<T>::epsilon()) );
}
}
/*
* Converts char* [and wchar_t*] to float number type and checks, that generated
* number does not exceeds allowed epsilon.
*/
#ifndef BOOST_LCAST_NO_WCHAR_T
#define CHECK_CLOSE_ABS_DIFF(VAL,PREFIX) \
converted_val = lexical_cast<test_t>(#VAL); \
BOOST_TEST_CLOSE_FRACTION( (static_cast<bool>(VAL ## L)? VAL ## L : std::numeric_limits<test_t>::epsilon()), \
(converted_val ? converted_val : std::numeric_limits<test_t>::epsilon()), \
std::numeric_limits<test_t>::epsilon() \
); \
BOOST_TEST_EQ(converted_val, lexical_cast<test_t>(L## #VAL) );
#else
#define CHECK_CLOSE_ABS_DIFF(VAL,TYPE) \
converted_val = lexical_cast<test_t>(#VAL); \
BOOST_TEST_CLOSE_FRACTION( (static_cast<bool>(VAL ## L)? VAL ## L : std::numeric_limits<test_t>::epsilon()), \
(converted_val ? converted_val : std::numeric_limits<test_t>::epsilon()), \
std::numeric_limits<test_t>::epsilon() \
);
#endif
template <class TestType>
void test_converion_to_float_types()
{
typedef TestType test_t;
test_t converted_val;
BOOST_TEST_CLOSE_FRACTION(1.0, lexical_cast<test_t>('1'), (std::numeric_limits<test_t>::epsilon()));
BOOST_TEST_EQ(0.0, lexical_cast<test_t>('0'));
unsigned char const uc_one = '1';
unsigned char const uc_zero ='0';
BOOST_TEST_CLOSE_FRACTION(1.0, lexical_cast<test_t>(uc_one), (std::numeric_limits<test_t>::epsilon()));
BOOST_TEST_EQ(0.0, lexical_cast<test_t>(uc_zero));
signed char const sc_one = '1';
signed char const sc_zero ='0';
BOOST_TEST_CLOSE_FRACTION(1.0, lexical_cast<test_t>(sc_one), (std::numeric_limits<test_t>::epsilon()));
BOOST_TEST_EQ(0.0, lexical_cast<test_t>(sc_zero));
BOOST_TEST_CLOSE_FRACTION(1e34L, lexical_cast<test_t>( "10000000000000000000000000000000000"), (std::numeric_limits<test_t>::epsilon() * 1e34L) );
// VC failes the next test
// BOOST_TEST_CLOSE_FRACTION(1e-35L, lexical_cast<test_t>("0.00000000000000000000000000000000001"), (std::numeric_limits<test_t>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(
0.1111111111111111111111111111111111111111111111111111111111111111111111111L
, lexical_cast<test_t>("0.1111111111111111111111111111111111111111111111111111111111111111111111111")
, (std::numeric_limits<test_t>::epsilon()) );
CHECK_CLOSE_ABS_DIFF(1,test_t);
BOOST_TEST_EQ(0,lexical_cast<test_t>("0"));
CHECK_CLOSE_ABS_DIFF(-1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0, test_t);
CHECK_CLOSE_ABS_DIFF(0.0, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0,test_t);
CHECK_CLOSE_ABS_DIFF(1e1, test_t);
CHECK_CLOSE_ABS_DIFF(0e1, test_t);
CHECK_CLOSE_ABS_DIFF(-1e1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0e1,test_t);
CHECK_CLOSE_ABS_DIFF(1e-1, test_t);
CHECK_CLOSE_ABS_DIFF(0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1e-1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0e-1,test_t);
CHECK_CLOSE_ABS_DIFF(1E1, test_t);
CHECK_CLOSE_ABS_DIFF(0E1, test_t);
CHECK_CLOSE_ABS_DIFF(-1E1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0E1,test_t);
CHECK_CLOSE_ABS_DIFF(1E-1, test_t);
CHECK_CLOSE_ABS_DIFF(0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1E-1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(10.0, test_t);
CHECK_CLOSE_ABS_DIFF(00.0, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0,test_t);
CHECK_CLOSE_ABS_DIFF(10e1, test_t);
CHECK_CLOSE_ABS_DIFF(00e1, test_t);
CHECK_CLOSE_ABS_DIFF(-10e1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0e1,test_t);
CHECK_CLOSE_ABS_DIFF(10e-1, test_t);
CHECK_CLOSE_ABS_DIFF(00e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10e-1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0e-1,test_t);
CHECK_CLOSE_ABS_DIFF(10E1, test_t);
CHECK_CLOSE_ABS_DIFF(00E1, test_t);
CHECK_CLOSE_ABS_DIFF(-10E1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0E1,test_t);
CHECK_CLOSE_ABS_DIFF(10E-1, test_t);
CHECK_CLOSE_ABS_DIFF(00E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10E-1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10101.0E-011, test_t);
CHECK_CLOSE_ABS_DIFF(-10101093, test_t);
CHECK_CLOSE_ABS_DIFF(10101093, test_t);
CHECK_CLOSE_ABS_DIFF(-.34, test_t);
CHECK_CLOSE_ABS_DIFF(.34, test_t);
CHECK_CLOSE_ABS_DIFF(.34e10, test_t);
BOOST_TEST_THROWS(lexical_cast<test_t>("-1.e"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("-1.E"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.e"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.E"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0e"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0E"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("10E"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("10e"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0e-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0E-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("10E-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("10e-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("e1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("e-1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("e-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>(".e"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>(".11111111111111111111111111111111111111111111111111111111111111111111ee"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>(".11111111111111111111111111111111111111111111111111111111111111111111e-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("."), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("-B"), bad_lexical_cast);
// Following two tests are not valid for C++11 compilers
//BOOST_TEST_THROWS(lexical_cast<test_t>("0xB"), bad_lexical_cast);
//BOOST_TEST_THROWS(lexical_cast<test_t>("0x0"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("--1.0"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0e--1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0.0"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1e1e1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0e-1e-1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>(" 1.0"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("1.0 "), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>(""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("-"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>('\0'), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>('-'), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>('.'), bad_lexical_cast);
}
template <class T>
void test_float_typess_for_overflows()
{
typedef T test_t;
test_t minvalue = (std::numeric_limits<test_t>::min)();
std::string s_min_value = lexical_cast<std::string>(minvalue);
BOOST_TEST_CLOSE_FRACTION(minvalue, lexical_cast<test_t>(minvalue), (std::numeric_limits<test_t>::epsilon()));
BOOST_TEST_CLOSE_FRACTION(minvalue, lexical_cast<test_t>(s_min_value), (std::numeric_limits<test_t>::epsilon() * 2));
test_t maxvalue = (std::numeric_limits<test_t>::max)();
std::string s_max_value = lexical_cast<std::string>(maxvalue);
BOOST_TEST_CLOSE_FRACTION(maxvalue, lexical_cast<test_t>(maxvalue), (std::numeric_limits<test_t>::epsilon()));
BOOST_TEST_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_TEST_THROWS(lexical_cast<test_t>(s_max_value+"1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>(s_max_value+"9"), bad_lexical_cast);
// VC9 can fail the following tests on floats and doubles when using stingstream...
BOOST_TEST_THROWS(lexical_cast<test_t>("1"+s_max_value), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<test_t>("9"+s_max_value), bad_lexical_cast);
#endif
#if !(defined(_LIBCPP_VERSION) && defined(BOOST_LEXICAL_CAST_DETAIL_TEST_ON_OLD))
if ( std::is_same<test_t,float>::value )
{
BOOST_TEST_THROWS(lexical_cast<test_t>( (std::numeric_limits<double>::max)() ), bad_lexical_cast);
BOOST_TEST(
(std::numeric_limits<double>::min)() - std::numeric_limits<test_t>::epsilon()
<= lexical_cast<test_t>( (std::numeric_limits<double>::min)() )
&& lexical_cast<test_t>( (std::numeric_limits<double>::min)() )
<= (std::numeric_limits<double>::min)() + std::numeric_limits<test_t>::epsilon()
);
BOOST_TEST(
(std::numeric_limits<double>::min)() / 2 - std::numeric_limits<test_t>::epsilon()
<= lexical_cast<test_t>( (std::numeric_limits<double>::min)() / 2 )
&& lexical_cast<test_t>( (std::numeric_limits<double>::min)() / 2 )
<= (std::numeric_limits<double>::min)() / 2 + std::numeric_limits<test_t>::epsilon()
);
}
if ( sizeof(test_t) < sizeof(long double) )
{
BOOST_TEST_THROWS(lexical_cast<test_t>( (std::numeric_limits<long double>::max)() ), bad_lexical_cast);
BOOST_TEST(
(std::numeric_limits<long double>::min)() - std::numeric_limits<test_t>::epsilon()
<= lexical_cast<test_t>( (std::numeric_limits<long double>::min)() )
&& lexical_cast<test_t>( (std::numeric_limits<long double>::min)() )
<= (std::numeric_limits<long double>::min)() + std::numeric_limits<test_t>::epsilon()
);
BOOST_TEST(
(std::numeric_limits<long double>::min)() / 2 - std::numeric_limits<test_t>::epsilon()
<= lexical_cast<test_t>( (std::numeric_limits<long double>::min)() / 2 )
&& lexical_cast<test_t>( (std::numeric_limits<long double>::min)() / 2 )
<= (std::numeric_limits<long double>::min)() / 2 + std::numeric_limits<test_t>::epsilon()
);
}
#endif
}
#undef CHECK_CLOSE_ABS_DIFF
// Epsilon is multiplied by 2 because of two lexical conversions
#define TEST_TO_FROM_CAST_AROUND_TYPED(VAL,STRING_TYPE) \
test_value = VAL + std::numeric_limits<test_t>::epsilon() * i ; \
converted_val = lexical_cast<test_t>( lexical_cast<STRING_TYPE>(test_value) ); \
BOOST_TEST_CLOSE_FRACTION( \
test_value, \
converted_val, \
std::numeric_limits<test_t>::epsilon() * 2 \
);
/*
* For interval [ from_mult*epsilon+VAL, to_mult*epsilon+VAL ], converts float type
* numbers to string[wstring] and then back to float type, then compares initial
* values and generated.
* Step is epsilon
*/
#ifndef BOOST_LCAST_NO_WCHAR_T
# define TEST_TO_FROM_CAST_AROUND(VAL) \
for(i=from_mult; i<=to_mult; ++i) { \
TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::string) \
TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::wstring) \
}
#else
# define TEST_TO_FROM_CAST_AROUND(VAL) \
for(i=from_mult; i<=to_mult; ++i) { \
TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::string) \
}
#endif
template <class TestType>
void test_converion_from_to_float_types()
{
typedef TestType test_t;
test_t test_value;
test_t converted_val;
int i;
int from_mult = -50;
int to_mult = 50;
TEST_TO_FROM_CAST_AROUND( 0.0 );
long double val1;
for(val1 = 1.0e-10L; val1 < 1e11; val1*=10 )
TEST_TO_FROM_CAST_AROUND( val1 );
long double val2;
for(val2 = -1.0e-10L; val2 > -1e11; val2*=10 )
TEST_TO_FROM_CAST_AROUND( val2 );
from_mult = -100;
to_mult = 0;
TEST_TO_FROM_CAST_AROUND( (std::numeric_limits<test_t>::max)() );
from_mult = 0;
to_mult = 100;
TEST_TO_FROM_CAST_AROUND( (std::numeric_limits<test_t>::min)() );
}
#undef TEST_TO_FROM_CAST_AROUND
#undef TEST_TO_FROM_CAST_AROUND_TYPED
template<class T, class CharT>
void test_conversion_from_float_to_char(CharT zero)
{
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(0)) == zero + 0);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(1)) == zero + 1);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(2)) == zero + 2);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(3)) == zero + 3);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(4)) == zero + 4);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(5)) == zero + 5);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(6)) == zero + 6);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(7)) == zero + 7);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(8)) == zero + 8);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(9)) == zero + 9);
BOOST_TEST_THROWS(lexical_cast<CharT>(static_cast<T>(10)), bad_lexical_cast);
T t = (std::numeric_limits<T>::max)();
BOOST_TEST_THROWS(lexical_cast<CharT>(t), bad_lexical_cast);
}
template<class T, class CharT>
void test_conversion_from_char_to_float(CharT zero)
{
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 0)), static_cast<T>(0), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 1)), static_cast<T>(1), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 2)), static_cast<T>(2), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 3)), static_cast<T>(3), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 4)), static_cast<T>(4), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 5)), static_cast<T>(5), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 6)), static_cast<T>(6), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 7)), static_cast<T>(7), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 8)), static_cast<T>(8), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 9)), static_cast<T>(9), (std::numeric_limits<T>::epsilon()) );
BOOST_TEST_THROWS(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
}
struct restore_oldloc
{
std::locale oldloc;
~restore_oldloc() { std::locale::global(oldloc); }
};
template<class T>
void test_conversion_from_to_float()
{ char const zero = '0';
signed char const szero = '0';
unsigned char const uzero = '0';
test_conversion_from_float_to_char<T>(zero);
test_conversion_from_char_to_float<T>(zero);
test_conversion_from_float_to_char<T>(szero);
test_conversion_from_char_to_float<T>(szero);
test_conversion_from_float_to_char<T>(uzero);
test_conversion_from_char_to_float<T>(uzero);
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
wchar_t const wzero = L'0';
test_conversion_from_float_to_char<T>(wzero);
test_conversion_from_char_to_float<T>(wzero);
#endif
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>("+1"), 1, std::numeric_limits<T>::epsilon());
BOOST_TEST_CLOSE_FRACTION(lexical_cast<T>("+9"), 9, std::numeric_limits<T>::epsilon());
BOOST_TEST_THROWS(lexical_cast<T>("++1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("-+9"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("--1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("+-9"), bad_lexical_cast);
test_converion_to_float_types<T>();
test_float_typess_for_overflows<T>();
test_converion_from_to_float_types<T>();
typedef std::numpunct<char> numpunct;
restore_oldloc guard;
std::locale const& oldloc = guard.oldloc;
std::string grouping1 = BOOST_USE_FACET(numpunct, oldloc).grouping();
std::string grouping2(grouping1);
test_conversion_from_to_float_for_locale<T>();
try
{
std::locale newloc("");
std::locale::global(newloc);
grouping2 = BOOST_USE_FACET(numpunct, newloc).grouping();
}
catch(std::exception const& ex)
{
std::string msg("Failed to set system locale: ");
msg += ex.what();
std::cerr << msg;
}
if(grouping1 != grouping2)
test_conversion_from_to_float_for_locale<T>();
if(grouping1.empty() && grouping2.empty())
std::cerr << "Formatting with thousands_sep has not been tested";
}
void test_conversion_from_to_float()
{
test_conversion_from_to_float<float>();
}
void test_conversion_from_to_double()
{
test_conversion_from_to_float<double>();
}
void test_conversion_from_to_long_double()
{
// We do not run tests on compilers and Standard Libraries with poor support of long double
#if !defined(BOOST_LEXICAL_CAST_NO_LONG_DOUBLE_MATH_FUNCTIONS)
test_conversion_from_to_float<long double>();
#endif
BOOST_TEST(true);
}
template <class Integral, class Float>
void test_conversion_integral_float()
{
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>(static_cast<Float>(1)), static_cast<Float>(1), std::numeric_limits<Float>::epsilon());
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>(static_cast<Float>(1.1234)), static_cast<Float>(1.1234), std::numeric_limits<Float>::epsilon());
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>(static_cast<Float>(-1.1234)), static_cast<Float>(-1.1234), std::numeric_limits<Float>::epsilon());
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>(static_cast<Integral>(0)), static_cast<Float>(0), std::numeric_limits<Float>::epsilon());
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>(static_cast<Integral>(1)), static_cast<Float>(1), std::numeric_limits<Float>::epsilon());
#ifndef __CYGWIN__
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>((std::numeric_limits<Integral>::max)()), static_cast<Float>((std::numeric_limits<Integral>::max)()), std::numeric_limits<Float>::epsilon());
BOOST_TEST_CLOSE_FRACTION(lexical_cast<Float>((std::numeric_limits<Integral>::min)()), static_cast<Float>((std::numeric_limits<Integral>::min)()), std::numeric_limits<Float>::epsilon());
#endif
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(0.0)), 0);
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(1.0)), 1);
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(8.0)), 8);
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(16.0)), 16);
if (boost::detail::lcast::is_signed<Integral>::value) {
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(-1.0)), -1);
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(-8.0)), -8);
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(-16.0)), -16);
} else {
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(-1.0)), (std::numeric_limits<Integral>::max)());
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(-8.0)), (std::numeric_limits<Integral>::max)() - 7);
BOOST_TEST_EQ(lexical_cast<Integral>(static_cast<Float>(-16.0)), (std::numeric_limits<Integral>::max)() - 15);
}
BOOST_TEST_THROWS(lexical_cast<Integral>(static_cast<Float>(0.5)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(static_cast<Float>(-0.5)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(static_cast<Float>(1.5)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(static_cast<Float>(-1.5)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>((std::numeric_limits<Float>::min)()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>((std::numeric_limits<Float>::max)()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>((std::numeric_limits<Float>::epsilon)()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>((std::numeric_limits<Float>::lowest)()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<Float>::quiet_NaN()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<Float>::quiet_NaN()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<Float>::infinity()), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<Float>::infinity()), bad_lexical_cast);
}
int main()
{
test_conversion_from_to_float();
test_conversion_from_to_double();
test_conversion_from_to_long_double();
test_conversion_integral_float<int, float>();
test_conversion_integral_float<int, double>();
test_conversion_integral_float<unsigned short, float>();
test_conversion_integral_float<unsigned short, double>();
test_conversion_integral_float<short, float>();
test_conversion_integral_float<short, double>();
test_conversion_integral_float<long int, float>();
test_conversion_integral_float<long int, double>();
test_conversion_integral_float<long long, float>();
test_conversion_integral_float<long long, double>();
test_conversion_integral_float<unsigned long long, float>();
test_conversion_integral_float<unsigned long long, double>();
return boost::report_errors();
}
+16
View File
@@ -0,0 +1,16 @@
// Copyright Antony Polukhin, 2013-2026.
//
// 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 <string>
int main()
{
volatile int i = 42;
boost::lexical_cast<std::string>(i);
return 1;
}
-38
View File
@@ -1,38 +0,0 @@
// Copyright David Abrahams 2003.
// 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/implicit_cast.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/type.hpp>
using boost::implicit_cast;
using boost::type;
template <class T>
type<T> check_return(T) { return type<T>(); }
struct foo
{
foo(char const*) {}
operator long() const { return 0; }
};
typedef type<long> long_type;
typedef type<foo> foo_type;
int main()
{
type<long> x = check_return(boost::implicit_cast<long>(1));
BOOST_TEST(boost::implicit_cast<long>(1) == 1L);
type<foo> f = check_return(boost::implicit_cast<foo>("hello"));
type<long> z = check_return(boost::implicit_cast<long>(foo("hello")));
// warning supression:
(void)x;
(void)f;
(void)z;
return boost::report_errors();
}
-26
View File
@@ -1,26 +0,0 @@
// Copyright David Abrahams 2003.
// 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/implicit_cast.hpp>
#include <boost/type.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
using boost::implicit_cast;
struct foo
{
explicit foo(char const*) {}
};
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
return 0;
}
+63
View File
@@ -0,0 +1,63 @@
// Copyright Antony Polukhin, 2023-2026.
//
// 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/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
struct oops {
operator int () const {
return 41;
}
};
inline std::ostream& operator<<(std::ostream& os, const oops&) {
return os << 42;
}
struct oops2 {
operator double () const {
return 1.12;
}
};
inline std::ostream& operator<<(std::ostream& os, const oops2&) {
return os << 2;
}
struct Value {
explicit Value(double x) : x(x) {}
operator double() const {
return x;
}
double x;
};
int main() {
BOOST_TEST_EQ(boost::lexical_cast<int>(oops{}), 42);
BOOST_TEST_EQ(boost::lexical_cast<std::string>(oops{}), "42");
BOOST_TEST_EQ(boost::lexical_cast<double>(oops2{}), 2);
BOOST_TEST_EQ(boost::lexical_cast<std::string>(oops2{}), "2");
Value longer_that_1_digit(128);
BOOST_TEST_EQ(boost::lexical_cast<std::string>(longer_that_1_digit), "128");
// iostreams have default precision 6, see [basic.ios.cons]
const double precision_more_than_6_digits = 1.23456789123;
// At the moment we do not set the precision for types that use conversion
// operators for ostreaming, so the below test pass. We do not set precision
// for user provided `operator<<`, types with conversion operators follow
// the same design decision for now.
BOOST_TEST_NE(
boost::lexical_cast<std::string>(Value(precision_more_than_6_digits)),
boost::lexical_cast<std::string>(precision_more_than_6_digits)
);
return boost::report_errors();
}
+242
View File
@@ -0,0 +1,242 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2026.
//
// 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 <type_traits>
#include <boost/core/cmath.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
using namespace boost;
template <class T>
bool is_pos_inf(T value)
{
return (boost::core::isinf)(value) && !(boost::core::signbit)(value);
}
template <class T>
bool is_neg_inf(T value)
{
return (boost::core::isinf)(value) && (boost::core::signbit)(value);
}
template <class T>
bool is_pos_nan(T value)
{
return (boost::core::isnan)(value) && !(boost::core::signbit)(value);
}
template <class T>
bool is_neg_nan(T value)
{
/* There is some strange behaviour on Itanium platform with -nan nuber for long double.
* It is a IA64 feature, or it is a boost::math feature, not a lexical_cast bug */
#if defined(__ia64__) || defined(_M_IA64)
return (boost::core::isnan)(value)
&& ( std::is_same<T, long double >::value || (boost::core::signbit)(value) );
#else
return (boost::core::isnan)(value) && (boost::core::signbit)(value);
#endif
}
template <class T>
void test_inf_nan_templated()
{
typedef T test_t;
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("inf") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("INF") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-inf") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-INF") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+inf") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+INF") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("infinity") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("INFINITY") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-infinity") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-INFINITY") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+infinity") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("+INFINITY") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("iNfiNity") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>("INfinity") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-inFINITY") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>("-INFINITY") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("nan") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("NAN") ) );
BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-nan") ) );
BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-NAN") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+nan") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+NAN") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("nAn") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("NaN") ) );
BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-nAn") ) );
BOOST_TEST( is_neg_nan( lexical_cast<test_t>("-NaN") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+Nan") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("+nAN") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("nan()") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>("NAN(some string)") ) );
BOOST_TEST_THROWS( lexical_cast<test_t>("NAN(some string"), bad_lexical_cast );
BOOST_TEST(lexical_cast<std::string>( (boost::core::copysign)(std::numeric_limits<test_t >::infinity(), static_cast<test_t>(-1.0)))
== "-inf" );
BOOST_TEST(lexical_cast<std::string>( std::numeric_limits<test_t >::infinity()) == "inf" );
BOOST_TEST(lexical_cast<std::string>( std::numeric_limits<test_t >::quiet_NaN()) == "nan" );
#if !defined(__ia64__) && !defined(_M_IA64)
BOOST_TEST(lexical_cast<std::string>(
(boost::core::copysign)(std::numeric_limits<test_t >::quiet_NaN(), static_cast<test_t>(-1.0)))
== "-nan" );
#endif
#ifndef BOOST_LCAST_NO_WCHAR_T
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"inf") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"INF") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-inf") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-INF") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+inf") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+INF") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"infinity") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"INFINITY") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-infinity") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-INFINITY") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+infinity") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+INFINITY") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-infINIty") ) );
BOOST_TEST( is_neg_inf( lexical_cast<test_t>(L"-INFiniTY") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+inFINIty") ) );
BOOST_TEST( is_pos_inf( lexical_cast<test_t>(L"+INfinITY") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"nan") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"NAN") ) );
BOOST_TEST( is_neg_nan( lexical_cast<test_t>(L"-nan") ) );
BOOST_TEST( is_neg_nan( lexical_cast<test_t>(L"-NAN") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"+nan") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"+NAN") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"nan()") ) );
BOOST_TEST( is_pos_nan( lexical_cast<test_t>(L"NAN(some string)") ) );
BOOST_TEST_THROWS( lexical_cast<test_t>(L"NAN(some string"), bad_lexical_cast );
BOOST_TEST(lexical_cast<std::wstring>( (boost::core::copysign)(std::numeric_limits<test_t >::infinity(), static_cast<test_t>(-1.0)))
== L"-inf" );
BOOST_TEST(lexical_cast<std::wstring>( std::numeric_limits<test_t >::infinity()) == L"inf" );
BOOST_TEST(lexical_cast<std::wstring>( std::numeric_limits<test_t >::quiet_NaN()) == L"nan" );
#if !defined(__ia64__) && !defined(_M_IA64)
BOOST_TEST(lexical_cast<std::wstring>(
(boost::core::copysign)(std::numeric_limits<test_t >::quiet_NaN(), static_cast<test_t>(-1.0)))
== L"-nan" );
#endif
#endif
}
void test_inf_nan_float()
{
test_inf_nan_templated<float >();
BOOST_TEST(is_pos_nan(lexical_cast<float>(std::numeric_limits<float>::quiet_NaN())));
BOOST_TEST(is_neg_nan(lexical_cast<float>(-std::numeric_limits<float>::quiet_NaN())));
BOOST_TEST(is_pos_inf(lexical_cast<float>(std::numeric_limits<float>::infinity())));
BOOST_TEST(is_neg_inf(lexical_cast<float>(-std::numeric_limits<float>::infinity())));
BOOST_TEST(is_pos_nan(lexical_cast<float>(std::numeric_limits<double>::quiet_NaN())));
BOOST_TEST(is_neg_nan(lexical_cast<float>(-std::numeric_limits<double>::quiet_NaN())));
BOOST_TEST(is_pos_inf(lexical_cast<float>(std::numeric_limits<double>::infinity())));
BOOST_TEST(is_neg_inf(lexical_cast<float>(-std::numeric_limits<double>::infinity())));
}
void test_inf_nan_double()
{
test_inf_nan_templated<double >();
BOOST_TEST(is_pos_nan(lexical_cast<double>(std::numeric_limits<float>::quiet_NaN())));
BOOST_TEST(is_neg_nan(lexical_cast<double>(-std::numeric_limits<float>::quiet_NaN())));
BOOST_TEST(is_pos_inf(lexical_cast<double>(std::numeric_limits<float>::infinity())));
BOOST_TEST(is_neg_inf(lexical_cast<double>(-std::numeric_limits<float>::infinity())));
BOOST_TEST(is_pos_nan(lexical_cast<double>(std::numeric_limits<double>::quiet_NaN())));
BOOST_TEST(is_neg_nan(lexical_cast<double>(-std::numeric_limits<double>::quiet_NaN())));
BOOST_TEST(is_pos_inf(lexical_cast<double>(std::numeric_limits<double>::infinity())));
BOOST_TEST(is_neg_inf(lexical_cast<double>(-std::numeric_limits<double>::infinity())));
BOOST_TEST(is_pos_nan(lexical_cast<double>(std::numeric_limits<long double>::quiet_NaN())));
BOOST_TEST(is_neg_nan(lexical_cast<double>(-std::numeric_limits<long double>::quiet_NaN())));
BOOST_TEST(is_pos_inf(lexical_cast<double>(std::numeric_limits<long double>::infinity())));
BOOST_TEST(is_neg_inf(lexical_cast<double>(-std::numeric_limits<long double>::infinity())));
}
void test_inf_nan_long_double()
{
// We do not run tests on compilers with bugs
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
test_inf_nan_templated<long double >();
#endif
BOOST_TEST(true);
}
template <class Integral>
void test_inf_nan_to_integral()
{
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<float>::quiet_NaN()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<float>::quiet_NaN()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<float>::infinity()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<float>::infinity()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<double>::quiet_NaN()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<double>::quiet_NaN()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<double>::infinity()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<double>::infinity()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<long double>::quiet_NaN()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<long double>::quiet_NaN()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(std::numeric_limits<long double>::infinity()), boost::bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<Integral>(-std::numeric_limits<long double>::infinity()), boost::bad_lexical_cast);
}
int main()
{
test_inf_nan_float();
test_inf_nan_double();
test_inf_nan_long_double();
test_inf_nan_to_integral<int>();
test_inf_nan_to_integral<bool>();
test_inf_nan_to_integral<short>();
return boost::report_errors();
}
@@ -4,7 +4,7 @@
//
// Copyright Terje Sletteb and Kevlin Henney, 2005.
// Copyright Alexander Nasonov, 2006.
// Copyright Antony Polukhin, 2011-2012.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -19,25 +19,20 @@
//
#define _SCL_SECURE_NO_WARNINGS
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/cstdint.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast/detail/type_traits.hpp>
#include <boost/type_traits/integral_promotion.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
#include <type_traits>
#include <boost/lexical_cast.hpp>
#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
&& !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
@@ -48,6 +43,11 @@
#define BOOST_LCAST_NO_WCHAR_T
#endif
// There's no typeinfo for unsigned __int128 in Xcode_15.0.1
#if defined(BOOST_HAS_INT128) && !defined(BOOST_LEXICAL_CAST_TEST_NO_128_INTS) && !defined(__APPLE__)
# define BOOST_LCAST_TEST_128 1
#endif
// Test all 65536 values if true:
bool const lcast_test_small_integral_types_completely = false;
@@ -57,112 +57,65 @@ 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();
void test_conversion_from_to_uint();
void test_conversion_from_to_long();
void test_conversion_from_to_ulong();
void test_conversion_from_to_intmax_t();
void test_conversion_from_to_uintmax_t();
#ifdef LCAST_TEST_LONGLONG
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();
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast unit test on integral types");
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_short));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ushort));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_int));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uint));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_ulong));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_intmax_t));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_uintmax_t));
#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));
return suite;
}
template<class T, class CharT>
void test_conversion_from_integral_to_char(CharT zero)
{
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(0)) == zero + 0);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(1)) == zero + 1);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(2)) == zero + 2);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(3)) == zero + 3);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(4)) == zero + 4);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(5)) == zero + 5);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(6)) == zero + 6);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(7)) == zero + 7);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(8)) == zero + 8);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(9)) == zero + 9);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(0)) == zero + 0);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(1)) == zero + 1);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(2)) == zero + 2);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(3)) == zero + 3);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(4)) == zero + 4);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(5)) == zero + 5);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(6)) == zero + 6);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(7)) == zero + 7);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(8)) == zero + 8);
BOOST_TEST(lexical_cast<CharT>(static_cast<T>(9)) == zero + 9);
BOOST_CHECK_THROW(lexical_cast<CharT>(static_cast<T>(10)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<CharT>(static_cast<T>(10)), bad_lexical_cast);
T t = (std::numeric_limits<T>::max)();
BOOST_CHECK_THROW(lexical_cast<CharT>(t), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<CharT>(t), bad_lexical_cast);
}
template<class T, class CharT>
void test_conversion_from_char_to_integral(CharT zero)
{
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 0)) == static_cast<T>(0) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 1)) == static_cast<T>(1) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 2)) == static_cast<T>(2) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 3)) == static_cast<T>(3) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 4)) == static_cast<T>(4) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 5)) == static_cast<T>(5) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 6)) == static_cast<T>(6) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 7)) == static_cast<T>(7) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 8)) == static_cast<T>(8) );
BOOST_CHECK(lexical_cast<T>( static_cast<CharT>(zero + 9)) == static_cast<T>(9) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 0)) == static_cast<T>(0) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 1)) == static_cast<T>(1) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 2)) == static_cast<T>(2) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 3)) == static_cast<T>(3) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 4)) == static_cast<T>(4) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 5)) == static_cast<T>(5) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 6)) == static_cast<T>(6) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 7)) == static_cast<T>(7) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 8)) == static_cast<T>(8) );
BOOST_TEST(lexical_cast<T>( static_cast<CharT>(zero + 9)) == static_cast<T>(9) );
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
}
template<class T>
void test_conversion_from_integral_to_integral()
{
T t = 0;
BOOST_CHECK(lexical_cast<T>(t) == t);
BOOST_TEST(lexical_cast<T>(t) == t);
// Next two variables are used to supress warnings.
// Next two variables are used to suppress warnings.
int st = 32767; unsigned int ut = st;
t = st;
BOOST_CHECK(lexical_cast<short>(t) == st);
BOOST_CHECK(lexical_cast<unsigned short>(t) == ut);
BOOST_CHECK(lexical_cast<int>(t) == st);
BOOST_CHECK(lexical_cast<unsigned int>(t) == ut);
BOOST_CHECK(lexical_cast<long>(t) == st);
BOOST_CHECK(lexical_cast<unsigned long>(t) == ut);
BOOST_TEST(lexical_cast<short>(t) == st);
BOOST_TEST(lexical_cast<unsigned short>(t) == ut);
BOOST_TEST(lexical_cast<int>(t) == st);
BOOST_TEST(lexical_cast<unsigned int>(t) == ut);
BOOST_TEST(lexical_cast<long>(t) == st);
BOOST_TEST(lexical_cast<unsigned long>(t) == ut);
t = (std::numeric_limits<T>::max)();
BOOST_CHECK(lexical_cast<T>(t) == t);
BOOST_TEST(lexical_cast<T>(t) == t);
t = (std::numeric_limits<T>::min)();
BOOST_CHECK(lexical_cast<T>(t) == t);
BOOST_TEST(lexical_cast<T>(t) == t);
}
@@ -207,39 +160,39 @@ void test_conversion_from_integral_to_string(CharT)
T t;
t = (limits::min)();
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
t = (limits::max)();
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
if(limits::digits <= 16 && lcast_test_small_integral_types_completely)
// min and max have already been tested.
for(t = 1 + (limits::min)(); t != (limits::max)(); ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
else
{
T const min_val = (limits::min)();
T const max_val = (limits::max)();
T const half_max_val = max_val / 2;
T const cnt = lcast_integral_test_counter; // to supress warnings
unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
T const cnt = lcast_integral_test_counter; // to suppress warnings
T const counter = cnt < half_max_val ? cnt : half_max_val;
unsigned int i;
T i = 0;
// Test values around min:
t = min_val;
for(i = 0; i < counter; ++i, ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around max:
t = max_val;
for(i = 0; i < counter; ++i, --t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around zero:
if(limits::is_signed)
for(t = static_cast<T>(-counter); t < static_cast<T>(counter); ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
// Test values around 100, 1000, 10000, ...
T ten_power = 100;
@@ -247,7 +200,7 @@ void test_conversion_from_integral_to_string(CharT)
{
// ten_power + 100 probably never overflows
for(t = ten_power - 100; t != ten_power + 100; ++t)
BOOST_CHECK(lexical_cast<string_type>(t) == to_str<CharT>(t));
BOOST_TEST(lexical_cast<string_type>(t) == to_str<CharT>(t));
}
}
}
@@ -265,23 +218,23 @@ void test_conversion_from_string_to_integral(CharT)
T const max_val = (limits::max)();
s = to_str<CharT>(min_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(s), min_val);
BOOST_TEST_EQ(lexical_cast<T>(s), min_val);
if(limits::is_signed)
{
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s + nine), bad_lexical_cast);
}
s = to_str<CharT>(max_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(s), max_val);
BOOST_TEST_EQ(lexical_cast<T>(s), max_val);
{
BOOST_CHECK_THROW(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(s + nine), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s + zero), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s + nine), bad_lexical_cast);
s = to_str<CharT>(max_val);
for (int i =1; i <=10; ++i) {
s[s.size()-1] += 1;
BOOST_CHECK_THROW(lexical_cast<T>( s ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( s ), bad_lexical_cast);
}
s = to_str<CharT>(max_val);
@@ -289,23 +242,23 @@ void test_conversion_from_string_to_integral(CharT)
typedef std::numpunct<char> numpunct;
if ( BOOST_USE_FACET(numpunct, loc).grouping().empty() ) {
// Following tests work well for locale C
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+s), max_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
BOOST_CHECK_EQUAL(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
BOOST_TEST_EQ(lexical_cast<T>(to_str<CharT>(0)+s), max_val);
BOOST_TEST_EQ(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
BOOST_TEST_EQ(lexical_cast<T>(to_str<CharT>(0)+to_str<CharT>(0)+to_str<CharT>(0)+s), max_val);
}
for (int i =1; i <=256; ++i) {
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
}
typedef BOOST_DEDUCED_TYPENAME boost::integral_promotion<T>::type promoted;
if ( !(boost::is_same<T, promoted>::value) )
typedef typename boost::integral_promotion<T>::type promoted;
if ( !(std::is_same<T, promoted>::value) )
{
promoted prom = max_val;
s = to_str<CharT>(max_val);
for (int i =1; i <=256; ++i) {
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(prom+i) ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( to_str<CharT>(prom+i) ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( to_str<CharT>(i)+s ), bad_lexical_cast);
}
}
}
@@ -313,30 +266,30 @@ void test_conversion_from_string_to_integral(CharT)
if(limits::digits <= 16 && lcast_test_small_integral_types_completely)
// min and max have already been tested.
for(T t = 1 + min_val; t != max_val; ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
BOOST_TEST(lexical_cast<T>(to_str<CharT>(t)) == t);
else
{
T const half_max_val = max_val / 2;
T const cnt = lcast_integral_test_counter; // to supress warnings
unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
T const cnt = lcast_integral_test_counter; // to suppress warnings
T const counter = cnt < half_max_val ? cnt : half_max_val;
T t;
unsigned int i;
T i;
// Test values around min:
t = min_val;
for(i = 0; i < counter; ++i, ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
BOOST_TEST(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around max:
t = max_val;
for(i = 0; i < counter; ++i, --t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
BOOST_TEST(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around zero:
if(limits::is_signed)
for(t = static_cast<T>(-counter); t < static_cast<T>(counter); ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
BOOST_TEST(lexical_cast<T>(to_str<CharT>(t)) == t);
// Test values around 100, 1000, 10000, ...
T ten_power = 100;
@@ -344,7 +297,7 @@ void test_conversion_from_string_to_integral(CharT)
{
// ten_power + 100 probably never overflows
for(t = ten_power - 100; t != ten_power + 100; ++t)
BOOST_CHECK(lexical_cast<T>(to_str<CharT>(t)) == t);
BOOST_TEST(lexical_cast<T>(to_str<CharT>(t)) == t);
}
}
}
@@ -357,32 +310,32 @@ void test_conversion_from_to_integral_for_locale()
numpunct const& np = BOOST_USE_FACET(numpunct, current_locale);
if ( !np.grouping().empty() )
{
BOOST_CHECK_THROW(
BOOST_TEST_THROWS(
lexical_cast<T>( std::string("100") + np.thousands_sep() + np.thousands_sep() + "0" )
, bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
// Exception must not be thrown, when we are using no separators at all
BOOST_CHECK( lexical_cast<T>("30000") == static_cast<T>(30000) );
BOOST_TEST( lexical_cast<T>("30000") == static_cast<T>(30000) );
}
test_conversion_from_integral_to_integral<T>();
// This is a part of test_conversion_from_integral_to_string<T>('0') method,
// but with BOOST_CHECK_EQUAL instead of BOOST_CHECK. It is required to see
// what is produced by the to_str<char>(t) method in situations when result
// is different. BOOST_CHECK does not work with wchar_t.
// but with BOOST_TEST_EQ instead of BOOST_TEST. It is required to see
// what is produced by the to_str<char>(t) method in situations when result
// is different. BOOST_TEST does not work with wchar_t.
typedef std::numeric_limits<T> limits;
T t = (limits::min)();
BOOST_CHECK_EQUAL(lexical_cast<std::string>(t), to_str<char>(t));
BOOST_TEST_EQ(lexical_cast<std::string>(t), to_str<char>(t));
test_conversion_from_integral_to_string<T>('0');
test_conversion_from_string_to_integral<T>('0');
#if !defined(BOOST_LCAST_NO_WCHAR_T)
if (lexical_cast<std::wstring>(t) != to_str<wchar_t>(t)) {
// Something went wrong, and now we are attempting to find and print the
// Something went wrong, and now we are attempting to find and print the
// difference.
std::wstring wstr = to_str<wchar_t>(t);
std::string lcast_str = lexical_cast<std::string>(t);
@@ -391,10 +344,10 @@ void test_conversion_from_to_integral_for_locale()
for (std::size_t i = 0; i < wstr.size(); ++i) {
str.push_back(static_cast<char>(wstr[i]));
}
BOOST_CHECK_EQUAL(lcast_str.length(), lexical_cast<std::wstring>(t).length());
BOOST_CHECK_EQUAL(to_str<char>(t), str);
BOOST_CHECK_EQUAL(lcast_str, str);
BOOST_TEST_EQ(lcast_str.length(), lexical_cast<std::wstring>(t).length());
BOOST_TEST_EQ(to_str<char>(t), str);
BOOST_TEST_EQ(lcast_str, str);
}
test_conversion_from_integral_to_string<T>(L'0');
@@ -425,52 +378,52 @@ 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) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
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) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
char32_t const u32zero = u'0';
test_conversion_from_integral_to_char<T>(u32zero);
test_conversion_from_char_to_integral<T>(u32zero);
#endif
BOOST_CHECK(lexical_cast<T>("-1") == static_cast<T>(-1));
BOOST_CHECK(lexical_cast<T>("-9") == static_cast<T>(-9));
BOOST_CHECK(lexical_cast<T>(-1) == static_cast<T>(-1));
BOOST_CHECK(lexical_cast<T>(-9) == static_cast<T>(-9));
BOOST_TEST(lexical_cast<T>("-1") == static_cast<T>(-1));
BOOST_TEST(lexical_cast<T>("-9") == static_cast<T>(-9));
BOOST_TEST(lexical_cast<T>(-1) == static_cast<T>(-1));
BOOST_TEST(lexical_cast<T>(-9) == static_cast<T>(-9));
BOOST_CHECK_THROW(lexical_cast<T>("-1.0"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("-9.0"), bad_lexical_cast);
BOOST_CHECK(lexical_cast<T>(-1.0) == static_cast<T>(-1));
BOOST_CHECK(lexical_cast<T>(-9.0) == static_cast<T>(-9));
BOOST_TEST_THROWS(lexical_cast<T>("-1.0"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("-9.0"), bad_lexical_cast);
BOOST_TEST(lexical_cast<T>(-1.0) == static_cast<T>(-1));
BOOST_TEST(lexical_cast<T>(-9.0) == static_cast<T>(-9));
BOOST_CHECK(lexical_cast<T>(static_cast<T>(1)) == static_cast<T>(1));
BOOST_CHECK(lexical_cast<T>(static_cast<T>(9)) == static_cast<T>(9));
BOOST_CHECK_THROW(lexical_cast<T>(1.1f), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.1), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.1L), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.0001f), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.0001), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>(1.0001L), bad_lexical_cast);
BOOST_TEST(lexical_cast<T>(static_cast<T>(1)) == static_cast<T>(1));
BOOST_TEST(lexical_cast<T>(static_cast<T>(9)) == static_cast<T>(9));
BOOST_TEST_THROWS(lexical_cast<T>(1.1f), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(1.1), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(1.1L), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(1.0001f), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(1.0001), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(1.0001L), bad_lexical_cast);
BOOST_CHECK(lexical_cast<T>("+1") == static_cast<T>(1) );
BOOST_CHECK(lexical_cast<T>("+9") == static_cast<T>(9) );
BOOST_CHECK(lexical_cast<T>("+10") == static_cast<T>(10) );
BOOST_CHECK(lexical_cast<T>("+90") == static_cast<T>(90) );
BOOST_CHECK_THROW(lexical_cast<T>("++1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("-+9"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("--1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
BOOST_TEST(lexical_cast<T>("+1") == static_cast<T>(1) );
BOOST_TEST(lexical_cast<T>("+9") == static_cast<T>(9) );
BOOST_TEST(lexical_cast<T>("+10") == static_cast<T>(10) );
BOOST_TEST(lexical_cast<T>("+90") == static_cast<T>(90) );
BOOST_TEST_THROWS(lexical_cast<T>("++1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("-+9"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("--1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>("+-9"), bad_lexical_cast);
// 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");
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);
BOOST_TEST_THROWS(lexical_cast<T>(must_owerflow_str), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(must_owerflow_negative_str), bad_lexical_cast);
must_owerflow_str += '0';
must_owerflow_negative_str += '0';
@@ -502,14 +455,14 @@ void test_conversion_from_to_integral()
{
std::string msg("Failed to set system locale: ");
msg += ex.what();
BOOST_TEST_MESSAGE(msg);
std::cerr << msg;
}
if(grouping1 != grouping2)
test_conversion_from_to_integral_for_locale<T>();
if(grouping1.empty() && grouping2.empty())
BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested");
std::cerr << "Formatting with thousands_sep has not been tested";
}
void test_conversion_from_to_short()
@@ -579,7 +532,7 @@ void test_conversion_from_to_ulonglong()
#endif
#ifdef BOOST_HAS_INT128
#ifdef BOOST_LCAST_TEST_128
template <bool Specialized, class T>
struct test_if_specialized {
@@ -596,7 +549,7 @@ struct test_if_specialized<true, T> {
void test_conversion_from_to_int128()
{
test_if_specialized<
std::numeric_limits<boost::int128_type>::is_specialized,
std::numeric_limits<boost::int128_type>::is_specialized,
boost::int128_type
>::test();
}
@@ -604,7 +557,7 @@ void test_conversion_from_to_int128()
void test_conversion_from_to_uint128()
{
test_if_specialized<
std::numeric_limits<boost::int128_type>::is_specialized,
std::numeric_limits<boost::int128_type>::is_specialized,
boost::uint128_type
>::test();
}
@@ -614,19 +567,19 @@ 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 typename boost::detail::lcast::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_TEST_EQ(lexical_cast<unsigned_t>((uns_limits::max)()), (uns_limits::max)());
BOOST_TEST_EQ(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_TEST_EQ(lexical_cast<signed_t>((s_limits::max)()), (s_limits::max)());
BOOST_TEST_EQ(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)()));
BOOST_TEST_EQ(lexical_cast<unsigned_t>((s_limits::max)()), static_cast<unsigned_t>((s_limits::max)()));
BOOST_TEST_EQ(lexical_cast<unsigned_t>((s_limits::min)()), static_cast<unsigned_t>((s_limits::min)()));
}
void test_integral_conversions_on_min_max()
@@ -643,11 +596,62 @@ void test_integral_conversions_on_min_max()
test_integral_conversions_on_min_max_impl<__int64>();
#endif
#ifdef BOOST_HAS_INT128
#ifdef BOOST_LCAST_TEST_128
test_integral_conversions_on_min_max_impl<boost::int128_type>();
#endif
#endif
}
void test_negative_integral() {
// From https://github.com/boostorg/lexical_cast/issues/45
BOOST_TEST_EQ(boost::lexical_cast<int>("-6575543"), -6575543);
BOOST_TEST_EQ(boost::lexical_cast<int>(-6575543), -6575543);
BOOST_TEST_EQ(boost::lexical_cast<int>("+6575543"), +6575543);
BOOST_TEST_EQ(boost::lexical_cast<int>(6575543), 6575543);
if (sizeof(short) == 2 && CHAR_BIT == 8) {
BOOST_TEST_EQ(boost::lexical_cast<short>("-32768"), -32768);
BOOST_TEST_EQ(boost::lexical_cast<short>(-32768), -32768);
BOOST_TEST_EQ(boost::lexical_cast<unsigned short>("-32768"), 32768);
BOOST_TEST_EQ(boost::lexical_cast<unsigned short>(-32768), 32768);
BOOST_TEST_EQ(boost::lexical_cast<unsigned short>(65535), 65535);
BOOST_TEST_THROWS(boost::lexical_cast<unsigned short>(-65536), bad_lexical_cast);
BOOST_TEST_EQ(boost::lexical_cast<unsigned short>(-65535), 1);
BOOST_TEST_EQ(boost::lexical_cast<unsigned short>(-65534), 2);
BOOST_TEST_THROWS(boost::lexical_cast<short>(65535), bad_lexical_cast);
BOOST_TEST_THROWS(boost::lexical_cast<short>(-65536), bad_lexical_cast);
BOOST_TEST_THROWS(boost::lexical_cast<short>(-65535), bad_lexical_cast);
}
}
int main()
{
test_conversion_from_to_short();
test_conversion_from_to_ushort();
test_conversion_from_to_int();
test_conversion_from_to_uint();
test_conversion_from_to_long();
test_conversion_from_to_ulong();
test_conversion_from_to_intmax_t();
test_conversion_from_to_uintmax_t();
#ifdef LCAST_TEST_LONGLONG
test_conversion_from_to_longlong();
test_conversion_from_to_ulonglong();
#endif
#ifdef BOOST_LCAST_TEST_128
test_conversion_from_to_int128();
test_conversion_from_to_uint128();
#endif
test_integral_conversions_on_min_max();
test_negative_integral();
return boost::report_errors();
}
+238
View File
@@ -0,0 +1,238 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012-2026.
//
// 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/range/iterator_range.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
using namespace boost;
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
#define BOOST_LC_RUNU16
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(_LIBCPP_VERSION) && !defined(BOOST_MSVC)
#define BOOST_LC_RUNU32
#endif
struct class_with_user_defined_sream_operators {
int i;
operator int() const {
return i;
}
};
template <class CharT>
inline std::basic_istream<CharT>& operator >> (std::basic_istream<CharT>& istr, class_with_user_defined_sream_operators& rhs)
{
return istr >> rhs.i;
}
template <class RngT>
void do_test_iterator_range_impl(const RngT& rng)
{
BOOST_TEST_EQ(lexical_cast<int>(rng), 1);
BOOST_TEST_EQ(lexical_cast<int>(rng.begin(), rng.size()), 1);
BOOST_TEST_EQ(lexical_cast<unsigned int>(rng), 1u);
BOOST_TEST_EQ(lexical_cast<unsigned int>(rng.begin(), rng.size()), 1u);
BOOST_TEST_EQ(lexical_cast<short>(rng), 1);
BOOST_TEST_EQ(lexical_cast<short>(rng.begin(), rng.size()), 1);
BOOST_TEST_EQ(lexical_cast<unsigned short>(rng), 1u);
BOOST_TEST_EQ(lexical_cast<unsigned short>(rng.begin(), rng.size()), 1u);
BOOST_TEST_EQ(lexical_cast<long int>(rng), 1);
BOOST_TEST_EQ(lexical_cast<long int>(rng.begin(), rng.size()), 1);
BOOST_TEST_EQ(lexical_cast<unsigned long int>(rng), 1u);
BOOST_TEST_EQ(lexical_cast<unsigned long int>(rng.begin(), rng.size()), 1u);
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
BOOST_TEST_EQ(lexical_cast<float>(rng), 1.0f);
BOOST_TEST_EQ(lexical_cast<float>(rng.begin(), rng.size()), 1.0f);
BOOST_TEST_EQ(lexical_cast<double>(rng), 1.0);
BOOST_TEST_EQ(lexical_cast<double>(rng.begin(), rng.size()), 1.0);
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
BOOST_TEST_EQ(lexical_cast<long double>(rng), 1.0L);
BOOST_TEST_EQ(lexical_cast<long double>(rng.begin(), rng.size()), 1.0L);
#endif
BOOST_TEST_EQ(lexical_cast<class_with_user_defined_sream_operators>(rng), 1);
#endif
#if defined(BOOST_HAS_LONG_LONG)
BOOST_TEST_EQ(lexical_cast<boost::ulong_long_type>(rng), 1u);
BOOST_TEST_EQ(lexical_cast<boost::ulong_long_type>(rng.begin(), rng.size()), 1u);
BOOST_TEST_EQ(lexical_cast<boost::long_long_type>(rng), 1);
BOOST_TEST_EQ(lexical_cast<boost::long_long_type>(rng.begin(), rng.size()), 1);
#elif defined(BOOST_HAS_MS_INT64)
BOOST_TEST_EQ(lexical_cast<unsigned __int64>(rng), 1u);
BOOST_TEST_EQ(lexical_cast<unsigned __int64>(rng.begin(), rng.size()), 1u);
BOOST_TEST_EQ(lexical_cast<__int64>(rng), 1);
BOOST_TEST_EQ(lexical_cast<__int64>(rng.begin(), rng.size()), 1);
#endif
}
template <class CharT>
void test_it_range_using_any_chars(CharT* one, CharT* eleven)
{
typedef CharT test_char_type;
// Zero terminated
iterator_range<test_char_type*> rng1(one, one + 1);
do_test_iterator_range_impl(rng1);
iterator_range<const test_char_type*> crng1(one, one + 1);
do_test_iterator_range_impl(crng1);
// Non zero terminated
iterator_range<test_char_type*> rng2(eleven, eleven + 1);
do_test_iterator_range_impl(rng2);
iterator_range<const test_char_type*> crng2(eleven, eleven + 1);
do_test_iterator_range_impl(crng2);
}
template <class CharT>
void test_it_range_using_char(CharT* one, CharT* eleven)
{
typedef CharT test_char_type;
iterator_range<test_char_type*> rng1(one, one + 1);
BOOST_TEST_EQ(lexical_cast<std::string>(rng1), "1");
iterator_range<const test_char_type*> crng1(one, one + 1);
BOOST_TEST_EQ(lexical_cast<std::string>(crng1), "1");
iterator_range<test_char_type*> rng2(eleven, eleven + 1);
BOOST_TEST_EQ(lexical_cast<std::string>(rng2), "1");
iterator_range<const test_char_type*> crng2(eleven, eleven + 1);
BOOST_TEST_EQ(lexical_cast<std::string>(crng2), "1");
BOOST_TEST_EQ(lexical_cast<float>(rng1), 1.0f);
BOOST_TEST_EQ(lexical_cast<double>(rng1), 1.0);
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
BOOST_TEST_EQ(lexical_cast<long double>(rng1), 1.0L);
#endif
BOOST_TEST_EQ(lexical_cast<class_with_user_defined_sream_operators>(rng1), 1);
BOOST_TEST_EQ(lexical_cast<float>(crng2), 1.0f);
BOOST_TEST_EQ(lexical_cast<double>(crng2), 1.0);
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
BOOST_TEST_EQ(lexical_cast<long double>(crng2), 1.0L);
#endif
BOOST_TEST_EQ(lexical_cast<class_with_user_defined_sream_operators>(crng2), 1);
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(_LIBCPP_VERSION)
BOOST_TEST(lexical_cast<std::wstring>(rng1) == L"1");
BOOST_TEST(lexical_cast<std::wstring>(crng1) == L"1");
BOOST_TEST(lexical_cast<std::wstring>(rng2) == L"1");
BOOST_TEST(lexical_cast<std::wstring>(crng2) == L"1");
#endif
#if defined(BOOST_LC_RUNU16) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
typedef std::basic_string<char16_t> my_char16_string;
BOOST_TEST(lexical_cast<my_char16_string>(rng1) == u"1");
BOOST_TEST(lexical_cast<my_char16_string>(crng1) == u"1");
BOOST_TEST(lexical_cast<my_char16_string>(rng2) == u"1");
BOOST_TEST(lexical_cast<my_char16_string>(crng2) == u"1");
#endif
#if defined(BOOST_LC_RUNU32) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
typedef std::basic_string<char32_t> my_char32_string;
BOOST_TEST(lexical_cast<my_char32_string>(rng1) == U"1");
BOOST_TEST(lexical_cast<my_char32_string>(crng1) == U"1");
BOOST_TEST(lexical_cast<my_char32_string>(rng2) == U"1");
BOOST_TEST(lexical_cast<my_char32_string>(crng2) == U"1");
#endif
}
void test_char_iterator_ranges()
{
typedef char test_char_type;
test_char_type data1[] = "1";
test_char_type data2[] = "11";
test_it_range_using_any_chars(data1, data2);
test_it_range_using_char(data1, data2);
}
void test_unsigned_char_iterator_ranges()
{
typedef unsigned char test_char_type;
test_char_type data1[] = "1";
test_char_type data2[] = "11";
test_it_range_using_any_chars(data1, data2);
test_it_range_using_char(data1, data2);
}
void test_signed_char_iterator_ranges()
{
typedef signed char test_char_type;
test_char_type data1[] = "1";
test_char_type data2[] = "11";
test_it_range_using_any_chars(data1, data2);
test_it_range_using_char(data1, data2);
}
void test_wchar_iterator_ranges()
{
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(_LIBCPP_VERSION)
typedef wchar_t test_char_type;
test_char_type data1[] = L"1";
test_char_type data2[] = L"11";
test_it_range_using_any_chars(data1, data2);
#endif
BOOST_TEST(true);
}
void test_char16_iterator_ranges()
{
#if defined(BOOST_LC_RUNU16)
typedef char16_t test_char_type;
test_char_type data1[] = u"1";
test_char_type data2[] = u"11";
test_it_range_using_any_chars(data1, data2);
#endif
BOOST_TEST(true);
}
void test_char32_iterator_ranges()
{
#if defined(BOOST_LC_RUNU32)
typedef char32_t test_char_type;
test_char_type data1[] = U"1";
test_char_type data2[] = U"11";
test_it_range_using_any_chars(data1, data2);
#endif
BOOST_TEST(true);
}
int main()
{
test_char_iterator_ranges();
test_unsigned_char_iterator_ranges();
test_signed_char_iterator_ranges();
test_wchar_iterator_ranges();
test_char16_iterator_ranges();
test_char32_iterator_ranges();
return boost::report_errors();
}
-83
View File
@@ -1,83 +0,0 @@
// Testing boost::lexical_cast with boost::container::string.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011.
//
// 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/test/unit_test.hpp>
#include <boost/container/string.hpp>
void testing_boost_containers_basic_string();
void testing_boost_containers_string_std_string();
void testing_boost_containers_string_widening();
using namespace boost;
boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("Testing boost::lexical_cast with boost::container::string");
suite->add(BOOST_TEST_CASE(testing_boost_containers_basic_string));
suite->add(BOOST_TEST_CASE(testing_boost_containers_string_std_string));
suite->add(BOOST_TEST_CASE(testing_boost_containers_string_widening));
return suite;
}
void testing_boost_containers_basic_string()
{
BOOST_CHECK("100" == lexical_cast<boost::container::string>("100"));
BOOST_CHECK(L"100" == lexical_cast<boost::container::wstring>(L"100"));
BOOST_CHECK("100" == lexical_cast<boost::container::string>(100));
boost::container::string str("1000");
BOOST_CHECK(1000 == lexical_cast<int>(str));
}
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
void testing_boost_containers_string_std_string()
{
std::string std_str("std_str");
boost::container::string boost_str("boost_str");
BOOST_CHECK(boost::lexical_cast<std::string>(boost_str) == "boost_str");
BOOST_CHECK(boost::lexical_cast<boost::container::string>(std_str) == "std_str");
#ifndef BOOST_LCAST_NO_WCHAR_T
std::wstring std_wstr(L"std_wstr");
boost::container::wstring boost_wstr(L"boost_wstr");
BOOST_CHECK(boost::lexical_cast<std::wstring>(boost_wstr) == L"boost_wstr");
BOOST_CHECK(boost::lexical_cast<boost::container::wstring>(std_wstr) == L"std_wstr");
#endif
}
void testing_boost_containers_string_widening()
{
const char char_array[] = "Test string";
#ifndef BOOST_LCAST_NO_WCHAR_T
const wchar_t wchar_array[] = L"Test string";
BOOST_CHECK(boost::lexical_cast<boost::container::wstring>(char_array) == wchar_array);
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
const char16_t char16_array[] = u"Test string";
BOOST_CHECK(boost::lexical_cast<boost::container::basic_string<char16_t> >(char_array) == char16_array);
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
const char32_t char32_array[] = U"Test string";
BOOST_CHECK(boost::lexical_cast<boost::container::basic_string<char32_t> >(char_array) == char32_array);
#endif
}
-167
View File
@@ -1,167 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator_range.hpp>
using namespace boost;
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
template <class T>
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)
BOOST_CHECK_THROW(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<boost::long_long_type>(v), bad_lexical_cast);
#elif defined(BOOST_HAS_MS_INT64)
BOOST_CHECK_THROW(lexical_cast<unsigned __int64>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<__int64>(v), bad_lexical_cast);
#endif
}
void test_empty_iterator_range()
{
boost::iterator_range<char*> v;
do_test_on_empty_input(v);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(v), std::string());
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
boost::iterator_range<const char*> cv;
do_test_on_empty_input(cv);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(cv), std::string());
BOOST_CHECK_THROW(lexical_cast<char>(cv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(cv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(cv), bad_lexical_cast);
const boost::iterator_range<const char*> ccv;
do_test_on_empty_input(ccv);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(ccv), std::string());
BOOST_CHECK_THROW(lexical_cast<char>(ccv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(ccv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(ccv), bad_lexical_cast);
}
void test_empty_string()
{
std::string v;
do_test_on_empty_input(v);
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
#ifndef BOOST_LCAST_NO_WCHAR_T
std::wstring vw;
do_test_on_empty_input(vw);
BOOST_CHECK_THROW(lexical_cast<wchar_t>(vw), bad_lexical_cast);
#endif
// Currently, no compiler and STL library fully support char16_t and char32_t
//#ifndef BOOST_NO_CXX11_CHAR16_T
// std::basic_string<char16_t> v16w;
// do_test_on_empty_input(v16w);
// BOOST_CHECK_THROW(lexical_cast<char16_t>(v16w), bad_lexical_cast);
//#endif
//#ifndef BOOST_NO_CXX11_CHAR32_T
// std::basic_string<char32_t> v32w;
// do_test_on_empty_input(v32w);
// BOOST_CHECK_THROW(lexical_cast<char32_t>(v32w), bad_lexical_cast);
//#endif
}
struct Escape
{
Escape(const std::string& s)
: str_(s)
{}
std::string str_;
};
inline std::ostream& operator<< (std::ostream& o, const Escape& rhs)
{
return o << rhs.str_;
}
void test_empty_user_class()
{
Escape v("");
do_test_on_empty_input(v);
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
}
namespace std {
inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v)
{
std::ostream_iterator<long> it(out);
std::copy(v.begin(), v.end(), it);
assert(out);
return out;
}
}
void test_empty_vector()
{
std::vector<long> v;
do_test_on_empty_input(v);
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
}
struct my_string {
friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) {
return sout << "";
}
};
void test_empty_zero_terminated_string()
{
my_string st;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(st), std::string());;
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast. Empty input unit test");
suite->add(BOOST_TEST_CASE(&test_empty_iterator_range));
suite->add(BOOST_TEST_CASE(&test_empty_string));
suite->add(BOOST_TEST_CASE(&test_empty_user_class));
suite->add(BOOST_TEST_CASE(&test_empty_vector));
suite->add(BOOST_TEST_CASE(&test_empty_zero_terminated_string));
return suite;
}
-46
View File
@@ -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);
}
-527
View File
@@ -1,527 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/cstdint.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
void test_conversion_from_to_float();
void test_conversion_from_to_double();
void test_conversion_from_to_long_double();
using namespace boost;
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast float types unit test");
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_float));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_double));
suite->add(BOOST_TEST_CASE(&test_conversion_from_to_long_double));
return suite;
}
// Replace "-,999" with "-999".
template<class CharT>
std::basic_string<CharT> to_str_gcc_workaround(std::basic_string<CharT> str)
{
std::locale loc;
std::numpunct<CharT> const& np = BOOST_USE_FACET(std::numpunct<CharT>, loc);
std::ctype<CharT> const& ct = BOOST_USE_FACET(std::ctype<CharT>, loc);
if(np.grouping().empty())
return str;
CharT prefix[3] = { ct.widen('-'), np.thousands_sep(), CharT() };
if(str.find(prefix) != 0)
return str;
prefix[1] = CharT();
str.replace(0, 2, prefix);
return str;
}
template<class CharT, class T>
std::basic_string<CharT> to_str(T t)
{
std::basic_ostringstream<CharT> o;
o << t;
return to_str_gcc_workaround(o.str());
}
template<class T>
void test_conversion_from_to_float_for_locale()
{
std::locale current_locale;
typedef std::numpunct<char> numpunct;
numpunct const& np = BOOST_USE_FACET(numpunct, current_locale);
if ( !np.grouping().empty() )
{
BOOST_CHECK_THROW(
lexical_cast<T>( std::string("100") + np.thousands_sep() + np.thousands_sep() + "0" )
, bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( std::string("100") + np.thousands_sep() ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( np.thousands_sep() + std::string("100") ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( std::string("1") + np.thousands_sep() + np.decimal_point() + "e10" ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( std::string("1e10") + np.thousands_sep() ), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( std::string("1") + np.thousands_sep() + "e10" ), bad_lexical_cast);
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( to_str< char >(100000) ), 100000, (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( to_str< char >(10000000u) ), 10000000u, (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( to_str< char >(100) ), 100, (std::numeric_limits<T>::epsilon()) );
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( to_str< wchar_t >(100000) ), 100000, (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( to_str< wchar_t >(10000000u) ), 10000000u, (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( to_str< wchar_t >(100) ), 100, (std::numeric_limits<T>::epsilon()) );
#endif
// Exception must not be thrown, when we are using no separators at all
BOOST_CHECK_CLOSE_FRACTION( lexical_cast<T>("30000"), static_cast<T>(30000), (std::numeric_limits<T>::epsilon()) );
}
}
/*
* Converts char* [and wchar_t*] to float number type and checks, that generated
* number does not exceeds allowed epsilon.
*/
#ifndef BOOST_LCAST_NO_WCHAR_T
#define CHECK_CLOSE_ABS_DIFF(VAL,PREFIX) \
converted_val = lexical_cast<test_t>(#VAL); \
BOOST_CHECK_CLOSE_FRACTION( (VAL ## L? VAL ## L : std::numeric_limits<test_t>::epsilon()), \
(converted_val ? converted_val : std::numeric_limits<test_t>::epsilon()), \
std::numeric_limits<test_t>::epsilon() \
); \
BOOST_CHECK_EQUAL(converted_val, lexical_cast<test_t>(L## #VAL) );
#else
#define CHECK_CLOSE_ABS_DIFF(VAL,TYPE) \
converted_val = lexical_cast<test_t>(#VAL); \
BOOST_CHECK_CLOSE_FRACTION( (VAL ## L? VAL ## L : std::numeric_limits<test_t>::epsilon()), \
(converted_val ? converted_val : std::numeric_limits<test_t>::epsilon()), \
std::numeric_limits<test_t>::epsilon() \
);
#endif
template <class TestType>
void test_converion_to_float_types()
{
typedef TestType test_t;
test_t converted_val;
BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<test_t>('1'), (std::numeric_limits<test_t>::epsilon()));
BOOST_CHECK_EQUAL(0.0, lexical_cast<test_t>('0'));
unsigned char const uc_one = '1';
unsigned char const uc_zero ='0';
BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<test_t>(uc_one), (std::numeric_limits<test_t>::epsilon()));
BOOST_CHECK_EQUAL(0.0, lexical_cast<test_t>(uc_zero));
signed char const sc_one = '1';
signed char const sc_zero ='0';
BOOST_CHECK_CLOSE_FRACTION(1.0, lexical_cast<test_t>(sc_one), (std::numeric_limits<test_t>::epsilon()));
BOOST_CHECK_EQUAL(0.0, lexical_cast<test_t>(sc_zero));
BOOST_CHECK_CLOSE_FRACTION(1e34L, lexical_cast<test_t>( "10000000000000000000000000000000000"), (std::numeric_limits<test_t>::epsilon()) );
// VC failes the next test
// BOOST_CHECK_CLOSE_FRACTION(1e-35L, lexical_cast<test_t>("0.00000000000000000000000000000000001"), (std::numeric_limits<test_t>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(
0.1111111111111111111111111111111111111111111111111111111111111111111111111L
, lexical_cast<test_t>("0.1111111111111111111111111111111111111111111111111111111111111111111111111")
, (std::numeric_limits<test_t>::epsilon()) );
CHECK_CLOSE_ABS_DIFF(1,test_t);
BOOST_CHECK_EQUAL(0,lexical_cast<test_t>("0"));
CHECK_CLOSE_ABS_DIFF(-1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0, test_t);
CHECK_CLOSE_ABS_DIFF(0.0, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0,test_t);
CHECK_CLOSE_ABS_DIFF(1e1, test_t);
CHECK_CLOSE_ABS_DIFF(0e1, test_t);
CHECK_CLOSE_ABS_DIFF(-1e1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0e1,test_t);
CHECK_CLOSE_ABS_DIFF(1e-1, test_t);
CHECK_CLOSE_ABS_DIFF(0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1e-1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0e-1,test_t);
CHECK_CLOSE_ABS_DIFF(1E1, test_t);
CHECK_CLOSE_ABS_DIFF(0E1, test_t);
CHECK_CLOSE_ABS_DIFF(-1E1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0E1,test_t);
CHECK_CLOSE_ABS_DIFF(1E-1, test_t);
CHECK_CLOSE_ABS_DIFF(0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1E-1,test_t);
CHECK_CLOSE_ABS_DIFF(1.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(0.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-1.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(10.0, test_t);
CHECK_CLOSE_ABS_DIFF(00.0, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0,test_t);
CHECK_CLOSE_ABS_DIFF(10e1, test_t);
CHECK_CLOSE_ABS_DIFF(00e1, test_t);
CHECK_CLOSE_ABS_DIFF(-10e1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0e1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0e1,test_t);
CHECK_CLOSE_ABS_DIFF(10e-1, test_t);
CHECK_CLOSE_ABS_DIFF(00e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10e-1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0e-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0e-1,test_t);
CHECK_CLOSE_ABS_DIFF(10E1, test_t);
CHECK_CLOSE_ABS_DIFF(00E1, test_t);
CHECK_CLOSE_ABS_DIFF(-10E1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0E1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0E1,test_t);
CHECK_CLOSE_ABS_DIFF(10E-1, test_t);
CHECK_CLOSE_ABS_DIFF(00E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10E-1,test_t);
CHECK_CLOSE_ABS_DIFF(10.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(00.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10.0E-1, test_t);
CHECK_CLOSE_ABS_DIFF(-10101.0E-011, test_t);
CHECK_CLOSE_ABS_DIFF(-10101093, test_t);
CHECK_CLOSE_ABS_DIFF(10101093, test_t);
CHECK_CLOSE_ABS_DIFF(-.34, test_t);
CHECK_CLOSE_ABS_DIFF(.34, test_t);
CHECK_CLOSE_ABS_DIFF(.34e10, test_t);
BOOST_CHECK_THROW(lexical_cast<test_t>("-1.e"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("-1.E"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.e"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.E"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0e"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0E"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("10E"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("10e"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0e-"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0E-"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("10E-"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("10e-"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("e1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("e-1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("e-"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>(".e"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>(".11111111111111111111111111111111111111111111111111111111111111111111ee"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>(".11111111111111111111111111111111111111111111111111111111111111111111e-"), bad_lexical_cast);
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>("--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);
BOOST_CHECK_THROW(lexical_cast<test_t>("1e1e1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0e-1e-1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>(" 1.0"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("1.0 "), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>(""), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>("-"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>('\0'), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>('-'), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<test_t>('.'), bad_lexical_cast);
}
template <class T>
void test_float_typess_for_overflows()
{
typedef T test_t;
test_t minvalue = (std::numeric_limits<test_t>::min)();
std::string s_min_value = lexical_cast<std::string>(minvalue);
BOOST_CHECK_CLOSE_FRACTION(minvalue, lexical_cast<test_t>(minvalue), (std::numeric_limits<test_t>::epsilon()));
BOOST_CHECK_CLOSE_FRACTION(minvalue, lexical_cast<test_t>(s_min_value), (std::numeric_limits<test_t>::epsilon() * 2));
test_t maxvalue = (std::numeric_limits<test_t>::max)();
std::string s_max_value = lexical_cast<std::string>(maxvalue);
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...
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 )
{
BOOST_CHECK_THROW(lexical_cast<test_t>( (std::numeric_limits<double>::max)() ), bad_lexical_cast);
BOOST_CHECK(
(std::numeric_limits<double>::min)() - std::numeric_limits<test_t>::epsilon()
<= lexical_cast<test_t>( (std::numeric_limits<double>::min)() )
&& lexical_cast<test_t>( (std::numeric_limits<double>::min)() )
<= (std::numeric_limits<double>::min)() + std::numeric_limits<test_t>::epsilon()
);
}
if ( sizeof(test_t) < sizeof(long double) )
{
BOOST_CHECK_THROW(lexical_cast<test_t>( (std::numeric_limits<long double>::max)() ), bad_lexical_cast);
BOOST_CHECK(
(std::numeric_limits<long double>::min)() - std::numeric_limits<test_t>::epsilon()
<= lexical_cast<test_t>( (std::numeric_limits<long double>::min)() )
&& lexical_cast<test_t>( (std::numeric_limits<long double>::min)() )
<= (std::numeric_limits<long double>::min)() + std::numeric_limits<test_t>::epsilon()
);
}
}
#undef CHECK_CLOSE_ABS_DIFF
// Epsilon is multiplied by 2 because of two lexical conversions
#define TEST_TO_FROM_CAST_AROUND_TYPED(VAL,STRING_TYPE) \
test_value = VAL + std::numeric_limits<test_t>::epsilon() * i ; \
converted_val = lexical_cast<test_t>( lexical_cast<STRING_TYPE>(test_value) ); \
BOOST_CHECK_CLOSE_FRACTION( \
test_value, \
converted_val, \
std::numeric_limits<test_t>::epsilon() * 2 \
);
/*
* For interval [ from_mult*epsilon+VAL, to_mult*epsilon+VAL ], converts float type
* numbers to string[wstring] and then back to float type, then compares initial
* values and generated.
* Step is epsilon
*/
#ifndef BOOST_LCAST_NO_WCHAR_T
# define TEST_TO_FROM_CAST_AROUND(VAL) \
for(i=from_mult; i<=to_mult; ++i) { \
TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::string) \
TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::wstring) \
}
#else
# define TEST_TO_FROM_CAST_AROUND(VAL) \
for(i=from_mult; i<=to_mult; ++i) { \
TEST_TO_FROM_CAST_AROUND_TYPED(VAL, std::string) \
}
#endif
template <class TestType>
void test_converion_from_to_float_types()
{
typedef TestType test_t;
test_t test_value;
test_t converted_val;
int i;
int from_mult = -50;
int to_mult = 50;
TEST_TO_FROM_CAST_AROUND( 0.0 );
long double val1;
for(val1 = 1.0e-10L; val1 < 1e11; val1*=10 )
TEST_TO_FROM_CAST_AROUND( val1 );
long double val2;
for(val2 = -1.0e-10L; val2 > -1e11; val2*=10 )
TEST_TO_FROM_CAST_AROUND( val2 );
from_mult = -100;
to_mult = 0;
TEST_TO_FROM_CAST_AROUND( (std::numeric_limits<test_t>::max)() );
from_mult = 0;
to_mult = 100;
TEST_TO_FROM_CAST_AROUND( (std::numeric_limits<test_t>::min)() );
}
#undef TEST_TO_FROM_CAST_AROUND
#undef TEST_TO_FROM_CAST_AROUND_TYPED
template<class T, class CharT>
void test_conversion_from_float_to_char(CharT zero)
{
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(0)) == zero + 0);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(1)) == zero + 1);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(2)) == zero + 2);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(3)) == zero + 3);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(4)) == zero + 4);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(5)) == zero + 5);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(6)) == zero + 6);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(7)) == zero + 7);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(8)) == zero + 8);
BOOST_CHECK(lexical_cast<CharT>(static_cast<T>(9)) == zero + 9);
BOOST_CHECK_THROW(lexical_cast<CharT>(static_cast<T>(10)), bad_lexical_cast);
T t = (std::numeric_limits<T>::max)();
BOOST_CHECK_THROW(lexical_cast<CharT>(t), bad_lexical_cast);
}
template<class T, class CharT>
void test_conversion_from_char_to_float(CharT zero)
{
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 0)), static_cast<T>(0), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 1)), static_cast<T>(1), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 2)), static_cast<T>(2), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 3)), static_cast<T>(3), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 4)), static_cast<T>(4), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 5)), static_cast<T>(5), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 6)), static_cast<T>(6), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 7)), static_cast<T>(7), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 8)), static_cast<T>(8), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>( static_cast<CharT>(zero + 9)), static_cast<T>(9), (std::numeric_limits<T>::epsilon()) );
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero + 10)), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>( static_cast<CharT>(zero - 1)), bad_lexical_cast);
}
struct restore_oldloc
{
std::locale oldloc;
~restore_oldloc() { std::locale::global(oldloc); }
};
template<class T>
void test_conversion_from_to_float()
{ char const zero = '0';
signed char const szero = '0';
unsigned char const uzero = '0';
test_conversion_from_float_to_char<T>(zero);
test_conversion_from_char_to_float<T>(zero);
test_conversion_from_float_to_char<T>(szero);
test_conversion_from_char_to_float<T>(szero);
test_conversion_from_float_to_char<T>(uzero);
test_conversion_from_char_to_float<T>(uzero);
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
wchar_t const wzero = L'0';
test_conversion_from_float_to_char<T>(wzero);
test_conversion_from_char_to_float<T>(wzero);
#endif
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>("+1"), 1, std::numeric_limits<T>::epsilon());
BOOST_CHECK_CLOSE_FRACTION(lexical_cast<T>("+9"), 9, std::numeric_limits<T>::epsilon());
BOOST_CHECK_THROW(lexical_cast<T>("++1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("-+9"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("--1"), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
test_converion_to_float_types<T>();
test_float_typess_for_overflows<T>();
test_converion_from_to_float_types<T>();
typedef std::numpunct<char> numpunct;
restore_oldloc guard;
std::locale const& oldloc = guard.oldloc;
std::string grouping1 = BOOST_USE_FACET(numpunct, oldloc).grouping();
std::string grouping2(grouping1);
test_conversion_from_to_float_for_locale<T>();
try
{
std::locale newloc("");
std::locale::global(newloc);
grouping2 = BOOST_USE_FACET(numpunct, newloc).grouping();
}
catch(std::exception const& ex)
{
std::string msg("Failed to set system locale: ");
msg += ex.what();
BOOST_TEST_MESSAGE(msg);
}
if(grouping1 != grouping2)
test_conversion_from_to_float_for_locale<T>();
if(grouping1.empty() && grouping2.empty())
BOOST_TEST_MESSAGE("Formatting with thousands_sep has not been tested");
}
void test_conversion_from_to_float()
{
test_conversion_from_to_float<float>();
}
void test_conversion_from_to_double()
{
test_conversion_from_to_float<double>();
}
void test_conversion_from_to_long_double()
{
// We do not run tests on compilers with bugs
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
test_conversion_from_to_float<long double>();
#endif
BOOST_CHECK(true);
}
-205
View File
@@ -1,205 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/math/special_functions/sign.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
using namespace boost;
template <class T>
bool is_pos_inf(T value)
{
return (boost::math::isinf)(value) && !(boost::math::signbit)(value);
}
template <class T>
bool is_neg_inf(T value)
{
return (boost::math::isinf)(value) && (boost::math::signbit)(value);
}
template <class T>
bool is_pos_nan(T value)
{
return (boost::math::isnan)(value) && !(boost::math::signbit)(value);
}
template <class T>
bool is_neg_nan(T value)
{
/* There is some strange behaviour on Itanium platform with -nan nuber for long double.
* It is a IA64 feature, or it is a boost::math feature, not a lexical_cast bug */
#if defined(__ia64__) || defined(_M_IA64)
return (boost::math::isnan)(value)
&& ( boost::is_same<T, long double >::value || (boost::math::signbit)(value) );
#else
return (boost::math::isnan)(value) && (boost::math::signbit)(value);
#endif
}
template <class T>
void test_inf_nan_templated()
{
typedef T test_t;
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("inf") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("INF") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>("-inf") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>("-INF") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("+inf") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("+INF") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("infinity") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("INFINITY") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>("-infinity") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>("-INFINITY") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("+infinity") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("+INFINITY") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("iNfiNity") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>("INfinity") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>("-inFINITY") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>("-INFINITY") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("nan") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("NAN") ) );
BOOST_CHECK( is_neg_nan( lexical_cast<test_t>("-nan") ) );
BOOST_CHECK( is_neg_nan( lexical_cast<test_t>("-NAN") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("+nan") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("+NAN") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("nAn") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("NaN") ) );
BOOST_CHECK( is_neg_nan( lexical_cast<test_t>("-nAn") ) );
BOOST_CHECK( is_neg_nan( lexical_cast<test_t>("-NaN") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("+Nan") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("+nAN") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("nan()") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>("NAN(some string)") ) );
BOOST_CHECK_THROW( lexical_cast<test_t>("NAN(some string"), bad_lexical_cast );
BOOST_CHECK(lexical_cast<std::string>( (boost::math::changesign)(std::numeric_limits<test_t >::infinity()))
== "-inf" );
BOOST_CHECK(lexical_cast<std::string>( std::numeric_limits<test_t >::infinity()) == "inf" );
BOOST_CHECK(lexical_cast<std::string>( std::numeric_limits<test_t >::quiet_NaN()) == "nan" );
#if !defined(__ia64__) && !defined(_M_IA64)
BOOST_CHECK(lexical_cast<std::string>(
(boost::math::changesign)(std::numeric_limits<test_t >::quiet_NaN()))
== "-nan" );
#endif
#ifndef BOOST_LCAST_NO_WCHAR_T
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"inf") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"INF") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>(L"-inf") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>(L"-INF") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"+inf") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"+INF") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"infinity") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"INFINITY") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>(L"-infinity") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>(L"-INFINITY") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"+infinity") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"+INFINITY") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>(L"-infINIty") ) );
BOOST_CHECK( is_neg_inf( lexical_cast<test_t>(L"-INFiniTY") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"+inFINIty") ) );
BOOST_CHECK( is_pos_inf( lexical_cast<test_t>(L"+INfinITY") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>(L"nan") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>(L"NAN") ) );
BOOST_CHECK( is_neg_nan( lexical_cast<test_t>(L"-nan") ) );
BOOST_CHECK( is_neg_nan( lexical_cast<test_t>(L"-NAN") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>(L"+nan") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>(L"+NAN") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>(L"nan()") ) );
BOOST_CHECK( is_pos_nan( lexical_cast<test_t>(L"NAN(some string)") ) );
BOOST_CHECK_THROW( lexical_cast<test_t>(L"NAN(some string"), bad_lexical_cast );
BOOST_CHECK(lexical_cast<std::wstring>( (boost::math::changesign)(std::numeric_limits<test_t >::infinity()))
== L"-inf" );
BOOST_CHECK(lexical_cast<std::wstring>( std::numeric_limits<test_t >::infinity()) == L"inf" );
BOOST_CHECK(lexical_cast<std::wstring>( std::numeric_limits<test_t >::quiet_NaN()) == L"nan" );
#if !defined(__ia64__) && !defined(_M_IA64)
BOOST_CHECK(lexical_cast<std::wstring>(
(boost::math::changesign)(std::numeric_limits<test_t >::quiet_NaN()))
== L"-nan" );
#endif
#endif
}
void test_inf_nan_float()
{
test_inf_nan_templated<float >();
}
void test_inf_nan_double()
{
test_inf_nan_templated<double >();
}
void test_inf_nan_long_double()
{
// We do not run tests on compilers with bugs
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
test_inf_nan_templated<long double >();
#endif
BOOST_CHECK(true);
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast inf anf nan parsing unit test");
suite->add(BOOST_TEST_CASE(&test_inf_nan_float));
suite->add(BOOST_TEST_CASE(&test_inf_nan_double));
suite->add(BOOST_TEST_CASE(&test_inf_nan_long_double));
return suite;
}
-245
View File
@@ -1,245 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator_range.hpp>
using namespace boost;
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#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;
operator int() const {
return i;
}
};
template <class CharT>
inline std::basic_istream<CharT>& operator >> (std::basic_istream<CharT>& istr, class_with_user_defined_sream_operators& rhs)
{
return istr >> rhs.i;
}
template <class RngT>
void do_test_iterator_range_impl(const RngT& rng)
{
BOOST_CHECK_EQUAL(lexical_cast<int>(rng), 1);
BOOST_CHECK_EQUAL(lexical_cast<int>(rng.begin(), rng.size()), 1);
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(rng), 1u);
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(rng.begin(), rng.size()), 1u);
BOOST_CHECK_EQUAL(lexical_cast<short>(rng), 1);
BOOST_CHECK_EQUAL(lexical_cast<short>(rng.begin(), rng.size()), 1);
BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(rng), 1u);
BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(rng.begin(), rng.size()), 1u);
BOOST_CHECK_EQUAL(lexical_cast<long int>(rng), 1);
BOOST_CHECK_EQUAL(lexical_cast<long int>(rng.begin(), rng.size()), 1);
BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng), 1u);
BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng.begin(), rng.size()), 1u);
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
BOOST_CHECK_EQUAL(lexical_cast<float>(rng), 1.0f);
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)
BOOST_CHECK_EQUAL(lexical_cast<boost::ulong_long_type>(rng), 1u);
BOOST_CHECK_EQUAL(lexical_cast<boost::ulong_long_type>(rng.begin(), rng.size()), 1u);
BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng), 1);
BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng.begin(), rng.size()), 1);
#elif defined(BOOST_HAS_MS_INT64)
BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng), 1u);
BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng.begin(), rng.size()), 1u);
BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng), 1);
BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng.begin(), rng.size()), 1);
#endif
}
template <class CharT>
void test_it_range_using_any_chars(CharT* one, CharT* eleven)
{
typedef CharT test_char_type;
// Zero terminated
iterator_range<test_char_type*> rng1(one, one + 1);
do_test_iterator_range_impl(rng1);
iterator_range<const test_char_type*> crng1(one, one + 1);
do_test_iterator_range_impl(crng1);
// Non zero terminated
iterator_range<test_char_type*> rng2(eleven, eleven + 1);
do_test_iterator_range_impl(rng2);
iterator_range<const test_char_type*> crng2(eleven, eleven + 1);
do_test_iterator_range_impl(crng2);
}
template <class CharT>
void test_it_range_using_char(CharT* one, CharT* eleven)
{
typedef CharT test_char_type;
iterator_range<test_char_type*> rng1(one, one + 1);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(rng1), "1");
iterator_range<const test_char_type*> crng1(one, one + 1);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(crng1), "1");
iterator_range<test_char_type*> rng2(eleven, eleven + 1);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(rng2), "1");
iterator_range<const test_char_type*> crng2(eleven, eleven + 1);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(crng2), "1");
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
BOOST_CHECK(lexical_cast<std::wstring>(rng1) == L"1");
BOOST_CHECK(lexical_cast<std::wstring>(crng1) == L"1");
BOOST_CHECK(lexical_cast<std::wstring>(rng2) == L"1");
BOOST_CHECK(lexical_cast<std::wstring>(crng2) == L"1");
#endif
#if defined(BOOST_LC_RUNU16) && 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");
BOOST_CHECK(lexical_cast<my_char16_string>(rng2) == u"1");
BOOST_CHECK(lexical_cast<my_char16_string>(crng2) == u"1");
#endif
#if defined(BOOST_LC_RUNU32) && 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");
BOOST_CHECK(lexical_cast<my_char32_string>(rng2) == U"1");
BOOST_CHECK(lexical_cast<my_char32_string>(crng2) == U"1");
#endif
}
void test_char_iterator_ranges()
{
typedef char test_char_type;
test_char_type data1[] = "1";
test_char_type data2[] = "11";
test_it_range_using_any_chars(data1, data2);
test_it_range_using_char(data1, data2);
}
void test_unsigned_char_iterator_ranges()
{
typedef unsigned char test_char_type;
test_char_type data1[] = "1";
test_char_type data2[] = "11";
test_it_range_using_any_chars(data1, data2);
test_it_range_using_char(data1, data2);
}
void test_signed_char_iterator_ranges()
{
typedef signed char test_char_type;
test_char_type data1[] = "1";
test_char_type data2[] = "11";
test_it_range_using_any_chars(data1, data2);
test_it_range_using_char(data1, data2);
}
void test_wchar_iterator_ranges()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
typedef wchar_t test_char_type;
test_char_type data1[] = L"1";
test_char_type data2[] = L"11";
test_it_range_using_any_chars(data1, data2);
#endif
BOOST_CHECK(true);
}
void test_char16_iterator_ranges()
{
#if defined(BOOST_LC_RUNU16)
typedef char16_t test_char_type;
test_char_type data1[] = u"1";
test_char_type data2[] = u"11";
test_it_range_using_any_chars(data1, data2);
#endif
BOOST_CHECK(true);
}
void test_char32_iterator_ranges()
{
#if defined(BOOST_LC_RUNU32)
typedef char32_t test_char_type;
test_char_type data1[] = U"1";
test_char_type data2[] = U"11";
test_it_range_using_any_chars(data1, data2);
#endif
BOOST_CHECK(true);
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite = BOOST_TEST_SUITE("lexical_cast. Testing conversions using iterator_range<>");
suite->add(BOOST_TEST_CASE(&test_char_iterator_ranges));
suite->add(BOOST_TEST_CASE(&test_unsigned_char_iterator_ranges));
suite->add(BOOST_TEST_CASE(&test_signed_char_iterator_ranges));
suite->add(BOOST_TEST_CASE(&test_wchar_iterator_ranges));
suite->add(BOOST_TEST_CASE(&test_char16_iterator_ranges));
suite->add(BOOST_TEST_CASE(&test_char32_iterator_ranges));
return suite;
}
-95
View File
@@ -1,95 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator_range.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#error "This test must be compiled with -DBOOST_NO_EXCEPTIONS"
#endif
bool g_was_exception = false;
namespace boost {
void throw_exception(std::exception const & ) {
g_was_exception = true;
}
}
using namespace boost;
struct Escape
{
Escape(){}
Escape(const std::string& s)
: str_(s)
{}
std::string str_;
};
inline std::ostream& operator<< (std::ostream& o, const Escape& rhs)
{
return o << rhs.str_;
}
inline std::istream& operator>> (std::istream& i, Escape& rhs)
{
return i >> rhs.str_;
}
void test_exceptions_off()
{
Escape v("");
g_was_exception = false;
lexical_cast<char>(v);
BOOST_CHECK(g_was_exception);
g_was_exception = false;
lexical_cast<unsigned char>(v);
BOOST_CHECK(g_was_exception);
v = lexical_cast<Escape>(100);
BOOST_CHECK_EQUAL(lexical_cast<int>(v), 100);
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(v), 100u);
v = lexical_cast<Escape>(0.0);
BOOST_CHECK_EQUAL(lexical_cast<double>(v), 0.0);
BOOST_CHECK_EQUAL(lexical_cast<short>(100), 100);
BOOST_CHECK_EQUAL(lexical_cast<float>(0.0), 0.0);
g_was_exception = false;
lexical_cast<short>(700000);
BOOST_CHECK(g_was_exception);
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast. Testing with BOOST_NO_EXCEPTIONS");
suite->add(BOOST_TEST_CASE(&test_exceptions_off));
return suite;
}
-168
View File
@@ -1,168 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/range/iterator_range.hpp>
using namespace boost;
// Testing compilation and some basic usage with BOOST_NO_STD_LOCALE
// Tests are mainly copyied from lexical_cast_empty_input_test.cpp (something
// new added to test_empty_3)
#ifndef BOOST_NO_STD_LOCALE
#error "This test must be compiled with -DBOOST_NO_STD_LOCALE"
#endif
template <class T>
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)
BOOST_CHECK_THROW(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<boost::long_long_type>(v), bad_lexical_cast);
#elif defined(BOOST_HAS_MS_INT64)
BOOST_CHECK_THROW(lexical_cast<unsigned __int64>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<__int64>(v), bad_lexical_cast);
#endif
}
void test_empty_1()
{
boost::iterator_range<char*> v;
do_test_on_empty_input(v);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(v), std::string());
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
boost::iterator_range<const char*> cv;
do_test_on_empty_input(cv);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(cv), std::string());
BOOST_CHECK_THROW(lexical_cast<char>(cv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(cv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(cv), bad_lexical_cast);
const boost::iterator_range<const char*> ccv;
do_test_on_empty_input(ccv);
BOOST_CHECK_EQUAL(lexical_cast<std::string>(ccv), std::string());
BOOST_CHECK_THROW(lexical_cast<char>(ccv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(ccv), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(ccv), bad_lexical_cast);
}
void test_empty_2()
{
std::string v;
do_test_on_empty_input(v);
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
}
struct Escape
{
Escape(){}
Escape(const std::string& s)
: str_(s)
{}
std::string str_;
};
inline std::ostream& operator<< (std::ostream& o, const Escape& rhs)
{
return o << rhs.str_;
}
inline std::istream& operator>> (std::istream& i, Escape& rhs)
{
return i >> rhs.str_;
}
void test_empty_3()
{
Escape v("");
do_test_on_empty_input(v);
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
v = lexical_cast<Escape>(100);
BOOST_CHECK_EQUAL(lexical_cast<int>(v), 100);
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(v), 100u);
v = lexical_cast<Escape>(0.0);
BOOST_CHECK_EQUAL(lexical_cast<double>(v), 0.0);
}
namespace std {
inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v)
{
std::ostream_iterator<long> it(out);
std::copy(v.begin(), v.end(), it);
assert(out);
return out;
}
}
void test_empty_4()
{
std::vector<long> v;
do_test_on_empty_input(v);
BOOST_CHECK_THROW(lexical_cast<char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_CHECK_THROW(lexical_cast<signed char>(v), bad_lexical_cast);
}
struct my_string {
friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) {
return sout << "";
}
};
void test_empty_5()
{
my_string st;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(st), std::string());;
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast. Testing with BOOST_NO_STD_LOCALE");
suite->add(BOOST_TEST_CASE(&test_empty_1));
suite->add(BOOST_TEST_CASE(&test_empty_2));
suite->add(BOOST_TEST_CASE(&test_empty_3));
suite->add(BOOST_TEST_CASE(&test_empty_4));
suite->add(BOOST_TEST_CASE(&test_empty_5));
return suite;
}
+177
View File
@@ -0,0 +1,177 @@
// Copyright Kevlin Henney, 2000-2005.
// Copyright Alexander Nasonov, 2006-2010.
// Copyright Antony Polukhin, 2011-2026.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// what: lexical_cast custom keyword cast
// who: contributed by Kevlin Henney,
// enhanced with contributions from Terje Slettebo,
// with additional fixes and suggestions from Gennaro Prota,
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
#ifndef BOOST_LEXICAL_CAST_LEXICAL_CAST_OLD_HPP
#define BOOST_LEXICAL_CAST_LEXICAL_CAST_OLD_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#include <climits>
#include <cstddef>
#include <string>
#include <cstring>
#include <cstdio>
#include <type_traits>
#include <boost/limits.hpp>
#include <boost/config/workaround.hpp>
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif
#if defined(BOOST_USE_MODULES)
#undef BOOST_USE_MODULES
#endif
#include <boost/lexical_cast/detail/lcast_precision.hpp>
#include <boost/lexical_cast/bad_lexical_cast.hpp>
#include <boost/lexical_cast/detail/widest_char.hpp>
namespace boost {
namespace detail
{
// selectors for choosing stream character type
template<typename Type>
struct stream_char
{
typedef char type;
};
#ifndef BOOST_LCAST_NO_WCHAR_T
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
template<>
struct stream_char<wchar_t>
{
typedef wchar_t type;
};
#endif
template<>
struct stream_char<wchar_t *>
{
typedef wchar_t type;
};
template<>
struct stream_char<const wchar_t *>
{
typedef wchar_t type;
};
template<>
struct stream_char<std::wstring>
{
typedef wchar_t type;
};
#endif
// stream wrapper for handling lexical conversions
template<typename Target, typename Source, typename Traits>
class lexical_stream
{
private:
typedef typename widest_char<
typename stream_char<Target>::type,
typename stream_char<Source>::type>::type char_type;
typedef Traits traits_type;
public:
lexical_stream(char_type* = 0, char_type* = 0)
{
stream.unsetf(std::ios::skipws);
lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
}
~lexical_stream()
{
#if defined(BOOST_NO_STRINGSTREAM)
stream.freeze(false);
#endif
}
bool operator<<(const Source &input)
{
return !(stream << input).fail();
}
template<typename InputStreamable>
bool operator>>(InputStreamable &output)
{
return !std::is_pointer<InputStreamable>::value &&
stream >> output &&
stream.get() == traits_type::eof();
}
bool operator>>(std::string &output)
{
#if defined(BOOST_NO_STRINGSTREAM)
stream << '\0';
#endif
stream.str().swap(output);
return true;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
bool operator>>(std::wstring &output)
{
stream.str().swap(output);
return true;
}
#endif
private:
#if defined(BOOST_NO_STRINGSTREAM)
std::strstream stream;
#elif defined(BOOST_NO_STD_LOCALE)
std::stringstream stream;
#else
std::basic_stringstream<char_type,traits_type> stream;
#endif
};
}
// call-by-value fallback version (deprecated)
template<typename Target, typename Source>
Target lexical_cast(Source arg)
{
typedef typename detail::widest_char<
typename detail::stream_char<Target>::type
, typename detail::stream_char<Source>::type
>::type char_type;
typedef std::char_traits<char_type> traits;
detail::lexical_stream<Target, Source, traits> interpreter;
Target result{};
if(!(interpreter << arg && interpreter >> result))
boost::conversion::detail::throw_bad_cast<Source, Target>();
return result;
}
} // namespace boost
#undef BOOST_LCAST_NO_WCHAR_T
#endif // BOOST_LEXICAL_CAST_LEXICAL_CAST_OLD_HPP
-158
View File
@@ -1,158 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012.
//
// 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/config.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
template <class T>
static void test_optimized_types_to_string_const()
{
namespace de = boost::detail;
typedef de::lexical_cast_stream_traits<T, std::string> trait_1;
BOOST_CHECK(!trait_1::is_source_input_not_optimized_t::value);
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_1::src_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_1::target_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_1::char_type, char>::value));
BOOST_CHECK(!trait_1::is_string_widening_required_t::value);
BOOST_CHECK(!trait_1::is_source_input_not_optimized_t::value);
typedef de::lexical_cast_stream_traits<const T, std::string> trait_2;
BOOST_CHECK(!trait_2::is_source_input_not_optimized_t::value);
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_2::src_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_2::target_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_2::char_type, char>::value));
BOOST_CHECK(!trait_2::is_string_widening_required_t::value);
BOOST_CHECK(!trait_2::is_source_input_not_optimized_t::value);
typedef de::lexical_cast_stream_traits<T, std::wstring> trait_3;
BOOST_CHECK(!trait_3::is_source_input_not_optimized_t::value);
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_3::src_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_3::target_char_t, wchar_t>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_3::char_type, wchar_t>::value));
BOOST_CHECK((boost::detail::is_character<BOOST_DEDUCED_TYPENAME trait_3::no_cv_src>::value != trait_3::is_string_widening_required_t::value));
BOOST_CHECK(!trait_3::is_source_input_not_optimized_t::value);
}
template <class T>
static void test_optimized_types_to_string()
{
test_optimized_types_to_string_const<T>();
namespace de = boost::detail;
typedef de::lexical_cast_stream_traits<std::string, T> trait_4;
BOOST_CHECK(!trait_4::is_source_input_not_optimized_t::value);
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_4::src_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_4::target_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_4::char_type, char>::value));
BOOST_CHECK(!trait_4::is_string_widening_required_t::value);
BOOST_CHECK(!trait_4::is_source_input_not_optimized_t::value);
typedef de::lexical_cast_stream_traits<const std::string, T> trait_5;
BOOST_CHECK(!trait_5::is_source_input_not_optimized_t::value);
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_5::src_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_5::target_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_5::char_type, char>::value));
BOOST_CHECK(!trait_5::is_string_widening_required_t::value);
BOOST_CHECK(!trait_5::is_source_input_not_optimized_t::value);
typedef de::lexical_cast_stream_traits<const std::wstring, T> trait_6;
BOOST_CHECK(!trait_6::is_source_input_not_optimized_t::value);
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_6::src_char_t, wchar_t>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_6::target_char_t, char>::value));
BOOST_CHECK((boost::is_same<BOOST_DEDUCED_TYPENAME trait_6::char_type, wchar_t>::value));
BOOST_CHECK(!trait_6::is_string_widening_required_t::value);
}
void test_metafunctions()
{
test_optimized_types_to_string<bool>();
test_optimized_types_to_string<char>();
test_optimized_types_to_string<unsigned char>();
test_optimized_types_to_string<signed char>();
test_optimized_types_to_string<short>();
test_optimized_types_to_string<unsigned short>();
test_optimized_types_to_string<int>();
test_optimized_types_to_string<unsigned int>();
test_optimized_types_to_string<long>();
test_optimized_types_to_string<unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
test_optimized_types_to_string<boost::ulong_long_type>();
test_optimized_types_to_string<boost::long_long_type>();
#elif defined(BOOST_HAS_MS_INT64)
test_optimized_types_to_string<unsigned __int64>();
test_optimized_types_to_string<__int64>();
#endif
#if !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
test_optimized_types_to_string<float>();
#endif
test_optimized_types_to_string<std::string>();
test_optimized_types_to_string<char*>();
//test_optimized_types_to_string<char[5]>();
//test_optimized_types_to_string<char[1]>();
test_optimized_types_to_string<unsigned char*>();
//test_optimized_types_to_string<unsigned char[5]>();
//test_optimized_types_to_string<unsigned char[1]>();
test_optimized_types_to_string<signed char*>();
//test_optimized_types_to_string<signed char[5]>();
//test_optimized_types_to_string<signed char[1]>();
test_optimized_types_to_string<boost::array<char, 1> >();
test_optimized_types_to_string<boost::array<char, 5> >();
test_optimized_types_to_string<boost::array<unsigned char, 1> >();
test_optimized_types_to_string<boost::array<unsigned char, 5> >();
test_optimized_types_to_string<boost::array<signed char, 1> >();
test_optimized_types_to_string<boost::array<signed char, 5> >();
test_optimized_types_to_string<boost::iterator_range<char*> >();
test_optimized_types_to_string<boost::iterator_range<unsigned char*> >();
test_optimized_types_to_string<boost::iterator_range<signed char*> >();
test_optimized_types_to_string_const<boost::array<const char, 1> >();
test_optimized_types_to_string_const<boost::array<const char, 5> >();
test_optimized_types_to_string_const<boost::array<const unsigned char, 1> >();
test_optimized_types_to_string_const<boost::array<const unsigned char, 5> >();
test_optimized_types_to_string_const<boost::array<const signed char, 1> >();
test_optimized_types_to_string_const<boost::array<const signed char, 5> >();
test_optimized_types_to_string_const<boost::iterator_range<const char*> >();
test_optimized_types_to_string_const<boost::iterator_range<const unsigned char*> >();
test_optimized_types_to_string_const<boost::iterator_range<const signed char*> >();
#ifndef BOOST_NO_CXX11_HDR_ARRAY
test_optimized_types_to_string<std::array<char, 1> >();
test_optimized_types_to_string<std::array<char, 5> >();
test_optimized_types_to_string<std::array<unsigned char, 1> >();
test_optimized_types_to_string<std::array<unsigned char, 5> >();
test_optimized_types_to_string<std::array<signed char, 1> >();
test_optimized_types_to_string<std::array<signed char, 5> >();
test_optimized_types_to_string_const<std::array<const char, 1> >();
test_optimized_types_to_string_const<std::array<const char, 5> >();
test_optimized_types_to_string_const<std::array<const unsigned char, 1> >();
test_optimized_types_to_string_const<std::array<const unsigned char, 5> >();
test_optimized_types_to_string_const<std::array<const signed char, 1> >();
test_optimized_types_to_string_const<std::array<const signed char, 5> >();
#endif
}
boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
{
boost::unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast traits tests");
suite->add(BOOST_TEST_CASE(&test_metafunctions));
return suite;
}
+601
View File
@@ -0,0 +1,601 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Terje Sletteb and Kevlin Henney, 2005.
// Copyright Alexander Nasonov, 2006.
// Copyright Antony Polukhin, 2011-2026.
//
// 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).
//
// Note: The unit test no longer compile on MSVC 6, but lexical_cast itself works for it.
//
// We need this #define before any #includes: otherwise msvc will emit warnings
// deep within std::string, resulting from our (perfectly legal) use of basic_string
// with a custom traits class:
//
#define _SCL_SECURE_NO_WARNINGS
#include <boost/cstdint.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/type_traits/integral_promotion.hpp>
#include <string>
#include <vector>
#include <algorithm> // std::transform
#include <memory>
#include <boost/lexical_cast.hpp>
#if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) \
&& !(defined(BOOST_MSVC) && BOOST_MSVC < 1300)
#define LCAST_TEST_LONGLONG
#endif
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
#endif
#ifndef BOOST_TEST_CLOSE_FRACTION
// Naiive, but works for tests in this file
#define BOOST_TEST_CLOSE_FRACTION(x, y, eps) BOOST_TEST(x - y + eps <= eps * 2)
#endif
template<class CharT>
struct my_traits : std::char_traits<CharT>
{
};
template<class CharT>
struct my_allocator : std::allocator<CharT>
{
typedef std::allocator<CharT> base_t;
my_allocator(){}
template <class U> my_allocator(const my_allocator<U>& v) : base_t(v) {}
template <class U> struct rebind { typedef my_allocator<U> other; };
};
using namespace boost;
void test_conversion_to_char()
{
BOOST_TEST_EQ('A', lexical_cast<char>('A'));
BOOST_TEST_EQ(' ', lexical_cast<char>(' '));
BOOST_TEST_EQ('1', lexical_cast<char>(1));
BOOST_TEST_EQ('0', lexical_cast<char>(0));
BOOST_TEST_THROWS(lexical_cast<char>(123), bad_lexical_cast);
BOOST_TEST_EQ('1', lexical_cast<char>(1.0));
BOOST_TEST_EQ('1', lexical_cast<char>(true));
BOOST_TEST_EQ('0', lexical_cast<char>(false));
BOOST_TEST_EQ('A', lexical_cast<char>("A"));
BOOST_TEST_EQ(' ', lexical_cast<char>(" "));
BOOST_TEST_THROWS(lexical_cast<char>(""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<char>("Test"), bad_lexical_cast);
BOOST_TEST_EQ('A', lexical_cast<char>(std::string("A")));
BOOST_TEST_EQ(' ', lexical_cast<char>(std::string(" ")));
BOOST_TEST_THROWS(
lexical_cast<char>(std::string("")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<char>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_to_int()
{
BOOST_TEST_EQ(1, lexical_cast<int>('1'));
BOOST_TEST_EQ(0, lexical_cast<int>('0'));
BOOST_TEST_THROWS(lexical_cast<int>('A'), bad_lexical_cast);
BOOST_TEST_EQ(1, lexical_cast<int>(1));
BOOST_TEST_EQ(1, lexical_cast<int>(1.0));
BOOST_TEST_EQ(
(std::numeric_limits<int>::max)(),
lexical_cast<int>((std::numeric_limits<int>::max)()));
BOOST_TEST_EQ(
(std::numeric_limits<int>::min)(),
lexical_cast<int>((std::numeric_limits<int>::min)()));
BOOST_TEST_THROWS(lexical_cast<int>(1.23), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<int>(1e20), bad_lexical_cast);
BOOST_TEST_EQ(1, lexical_cast<int>(true));
BOOST_TEST_EQ(0, lexical_cast<int>(false));
BOOST_TEST_EQ(123, lexical_cast<int>("123"));
BOOST_TEST_THROWS(
lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<int>(""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<int>("Test"), bad_lexical_cast);
BOOST_TEST_EQ(123, lexical_cast<int>("123"));
BOOST_TEST_EQ(123, lexical_cast<int>(std::string("123")));
BOOST_TEST_THROWS(
lexical_cast<int>(std::string(" 123")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<int>(std::string("")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<int>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_with_nonconst_char()
{
std::vector<char> buffer;
buffer.push_back('1');
buffer.push_back('\0');
BOOST_TEST_EQ(boost::lexical_cast<int>(&buffer[0]), 1);
std::vector<unsigned char> buffer2;
buffer2.push_back('1');
buffer2.push_back('\0');
BOOST_TEST_EQ(boost::lexical_cast<int>(&buffer2[0]), 1);
std::vector<unsigned char> buffer3;
buffer3.push_back('1');
buffer3.push_back('\0');
BOOST_TEST_EQ(boost::lexical_cast<int>(&buffer3[0]), 1);
#ifndef BOOST_LCAST_NO_WCHAR_T
std::vector<wchar_t> buffer4;
buffer4.push_back(L'1');
buffer4.push_back(L'\0');
BOOST_TEST_EQ(boost::lexical_cast<int>(&buffer4[0]), 1);
#endif
}
void test_conversion_to_double()
{
BOOST_TEST_CLOSE_FRACTION(1.0, lexical_cast<double>('1'), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_THROWS(lexical_cast<double>('A'), bad_lexical_cast);
BOOST_TEST_CLOSE_FRACTION(1.0, lexical_cast<double>(1), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_CLOSE_FRACTION(1.23, lexical_cast<double>(1.23), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_CLOSE_FRACTION(1.234567890, lexical_cast<double>(1.234567890), std::numeric_limits<double>::epsilon());
BOOST_TEST_CLOSE_FRACTION(1.234567890, lexical_cast<double>("1.234567890"), std::numeric_limits<double>::epsilon());
BOOST_TEST_CLOSE_FRACTION(1.0, lexical_cast<double>(true), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_CLOSE_FRACTION(0.0, lexical_cast<double>(false), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_CLOSE_FRACTION(1.23, lexical_cast<double>("1.23"), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_THROWS(lexical_cast<double>(""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<double>("Test"), bad_lexical_cast);
BOOST_TEST_CLOSE_FRACTION(1.23, lexical_cast<double>(std::string("1.23")), (std::numeric_limits<double>::epsilon()));
BOOST_TEST_THROWS(
lexical_cast<double>(std::string("")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<double>(std::string("Test")), bad_lexical_cast);
}
void test_conversion_to_bool()
{
BOOST_TEST_EQ(true, lexical_cast<bool>('1'));
BOOST_TEST_EQ(false, lexical_cast<bool>('0'));
BOOST_TEST_THROWS(lexical_cast<bool>('A'), bad_lexical_cast);
BOOST_TEST_EQ(true, lexical_cast<bool>(1));
BOOST_TEST_EQ(false, lexical_cast<bool>(0));
BOOST_TEST_THROWS(lexical_cast<bool>(123), bad_lexical_cast);
BOOST_TEST_EQ(true, lexical_cast<bool>(1.0));
BOOST_TEST_THROWS(lexical_cast<bool>(-123), bad_lexical_cast);
BOOST_TEST_EQ(false, lexical_cast<bool>(0.0));
BOOST_TEST_THROWS(lexical_cast<bool>(1234), bad_lexical_cast);
#if !defined(_CRAYC)
// Looks like a bug in CRAY compiler (throws bad_lexical_cast)
// TODO: localize the bug and report it to developers.
BOOST_TEST_EQ(true, lexical_cast<bool>(true));
BOOST_TEST_EQ(false, lexical_cast<bool>(false));
#endif
BOOST_TEST_EQ(true, lexical_cast<bool>("1"));
BOOST_TEST_EQ(false, lexical_cast<bool>("0"));
BOOST_TEST_THROWS(lexical_cast<bool>(""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("Test"), bad_lexical_cast);
BOOST_TEST_EQ(true, lexical_cast<bool>("1"));
BOOST_TEST_EQ(false, lexical_cast<bool>("0"));
BOOST_TEST_EQ(true, lexical_cast<bool>(std::string("1")));
BOOST_TEST_EQ(false, lexical_cast<bool>(std::string("0")));
BOOST_TEST_THROWS(lexical_cast<bool>(1.0001L), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>(2), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>(2u), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>(-1), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>(-2), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<bool>(std::string("")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<bool>(std::string("Test")), bad_lexical_cast);
BOOST_TEST(lexical_cast<bool>("+1") == true);
BOOST_TEST(lexical_cast<bool>("+0") == false);
BOOST_TEST(lexical_cast<bool>("-0") == false);
BOOST_TEST_THROWS(lexical_cast<bool>("--0"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("-+-0"), bad_lexical_cast);
BOOST_TEST(lexical_cast<bool>("0") == false);
BOOST_TEST(lexical_cast<bool>("1") == true);
BOOST_TEST(lexical_cast<bool>("00") == false);
BOOST_TEST(lexical_cast<bool>("00000000000") == false);
BOOST_TEST(lexical_cast<bool>("000000000001") == true);
BOOST_TEST(lexical_cast<bool>("+00") == false );
BOOST_TEST(lexical_cast<bool>("-00") == false );
BOOST_TEST(lexical_cast<bool>("+00000000001") == true );
BOOST_TEST_THROWS(lexical_cast<bool>("020"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("00200"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("-00200"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("+00200"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("000000000002"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("-1"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("-0000000001"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("00000000011"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("001001"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("-00000000010"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>("-000000000100"), bad_lexical_cast);
}
void test_conversion_to_string()
{
char buf[] = "hello";
char* str = buf;
BOOST_TEST_EQ(str, lexical_cast<std::string>(str));
BOOST_TEST_EQ("A", lexical_cast<std::string>('A'));
BOOST_TEST_EQ(" ", lexical_cast<std::string>(' '));
BOOST_TEST_EQ("123", lexical_cast<std::string>(123));
BOOST_TEST_EQ("1.23", lexical_cast<std::string>(1.23));
BOOST_TEST_EQ("1.111111111", lexical_cast<std::string>(1.111111111));
BOOST_TEST_EQ("1", lexical_cast<std::string>(true));
BOOST_TEST_EQ("0", lexical_cast<std::string>(false));
BOOST_TEST_EQ("Test", lexical_cast<std::string>("Test"));
BOOST_TEST_EQ(" ", lexical_cast<std::string>(" "));
BOOST_TEST_EQ("", lexical_cast<std::string>(""));
BOOST_TEST_EQ("Test", lexical_cast<std::string>(std::string("Test")));
BOOST_TEST_EQ(" ", lexical_cast<std::string>(std::string(" ")));
BOOST_TEST_EQ("", lexical_cast<std::string>(std::string("")));
}
void test_conversion_from_to_wchar_t_alias()
{
BOOST_TEST_EQ(123u, lexical_cast<unsigned short>("123"));
BOOST_TEST_EQ(123u, lexical_cast<unsigned int>("123"));
BOOST_TEST_EQ(123u, lexical_cast<unsigned long>("123"));
BOOST_TEST_EQ(std::string("123"),
lexical_cast<std::string>(static_cast<unsigned short>(123)));
BOOST_TEST_EQ(std::string("123"), lexical_cast<std::string>(123u));
BOOST_TEST_EQ(std::string("123"), lexical_cast<std::string>(123ul));
}
void test_conversion_from_wchar_t()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_TEST_EQ(1, lexical_cast<int>(L'1'));
BOOST_TEST_THROWS(lexical_cast<int>(L'A'), bad_lexical_cast);
#endif
BOOST_TEST_EQ(123, lexical_cast<int>(L"123"));
BOOST_TEST_THROWS(lexical_cast<int>(L""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<int>(L"Test"), bad_lexical_cast);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_TEST_EQ(1.0, lexical_cast<double>(L'1'));
BOOST_TEST_THROWS(lexical_cast<double>(L'A'), bad_lexical_cast);
#endif
BOOST_TEST_EQ(1.23, lexical_cast<double>(L"1.23"));
BOOST_TEST_THROWS(lexical_cast<double>(L""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<double>(L"Test"), bad_lexical_cast);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_TEST_EQ(true, lexical_cast<bool>(L'1'));
BOOST_TEST_EQ(false, lexical_cast<bool>(L'0'));
BOOST_TEST_THROWS(lexical_cast<bool>(L'A'), bad_lexical_cast);
#endif
BOOST_TEST_EQ(true, lexical_cast<bool>(L"1"));
BOOST_TEST_EQ(false, lexical_cast<bool>(L"0"));
BOOST_TEST_THROWS(lexical_cast<bool>(L""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<bool>(L"Test"), bad_lexical_cast);
#endif
}
void test_conversion_to_wchar_t()
{
#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_TEST(L'1' == lexical_cast<wchar_t>(1));
BOOST_TEST(L'0' == lexical_cast<wchar_t>(0));
BOOST_TEST(L'1' == lexical_cast<wchar_t>('1'));
BOOST_TEST(L'0' == lexical_cast<wchar_t>('0'));
BOOST_TEST_THROWS(lexical_cast<wchar_t>(123), bad_lexical_cast);
BOOST_TEST(L'1' == lexical_cast<wchar_t>(1.0));
BOOST_TEST(L'0' == lexical_cast<wchar_t>(0.0));
BOOST_TEST(L'1' == lexical_cast<wchar_t>(true));
BOOST_TEST(L'0' == lexical_cast<wchar_t>(false));
BOOST_TEST(L'A' == lexical_cast<wchar_t>(L'A'));
BOOST_TEST(L' ' == lexical_cast<wchar_t>(L' '));
BOOST_TEST(L'A' == lexical_cast<wchar_t>(L"A"));
BOOST_TEST(L' ' == lexical_cast<wchar_t>(L" "));
BOOST_TEST_THROWS(lexical_cast<wchar_t>(L""), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<wchar_t>(L"Test"), bad_lexical_cast);
BOOST_TEST(L'A' == lexical_cast<wchar_t>(std::wstring(L"A")));
BOOST_TEST(L' ' == lexical_cast<wchar_t>(std::wstring(L" ")));
BOOST_TEST_THROWS(
lexical_cast<wchar_t>(std::wstring(L"")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<wchar_t>(std::wstring(L"Test")), bad_lexical_cast);
#endif
BOOST_TEST(true);
}
void test_conversion_from_wstring()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
BOOST_TEST_EQ(123, lexical_cast<int>(std::wstring(L"123")));
BOOST_TEST_THROWS(
lexical_cast<int>(std::wstring(L"")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<int>(std::wstring(L"Test")), bad_lexical_cast);
BOOST_TEST_EQ(true, lexical_cast<bool>(std::wstring(L"1")));
BOOST_TEST_EQ(false, lexical_cast<bool>(std::wstring(L"0")));
BOOST_TEST_THROWS(
lexical_cast<bool>(std::wstring(L"")), bad_lexical_cast);
BOOST_TEST_THROWS(
lexical_cast<bool>(std::wstring(L"Test")), bad_lexical_cast);
#endif
BOOST_TEST(true);
}
void test_conversion_to_wstring()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
wchar_t buf[] = L"hello";
wchar_t* str = buf;
BOOST_TEST(str == lexical_cast<std::wstring>(str));
BOOST_TEST(L"123" == lexical_cast<std::wstring>(123));
BOOST_TEST(L"1.23" == lexical_cast<std::wstring>(1.23));
BOOST_TEST(L"1" == lexical_cast<std::wstring>(true));
BOOST_TEST(L"0" == lexical_cast<std::wstring>(false));
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_TEST(L"A" == lexical_cast<std::wstring>(L'A'));
BOOST_TEST(L" " == lexical_cast<std::wstring>(L' '));
BOOST_TEST(L"A" == lexical_cast<std::wstring>('A'));
#endif
BOOST_TEST(L"Test" == lexical_cast<std::wstring>(L"Test"));
BOOST_TEST(L" " == lexical_cast<std::wstring>(L" "));
BOOST_TEST(L"" == lexical_cast<std::wstring>(L""));
BOOST_TEST(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
BOOST_TEST(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
BOOST_TEST(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
#endif
BOOST_TEST(true);
}
void test_bad_lexical_cast()
{
try
{
lexical_cast<int>(std::string("Test"));
BOOST_TEST(false); // Exception expected
}
catch(const bad_lexical_cast &e)
{
BOOST_TEST(e.source_type() == typeid(std::string));
BOOST_TEST(e.target_type() == typeid(int));
}
}
void test_no_whitespace_stripping()
{
BOOST_TEST_THROWS(lexical_cast<int>(" 123"), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<int>("123 "), bad_lexical_cast);
}
void test_traits()
{
typedef std::basic_string<char, my_traits<char> > my_string;
my_string const s("s");
BOOST_TEST(boost::lexical_cast<char>(s) == s[0]);
BOOST_TEST(boost::lexical_cast<my_string>(s) == s);
BOOST_TEST(boost::lexical_cast<my_string>(-1) == "-1");
BOOST_TEST(boost::lexical_cast<int>(my_string("42")) == 42);
BOOST_TEST(boost::lexical_cast<double>(my_string("1.0")) == 1.0);
}
void test_wtraits()
{
typedef std::basic_string<wchar_t, my_traits<wchar_t> > my_string;
my_string const s(L"s");
BOOST_TEST(boost::lexical_cast<wchar_t>(s) == s[0]);
BOOST_TEST(boost::lexical_cast<my_string>(s) == s);
BOOST_TEST(boost::lexical_cast<my_string>(-1) == L"-1");
BOOST_TEST(boost::lexical_cast<int>(my_string(L"42")) == 42);
BOOST_TEST(boost::lexical_cast<double>(my_string(L"1.0")) == 1.0);
}
void test_allocator()
{
// Following test cause compilation error on MSVC2012:
// (Reason: cannot convert from 'std::_Wrap_alloc<_Alloc>' to 'const my_allocator<CharT>')
//
// MSVC developer is notified about this issue
#if !defined(_MSC_VER) || (_MSC_VER < 1700)
typedef std::basic_string< char
, std::char_traits<char>
, my_allocator<char>
> my_string;
my_string s("s");
BOOST_TEST(boost::lexical_cast<char>(s) == s[0]);
BOOST_TEST(boost::lexical_cast<std::string>(s) == "s");
BOOST_TEST(boost::lexical_cast<my_string>(s) == s);
BOOST_TEST(boost::lexical_cast<my_string>(1) == "1");
BOOST_TEST(boost::lexical_cast<my_string>("s") == s);
BOOST_TEST(boost::lexical_cast<my_string>(std::string("s")) == s);
#endif
}
void test_wallocator()
{
// Following test cause compilation error on MSVC2012:
// (Reason: cannot convert from 'std::_Wrap_alloc<_Alloc>' to 'const my_allocator<CharT>')
//
// MSVC developer is notified about this issue
#if !defined(_MSC_VER) || (_MSC_VER < 1700)
typedef std::basic_string< wchar_t
, std::char_traits<wchar_t>
, my_allocator<wchar_t>
> my_string;
my_string s(L"s");
BOOST_TEST(boost::lexical_cast<wchar_t>(s) == s[0]);
BOOST_TEST(boost::lexical_cast<std::wstring>(s) == L"s");
BOOST_TEST(boost::lexical_cast<my_string>(s) == s);
BOOST_TEST(boost::lexical_cast<my_string>(1) == L"1");
BOOST_TEST(boost::lexical_cast<my_string>(L"s") == s);
BOOST_TEST(boost::lexical_cast<my_string>(std::wstring(L"s")) == s);
#endif
}
void test_char_types_conversions()
{
const char c_arr[] = "Test array of chars";
const unsigned char uc_arr[] = "Test array of chars";
const signed char sc_arr[] = "Test array of chars";
BOOST_TEST(boost::lexical_cast<std::string>(c_arr) == std::string(c_arr));
BOOST_TEST(boost::lexical_cast<std::string>(uc_arr) == std::string(c_arr));
BOOST_TEST(boost::lexical_cast<std::string>(sc_arr) == std::string(c_arr));
BOOST_TEST(boost::lexical_cast<char>(c_arr[0]) == c_arr[0]);
BOOST_TEST(boost::lexical_cast<char>(uc_arr[0]) == c_arr[0]);
BOOST_TEST(boost::lexical_cast<char>(sc_arr[0]) == c_arr[0]);
BOOST_TEST(boost::lexical_cast<unsigned char>(c_arr[0]) == uc_arr[0]);
BOOST_TEST(boost::lexical_cast<unsigned char>(uc_arr[0]) == uc_arr[0]);
BOOST_TEST(boost::lexical_cast<unsigned char>(sc_arr[0]) == uc_arr[0]);
BOOST_TEST(boost::lexical_cast<signed char>(c_arr[0]) == sc_arr[0]);
BOOST_TEST(boost::lexical_cast<signed char>(uc_arr[0]) == sc_arr[0]);
BOOST_TEST(boost::lexical_cast<signed char>(sc_arr[0]) == sc_arr[0]);
#ifndef BOOST_LCAST_NO_WCHAR_T
const wchar_t wc_arr[]=L"Test array of chars";
BOOST_TEST(boost::lexical_cast<std::wstring>(wc_arr) == std::wstring(wc_arr));
BOOST_TEST(boost::lexical_cast<wchar_t>(wc_arr[0]) == wc_arr[0]);
#endif
}
struct foo_operators_test
{
foo_operators_test() : f(2) {}
int f;
};
template <typename OStream>
OStream& operator<<(OStream& ostr, const foo_operators_test& foo)
{
ostr << foo.f;
return ostr;
}
template <typename IStream>
IStream& operator>>(IStream& istr, foo_operators_test& foo)
{
istr >> foo.f;
return istr;
}
void operators_overload_test()
{
foo_operators_test foo;
BOOST_TEST_EQ(boost::lexical_cast<std::string>(foo), "2");
BOOST_TEST_EQ((boost::lexical_cast<foo_operators_test>("2")).f, 2);
// Must compile
(void)boost::lexical_cast<foo_operators_test>(foo);
}
void test_char16_conversions()
{
// There's no std::ctype<char16_t> in Xcode_15.0.1
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(__APPLE__)
BOOST_TEST(u"100" == lexical_cast<std::u16string>(u"100"));
#if !defined(_LIBCPP_VERSION) // libc++ also does not have std::ctype<char16_t>
BOOST_TEST(u"1" == lexical_cast<std::u16string>(u'1'));
#endif
#endif
}
void test_char32_conversions()
{
// There's no std::ctype<char32_t> in Xcode_15.0.1
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(__APPLE__)
BOOST_TEST(U"100" == lexical_cast<std::u32string>(U"100"));
#if !defined(_LIBCPP_VERSION) // libc++ also does not have std::ctype<char32_t>
BOOST_TEST(U"1" == lexical_cast<std::u32string>(U'1'));
#endif
#endif
}
void test_getting_pointer_to_function()
{
// Just checking that &lexical_cast<To, From> is not ambiguous
typedef char char_arr[4];
typedef int(*f1)(const char_arr&);
f1 p1 = &boost::lexical_cast<int, char_arr>;
BOOST_TEST(p1);
typedef int(*f2)(const std::string&);
f2 p2 = &boost::lexical_cast<int, std::string>;
BOOST_TEST(p2);
typedef std::string(*f3)(const int&);
f3 p3 = &boost::lexical_cast<std::string, int>;
BOOST_TEST(p3);
std::vector<int> values;
std::vector<std::string> ret;
std::transform(values.begin(), values.end(), ret.begin(), boost::lexical_cast<std::string, int>);
}
int main()
{
test_conversion_to_char();
test_conversion_to_int();
test_conversion_to_double();
test_conversion_to_bool();
test_conversion_from_to_wchar_t_alias();
test_conversion_to_string();
test_conversion_with_nonconst_char();
#ifndef BOOST_LCAST_NO_WCHAR_T
test_conversion_from_wchar_t();
test_conversion_to_wchar_t();
test_conversion_from_wstring();
test_conversion_to_wstring();
#endif
test_bad_lexical_cast();
test_no_whitespace_stripping();
test_traits();
test_wtraits();
test_allocator();
test_wallocator();
test_char_types_conversions();
operators_overload_test();
test_char16_conversions();
test_char32_conversions();
test_getting_pointer_to_function();
return boost::report_errors();
}
@@ -1,48 +0,0 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_typedefed_wchar_t_runtime()
{
#ifndef BOOST_LCAST_NO_WCHAR_T
#ifdef BOOST_MSVC
BOOST_STATIC_ASSERT((boost::is_same<wchar_t, unsigned short>::value));
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(L'A'), 65);
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(L'B'), 66);
BOOST_CHECK_EQUAL(boost::lexical_cast<wchar_t>(L"65"), 65);
BOOST_CHECK_EQUAL(boost::lexical_cast<wchar_t>(L"66"), 66);
#endif
#endif
BOOST_CHECK(1);
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast typedefed wchar_t runtime test");
suite->add(BOOST_TEST_CASE(&test_typedefed_wchar_t_runtime));
return suite;
}
@@ -3,6 +3,7 @@
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Alexander Nasonov, 2006.
// Copyright Antony Polukhin, 2023-2026.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -11,56 +12,38 @@
// Test round-tripping conversion FPT -> string -> FPT,
// where FPT is Floating Point Type.
#include <boost/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_round_conversion_float();
void test_round_conversion_double();
void test_round_conversion_long_double();
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_round_conversion_float));
suite->add(BOOST_TEST_CASE(&test_round_conversion_double));
suite->add(BOOST_TEST_CASE(&test_round_conversion_long_double));
return suite;
}
#if (defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__NetBSD__) \
|| (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \
|| defined(__MINGW64__)
# define BOOST_LEXICAL_CAST_NO_LONG_DOUBLE_MATH_FUNCTIONS
#endif
template<class T>
void test_round_conversion()
{
T epsilon = std::numeric_limits<T>::epsilon();
std::string const epsilon_s = boost::lexical_cast<std::string>(epsilon);
BOOST_CHECK(epsilon == lexical_cast<T>(epsilon_s));
BOOST_TEST(epsilon == boost::lexical_cast<T>(epsilon_s));
T max_ = (std::numeric_limits<T>::max)();
std::string const max_s = boost::lexical_cast<std::string>(max_);
BOOST_CHECK(max_ == lexical_cast<T>(max_s));
BOOST_TEST(max_ == boost::lexical_cast<T>(max_s));
T min_ = (std::numeric_limits<T>::min)();
std::string const min_s = boost::lexical_cast<std::string>(min_);
BOOST_CHECK(min_ == lexical_cast<T>(min_s));
BOOST_TEST(min_ == boost::lexical_cast<T>(min_s));
T max_div137 = max_ / 137;
std::string max_div137_s = boost::lexical_cast<std::string>(max_div137);
BOOST_CHECK(max_div137 == lexical_cast<T>(max_div137_s));
BOOST_TEST(max_div137 == boost::lexical_cast<T>(max_div137_s));
T epsilon_mult137 = epsilon * 137;
std::string epsilon_mult137_s(lexical_cast<std::string>(epsilon_mult137));
BOOST_CHECK(epsilon_mult137 == lexical_cast<T>(epsilon_mult137_s));
std::string epsilon_mult137_s(boost::lexical_cast<std::string>(epsilon_mult137));
BOOST_TEST(epsilon_mult137 == boost::lexical_cast<T>(epsilon_mult137_s));
}
@@ -70,7 +53,7 @@ void test_msvc_magic_values()
{
T magic_msvc = 0.00010000433948393407;
std::string magic_msvc_s = boost::lexical_cast<std::string>(magic_msvc);
BOOST_CHECK(magic_msvc == lexical_cast<T>(magic_msvc_s));
BOOST_TEST(magic_msvc == boost::lexical_cast<T>(magic_msvc_s));
}
void test_round_conversion_float()
@@ -86,11 +69,20 @@ void test_round_conversion_double()
void test_round_conversion_long_double()
{
// We do not run tests on compilers with bugs
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
// We do not run tests on compilers and Standard Libraries with poor support of long double
#if !defined(BOOST_LEXICAL_CAST_NO_LONG_DOUBLE_MATH_FUNCTIONS)
test_round_conversion<long double>();
test_msvc_magic_values<long double>();
#endif
BOOST_CHECK(true);
BOOST_TEST(true);
}
int main()
{
test_round_conversion_float();
test_round_conversion_double();
test_round_conversion_long_double();
return boost::report_errors();
}
+78
View File
@@ -0,0 +1,78 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012-2026.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/range/iterator_range.hpp>
#include <cstdlib>
#if defined(BOOST_USE_MODULES)
#undef BOOST_USE_MODULES
#endif
#include <boost/lexical_cast.hpp>
#include "escape_struct.hpp"
#ifndef BOOST_NO_EXCEPTIONS
#error "This test must be compiled with -DBOOST_NO_EXCEPTIONS"
#endif
namespace boost {
BOOST_NORETURN void throw_exception(std::exception const & ) {
static int state = 0;
++ state;
EscapeStruct v("");
switch(state) {
case 1:
lexical_cast<char>(v); // should call boost::throw_exception
std::exit(1);
case 2:
lexical_cast<unsigned char>(v); // should call boost::throw_exception
std::exit(2);
}
std::exit(boost::report_errors());
}
}
void test_exceptions_off() {
using namespace boost;
EscapeStruct v("");
v = lexical_cast<EscapeStruct>(100);
BOOST_TEST_EQ(lexical_cast<int>(v), 100);
BOOST_TEST_EQ(lexical_cast<unsigned int>(v), 100u);
v = lexical_cast<EscapeStruct>(0.0);
BOOST_TEST_EQ(lexical_cast<double>(v), 0.0);
BOOST_TEST_EQ(lexical_cast<short>(100), 100);
BOOST_TEST_EQ(lexical_cast<float>(0.0), 0.0);
lexical_cast<short>(700000); // should call boost::throw_exception
BOOST_TEST(false);
}
int main() {
test_exceptions_off();
return boost::report_errors();
}
+143
View File
@@ -0,0 +1,143 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012-2026.
//
// 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/core/lightweight_test.hpp>
#include <boost/range/iterator_range.hpp>
#include "escape_struct.hpp"
#include <vector>
#include <boost/lexical_cast.hpp>
using namespace boost;
// Testing compilation and some basic usage with BOOST_NO_STD_LOCALE
// Tests are mainly copyied from empty_input_test.cpp (something
// new added to test_empty_3)
#ifndef BOOST_NO_STD_LOCALE
#error "This test must be compiled with -DBOOST_NO_STD_LOCALE"
#endif
template <class T>
void do_test_on_empty_input(T& v)
{
BOOST_TEST_THROWS(lexical_cast<int>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<float>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<double>(v), bad_lexical_cast);
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
BOOST_TEST_THROWS(lexical_cast<long double>(v), bad_lexical_cast);
#endif
BOOST_TEST_THROWS(lexical_cast<unsigned int>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned short>(v), bad_lexical_cast);
#if defined(BOOST_HAS_LONG_LONG)
BOOST_TEST_THROWS(lexical_cast<boost::ulong_long_type>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<boost::long_long_type>(v), bad_lexical_cast);
#elif defined(BOOST_HAS_MS_INT64)
BOOST_TEST_THROWS(lexical_cast<unsigned __int64>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<__int64>(v), bad_lexical_cast);
#endif
}
void test_empty_1()
{
boost::iterator_range<char*> v;
do_test_on_empty_input(v);
BOOST_TEST_EQ(lexical_cast<std::string>(v), std::string());
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
boost::iterator_range<const char*> cv;
do_test_on_empty_input(cv);
BOOST_TEST_EQ(lexical_cast<std::string>(cv), std::string());
BOOST_TEST_THROWS(lexical_cast<char>(cv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(cv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(cv), bad_lexical_cast);
const boost::iterator_range<const char*> ccv;
do_test_on_empty_input(ccv);
BOOST_TEST_EQ(lexical_cast<std::string>(ccv), std::string());
BOOST_TEST_THROWS(lexical_cast<char>(ccv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(ccv), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(ccv), bad_lexical_cast);
}
void test_empty_2()
{
std::string v;
do_test_on_empty_input(v);
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
}
void test_empty_3()
{
EscapeStruct v("");
do_test_on_empty_input(v);
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
v = lexical_cast<EscapeStruct>(100);
BOOST_TEST_EQ(lexical_cast<int>(v), 100);
BOOST_TEST_EQ(lexical_cast<unsigned int>(v), 100u);
v = lexical_cast<EscapeStruct>(0.0);
BOOST_TEST_EQ(lexical_cast<double>(v), 0.0);
}
namespace std {
inline std::ostream & operator<<(std::ostream & out, const std::vector<long> & v)
{
std::ostream_iterator<long> it(out);
std::copy(v.begin(), v.end(), it);
BOOST_TEST(out);
return out;
}
}
void test_empty_4()
{
std::vector<long> v;
do_test_on_empty_input(v);
BOOST_TEST_THROWS(lexical_cast<char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<unsigned char>(v), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<signed char>(v), bad_lexical_cast);
}
struct my_string {
friend std::ostream &operator<<(std::ostream& sout, my_string const&/* st*/) {
return sout << "";
}
};
void test_empty_5()
{
my_string st;
BOOST_TEST_EQ(boost::lexical_cast<std::string>(st), std::string());;
}
int main()
{
test_empty_1();
test_empty_2();
test_empty_3();
test_empty_4();
test_empty_5();
return boost::report_errors();
}
@@ -3,6 +3,7 @@
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Alexander Nasonov, 2007.
// Copyright Antony Polukhin, 2023-2026.
//
// Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -10,30 +11,11 @@
//
// Test that Source can be non-copyable.
#include <boost/config.hpp>
#include <boost/core/noncopyable.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
void test_noncopyable();
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_noncopyable));
return suite;
}
class Noncopyable : private boost::noncopyable
{
@@ -49,6 +31,11 @@ inline std::ostream &operator<<(std::ostream &out, const Noncopyable&)
void test_noncopyable()
{
Noncopyable x;
BOOST_CHECK(boost::lexical_cast<std::string>(x) == "Noncopyable");
BOOST_TEST(boost::lexical_cast<std::string>(x) == "Noncopyable");
}
int main()
{
test_noncopyable();
return boost::report_errors();
}
+16 -24
View File
@@ -2,24 +2,17 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012.
// Copyright Antony Polukhin, 2012-2026.
//
// 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/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <sstream>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
#if defined(BOOST_NO_STRINGSTREAM)
typedef std::strstream ss_t;
@@ -36,15 +29,15 @@ void test_void_pointers_conversions()
ss_t ss;
ss << p_to_null;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(p_to_null), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(p_to_null), ss.str());
ss.str(std::string());
ss << cp_to_data;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(cp_to_data), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(cp_to_data), ss.str());
ss.str(std::string());
ss << p_to_data;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(p_to_data), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(p_to_data), ss.str());
ss.str(std::string());
}
@@ -59,15 +52,15 @@ void test_incomplete_type_pointers_conversions()
ss_t ss;
ss << p_to_null;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(p_to_null), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(p_to_null), ss.str());
ss.str(std::string());
ss << cp_to_data;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(cp_to_data), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(cp_to_data), ss.str());
ss.str(std::string());
ss << p_to_data;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(p_to_data), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(p_to_data), ss.str());
ss.str(std::string());
}
@@ -82,15 +75,14 @@ void test_inomplete_type_with_overloaded_ostream_op() {
meh heh = NULL;
ss_t ss;
ss << heh;
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(heh), ss.str());
BOOST_TEST_EQ(boost::lexical_cast<std::string>(heh), ss.str());
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
int main()
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast pinters test");
suite->add(BOOST_TEST_CASE(&test_void_pointers_conversions));
suite->add(BOOST_TEST_CASE(&test_incomplete_type_pointers_conversions));
suite->add(BOOST_TEST_CASE(&test_inomplete_type_with_overloaded_ostream_op));
return suite;
test_void_pointers_conversions();
test_incomplete_type_pointers_conversions();
test_inomplete_type_with_overloaded_ostream_op();
return boost::report_errors();
}
@@ -2,19 +2,18 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2012.
// Copyright Antony Polukhin, 2011-2026.
//
// 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/config.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iostream>
#include <type_traits>
#include <boost/lexical_cast.hpp>
///////////////////////// char streamable classes ///////////////////////////////////////////
@@ -24,33 +23,33 @@ std::ostream& operator << (std::ostream& ostr, const streamable_easy&) {
return ostr << streamable_easy::value;
}
std::istream& operator >> (std::istream& istr, const streamable_easy&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_easy::value);
int i; istr >> i; BOOST_TEST_EQ(i, streamable_easy::value);
return istr;
}
struct streamable_medium { enum ENU {value = 1}; };
template <class CharT>
typename boost::enable_if<boost::is_same<CharT, char>, std::basic_ostream<CharT>&>::type
typename std::enable_if<std::is_same<CharT, char>::value, std::basic_ostream<CharT>&>::type
operator << (std::basic_ostream<CharT>& ostr, const streamable_medium&) {
return ostr << streamable_medium::value;
}
template <class CharT>
typename boost::enable_if<boost::is_same<CharT, char>, std::basic_istream<CharT>&>::type
typename std::enable_if<std::is_same<CharT, char>::value, std::basic_istream<CharT>&>::type
operator >> (std::basic_istream<CharT>& istr, const streamable_medium&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_medium::value);
int i; istr >> i; BOOST_TEST_EQ(i, streamable_medium::value);
return istr;
}
struct streamable_hard { enum ENU {value = 2}; };
template <class CharT, class TraitsT>
typename boost::enable_if<boost::is_same<CharT, char>, std::basic_ostream<CharT, TraitsT>&>::type
typename std::enable_if<std::is_same<CharT, char>::value, std::basic_ostream<CharT, TraitsT>&>::type
operator << (std::basic_ostream<CharT, TraitsT>& ostr, const streamable_hard&) {
return ostr << streamable_hard::value;
}
template <class CharT, class TraitsT>
typename boost::enable_if<boost::is_same<CharT, char>, std::basic_istream<CharT, TraitsT>&>::type
typename std::enable_if<std::is_same<CharT, char>::value, std::basic_istream<CharT, TraitsT>&>::type
operator >> (std::basic_istream<CharT, TraitsT>& istr, const streamable_hard&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_hard::value);
int i; istr >> i; BOOST_TEST_EQ(i, streamable_hard::value);
return istr;
}
@@ -61,7 +60,7 @@ std::basic_ostream<char, TraitsT>& operator << (std::basic_ostream<char, TraitsT
}
template <class TraitsT>
std::basic_istream<char, TraitsT>& operator >> (std::basic_istream<char, TraitsT>& istr, const streamable_hard2&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, streamable_hard2::value);
int i; istr >> i; BOOST_TEST_EQ(i, streamable_hard2::value);
return istr;
}
@@ -73,33 +72,33 @@ std::wostream& operator << (std::wostream& ostr, const wstreamable_easy&) {
return ostr << wstreamable_easy::value;
}
std::wistream& operator >> (std::wistream& istr, const wstreamable_easy&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_easy::value);
int i; istr >> i; BOOST_TEST_EQ(i, wstreamable_easy::value);
return istr;
}
struct wstreamable_medium { enum ENU {value = 5}; };
template <class CharT>
typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_ostream<CharT>& >::type
typename std::enable_if<std::is_same<CharT, wchar_t>::value, std::basic_ostream<CharT>& >::type
operator << (std::basic_ostream<CharT>& ostr, const wstreamable_medium&) {
return ostr << wstreamable_medium::value;
}
template <class CharT>
typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_istream<CharT>& >::type
typename std::enable_if<std::is_same<CharT, wchar_t>::value, std::basic_istream<CharT>& >::type
operator >> (std::basic_istream<CharT>& istr, const wstreamable_medium&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_medium::value);
int i; istr >> i; BOOST_TEST_EQ(i, wstreamable_medium::value);
return istr;
}
struct wstreamable_hard { enum ENU {value = 6}; };
template <class CharT, class TraitsT>
typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_ostream<CharT, TraitsT>&>::type
typename std::enable_if<std::is_same<CharT, wchar_t>::value, std::basic_ostream<CharT, TraitsT>&>::type
operator << (std::basic_ostream<CharT, TraitsT>& ostr, const wstreamable_hard&) {
return ostr << wstreamable_hard::value;
}
template <class CharT, class TraitsT>
typename boost::enable_if<boost::is_same<CharT, wchar_t>, std::basic_istream<CharT, TraitsT>&>::type
typename std::enable_if<std::is_same<CharT, wchar_t>::value, std::basic_istream<CharT, TraitsT>&>::type
operator >> (std::basic_istream<CharT, TraitsT>& istr, const wstreamable_hard&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_hard::value);
int i; istr >> i; BOOST_TEST_EQ(i, wstreamable_hard::value);
return istr;
}
@@ -110,7 +109,7 @@ std::basic_ostream<wchar_t, TraitsT>& operator << (std::basic_ostream<wchar_t, T
}
template <class TraitsT>
std::basic_istream<wchar_t, TraitsT>& operator >> (std::basic_istream<wchar_t, TraitsT>& istr, const wstreamable_hard2&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, wstreamable_hard2::value);
int i; istr >> i; BOOST_TEST_EQ(i, wstreamable_hard2::value);
return istr;
}
@@ -122,7 +121,7 @@ std::ostream& operator << (std::ostream& ostr, const bistreamable_easy&) {
return ostr << bistreamable_easy::value;
}
std::istream& operator >> (std::istream& istr, const bistreamable_easy&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_easy::value);
int i; istr >> i; BOOST_TEST_EQ(i, bistreamable_easy::value);
return istr;
}
@@ -130,7 +129,7 @@ std::wostream& operator << (std::wostream& ostr, const bistreamable_easy&) {
return ostr << bistreamable_easy::value + 100;
}
std::wistream& operator >> (std::wistream& istr, const bistreamable_easy&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_easy::value + 100);
int i; istr >> i; BOOST_TEST_EQ(i, bistreamable_easy::value + 100);
return istr;
}
@@ -141,7 +140,7 @@ std::basic_ostream<CharT>& operator << (std::basic_ostream<CharT>& ostr, const b
}
template <class CharT>
std::basic_istream<CharT>& operator >> (std::basic_istream<CharT>& istr, const bistreamable_medium&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_medium::value + (sizeof(CharT) == 1 ? 0 : 100));
int i; istr >> i; BOOST_TEST_EQ(i, bistreamable_medium::value + (sizeof(CharT) == 1 ? 0 : 100));
return istr;
}
@@ -152,7 +151,7 @@ std::basic_ostream<CharT, TraitsT>& operator << (std::basic_ostream<CharT, Trait
}
template <class CharT, class TraitsT>
std::basic_istream<CharT, TraitsT>& operator >> (std::basic_istream<CharT, TraitsT>& istr, const bistreamable_hard&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard::value + (sizeof(CharT) == 1 ? 0 : 100));
int i; istr >> i; BOOST_TEST_EQ(i, bistreamable_hard::value + (sizeof(CharT) == 1 ? 0 : 100));
return istr;
}
@@ -163,7 +162,7 @@ std::basic_ostream<char, TraitsT>& operator << (std::basic_ostream<char, TraitsT
}
template <class TraitsT>
std::basic_istream<char, TraitsT>& operator >> (std::basic_istream<char, TraitsT>& istr, const bistreamable_hard2&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard2::value);
int i; istr >> i; BOOST_TEST_EQ(i, bistreamable_hard2::value);
return istr;
}
@@ -173,49 +172,33 @@ std::basic_ostream<wchar_t, TraitsT>& operator << (std::basic_ostream<wchar_t, T
}
template <class TraitsT>
std::basic_istream<wchar_t, TraitsT>& operator >> (std::basic_istream<wchar_t, TraitsT>& istr, const bistreamable_hard2&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, bistreamable_hard2::value + 100);
int i; istr >> i; BOOST_TEST_EQ(i, bistreamable_hard2::value + 100);
return istr;
}
void test_ostream_character_detection();
void test_istream_character_detection();
void test_mixed_stream_character_detection();
boost::unit_test::test_suite *init_unit_test_suite(int, char *[])
{
boost::unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast stream character detection");
suite->add(BOOST_TEST_CASE(&test_ostream_character_detection));
suite->add(BOOST_TEST_CASE(&test_istream_character_detection));
suite->add(BOOST_TEST_CASE(&test_mixed_stream_character_detection));
return suite;
}
template <class T>
static void test_ostr_impl() {
T streamable;
BOOST_CHECK_EQUAL(T::value, boost::lexical_cast<int>(streamable));
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable));
BOOST_TEST_EQ(T::value, boost::lexical_cast<int>(streamable));
BOOST_TEST_EQ(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable));
}
template <class T>
static void test_wostr_impl() {
T streamable;
BOOST_CHECK_EQUAL(T::value, boost::lexical_cast<int>(streamable));
// BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable)); // Shall not compile???
BOOST_CHECK(boost::lexical_cast<std::wstring>(T::value) == boost::lexical_cast<std::wstring>(streamable));
BOOST_TEST_EQ(T::value, boost::lexical_cast<int>(streamable));
// BOOST_TEST_EQ(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable)); // Shall not compile???
BOOST_TEST(boost::lexical_cast<std::wstring>(T::value) == boost::lexical_cast<std::wstring>(streamable));
}
template <class T>
static void test_bistr_impl() {
T streamable;
BOOST_CHECK_EQUAL(T::value, boost::lexical_cast<int>(streamable));
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable));
BOOST_TEST_EQ(T::value, boost::lexical_cast<int>(streamable));
BOOST_TEST_EQ(boost::lexical_cast<std::string>(T::value), boost::lexical_cast<std::string>(streamable));
BOOST_CHECK(boost::lexical_cast<std::wstring>(T::value + 100) == boost::lexical_cast<std::wstring>(streamable));
BOOST_TEST(boost::lexical_cast<std::wstring>(T::value + 100) == boost::lexical_cast<std::wstring>(streamable));
}
void test_ostream_character_detection() {
@@ -223,12 +206,12 @@ void test_ostream_character_detection() {
test_ostr_impl<streamable_medium>();
test_ostr_impl<streamable_hard>();
test_ostr_impl<streamable_hard2>();
test_wostr_impl<wstreamable_easy>();
test_wostr_impl<wstreamable_medium>();
test_wostr_impl<wstreamable_hard>();
test_wostr_impl<wstreamable_hard2>();
test_bistr_impl<bistreamable_easy>();
test_bistr_impl<bistreamable_medium>();
test_bistr_impl<bistreamable_hard>();
@@ -261,29 +244,26 @@ void test_istream_character_detection() {
test_istr_impl<streamable_medium>();
test_istr_impl<streamable_hard>();
test_istr_impl<streamable_hard2>();
test_wistr_impl<wstreamable_easy>();
test_wistr_impl<wstreamable_medium>();
test_wistr_impl<wstreamable_hard>();
test_wistr_impl<wstreamable_hard2>();
test_bistr_instr_impl<bistreamable_easy>();
test_bistr_instr_impl<bistreamable_medium>();
test_bistr_instr_impl<bistreamable_hard>();
test_bistr_instr_impl<bistreamable_hard2>();
}
struct wistreamble_ostreamable { enum ENU {value = 200}; };
std::ostream& operator << (std::ostream& ostr, const wistreamble_ostreamable&) {
return ostr << wistreamble_ostreamable::value;
}
std::wistream& operator >> (std::wistream& istr, const wistreamble_ostreamable&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, wistreamble_ostreamable::value);
int i = 100;
istr >> i;
BOOST_TEST_EQ(i, wistreamble_ostreamable::value);
return istr;
}
@@ -292,16 +272,27 @@ std::wostream& operator << (std::wostream& ostr, const istreamble_wostreamable&)
return ostr << istreamble_wostreamable::value;
}
std::istream& operator >> (std::istream& istr, const istreamble_wostreamable&) {
int i; istr >> i; BOOST_CHECK_EQUAL(i, istreamble_wostreamable::value);
int i; istr >> i; BOOST_TEST_EQ(i, istreamble_wostreamable::value);
return istr;
}
void test_mixed_stream_character_detection() {
//boost::lexical_cast<std::wstring>(std::string("qwe")); // TODO: ALLOW IT AS EXTENSION!
BOOST_TEST_EQ(boost::lexical_cast<int>(wistreamble_ostreamable::value), wistreamble_ostreamable::value);
boost::lexical_cast<wistreamble_ostreamable>(wistreamble_ostreamable::value);
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(wistreamble_ostreamable()), wistreamble_ostreamable::value);
BOOST_TEST_EQ(boost::lexical_cast<int>(wistreamble_ostreamable()), wistreamble_ostreamable::value);
boost::lexical_cast<istreamble_wostreamable>(istreamble_wostreamable::value);
BOOST_CHECK_EQUAL(boost::lexical_cast<int>(istreamble_wostreamable()), istreamble_wostreamable::value);
BOOST_TEST_EQ(boost::lexical_cast<int>(istreamble_wostreamable()), istreamble_wostreamable::value);
}
int main()
{
test_ostream_character_detection();
test_istream_character_detection();
test_mixed_stream_character_detection();
return boost::report_errors();
}
+195
View File
@@ -0,0 +1,195 @@
// Copyright Antony Polukhin, 2012-2026.
//
// 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).
#if defined(BOOST_USE_MODULES)
#undef BOOST_USE_MODULES
#endif
#include <boost/lexical_cast/detail/converter_lexical.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/array.hpp>
#include <boost/container/string.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/utility/string_view.hpp>
#include <type_traits>
template <class T>
struct is_optimized_stream : std::false_type {};
template <class CharT, class Traits, std::size_t CharacterBufferSize>
struct is_optimized_stream< boost::detail::lcast::optimized_src_stream<CharT, Traits, CharacterBufferSize> > : std::true_type {};
template <class Source, class Target>
static void assert_optimized_stream()
{
BOOST_TEST((is_optimized_stream<
typename boost::detail::lexical_converter_impl<Source, Target>::from_src_stream
>::value));
}
template <class T>
static void test_optimized_types_to_string_const()
{
namespace de = boost::detail;
typedef de::lexical_cast_stream_traits<T, std::string> trait_1;
BOOST_TEST((std::is_same<typename trait_1::src_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_1::target_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_1::char_type, char>::value));
assert_optimized_stream<T, std::string>();
assert_optimized_stream<T, boost::container::string>();
typedef de::lexical_cast_stream_traits<const T, std::string> trait_2;
BOOST_TEST((std::is_same<typename trait_2::src_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_2::target_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_2::char_type, char>::value));
typedef de::lexical_cast_stream_traits<T, std::wstring> trait_3;
BOOST_TEST((std::is_same<typename trait_3::src_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_3::target_char_t, wchar_t>::value));
BOOST_TEST((std::is_same<typename trait_3::char_type, wchar_t>::value));
assert_optimized_stream<T, std::wstring>();
assert_optimized_stream<T, boost::container::wstring>();
}
template <class T>
static void test_optimized_types_to_string()
{
test_optimized_types_to_string_const<T>();
namespace de = boost::detail;
typedef de::lexical_cast_stream_traits<std::string, T> trait_4;
BOOST_TEST((std::is_same<typename trait_4::src_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_4::target_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_4::char_type, char>::value));
assert_optimized_stream<std::string, T>();
typedef de::lexical_cast_stream_traits<const std::string, T> trait_5;
BOOST_TEST((std::is_same<typename trait_5::src_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_5::target_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_5::char_type, char>::value));
typedef de::lexical_cast_stream_traits<const std::wstring, T> trait_6;
BOOST_TEST((std::is_same<typename trait_6::src_char_t, wchar_t>::value));
BOOST_TEST((std::is_same<typename trait_6::target_char_t, char>::value));
BOOST_TEST((std::is_same<typename trait_6::char_type, wchar_t>::value));
}
template <class T>
static void test_optimized_types_to_x_string()
{
test_optimized_types_to_string<T>();
assert_optimized_stream<std::wstring, T>();
assert_optimized_stream<boost::container::wstring, T>();
}
template <class T>
static void test_optimized_types_to_wstring()
{
assert_optimized_stream<std::wstring, T>();
assert_optimized_stream<T, std::wstring>();
assert_optimized_stream<boost::container::wstring, T>();
assert_optimized_stream<T, boost::container::wstring>();
}
void test_metafunctions()
{
test_optimized_types_to_x_string<bool>();
test_optimized_types_to_x_string<char>();
test_optimized_types_to_x_string<unsigned char>();
test_optimized_types_to_x_string<signed char>();
test_optimized_types_to_x_string<short>();
test_optimized_types_to_x_string<unsigned short>();
test_optimized_types_to_x_string<int>();
test_optimized_types_to_x_string<unsigned int>();
test_optimized_types_to_x_string<long>();
test_optimized_types_to_x_string<unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
test_optimized_types_to_x_string<boost::ulong_long_type>();
test_optimized_types_to_x_string<boost::long_long_type>();
#elif defined(BOOST_HAS_MS_INT64)
test_optimized_types_to_x_string<unsigned __int64>();
test_optimized_types_to_x_string<__int64>();
#endif
test_optimized_types_to_string<float>();
test_optimized_types_to_string<double>();
test_optimized_types_to_string<long double>();
test_optimized_types_to_string<std::string>();
test_optimized_types_to_string<char*>();
//test_optimized_types_to_string<char[5]>();
//test_optimized_types_to_string<char[1]>();
test_optimized_types_to_string<unsigned char*>();
//test_optimized_types_to_string<unsigned char[5]>();
//test_optimized_types_to_string<unsigned char[1]>();
test_optimized_types_to_string<signed char*>();
//test_optimized_types_to_string<signed char[5]>();
//test_optimized_types_to_string<signed char[1]>();
test_optimized_types_to_string<boost::array<char, 1> >();
test_optimized_types_to_string<boost::array<char, 5> >();
test_optimized_types_to_string<boost::array<unsigned char, 1> >();
test_optimized_types_to_string<boost::array<unsigned char, 5> >();
test_optimized_types_to_string<boost::array<signed char, 1> >();
test_optimized_types_to_string<boost::array<signed char, 5> >();
test_optimized_types_to_string<boost::iterator_range<char*> >();
test_optimized_types_to_string<boost::iterator_range<unsigned char*> >();
test_optimized_types_to_string<boost::iterator_range<signed char*> >();
test_optimized_types_to_string_const<boost::array<const char, 1> >();
test_optimized_types_to_string_const<boost::array<const char, 5> >();
test_optimized_types_to_string_const<boost::array<const unsigned char, 1> >();
test_optimized_types_to_string_const<boost::array<const unsigned char, 5> >();
test_optimized_types_to_string_const<boost::array<const signed char, 1> >();
test_optimized_types_to_string_const<boost::array<const signed char, 5> >();
test_optimized_types_to_string_const<boost::iterator_range<const char*> >();
test_optimized_types_to_string_const<boost::iterator_range<const unsigned char*> >();
test_optimized_types_to_string_const<boost::iterator_range<const signed char*> >();
#ifndef BOOST_NO_CXX11_HDR_ARRAY
test_optimized_types_to_string<std::array<char, 1> >();
test_optimized_types_to_string<std::array<char, 5> >();
test_optimized_types_to_string<std::array<unsigned char, 1> >();
test_optimized_types_to_string<std::array<unsigned char, 5> >();
test_optimized_types_to_string<std::array<signed char, 1> >();
test_optimized_types_to_string<std::array<signed char, 5> >();
test_optimized_types_to_string_const<std::array<const char, 1> >();
test_optimized_types_to_string_const<std::array<const char, 5> >();
test_optimized_types_to_string_const<std::array<const unsigned char, 1> >();
test_optimized_types_to_string_const<std::array<const unsigned char, 5> >();
test_optimized_types_to_string_const<std::array<const signed char, 1> >();
test_optimized_types_to_string_const<std::array<const signed char, 5> >();
test_optimized_types_to_wstring<std::array<wchar_t, 42>>();
test_optimized_types_to_wstring<std::array<const wchar_t, 42>>();
#endif
test_optimized_types_to_wstring<wchar_t*>();
test_optimized_types_to_wstring<const wchar_t*>();
test_optimized_types_to_wstring<boost::iterator_range<const wchar_t*>>();
test_optimized_types_to_wstring<boost::iterator_range<wchar_t*>>();
test_optimized_types_to_string<boost::string_view>();
test_optimized_types_to_wstring<boost::basic_string_view<wchar_t>>();
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
test_optimized_types_to_string<std::string_view>();
test_optimized_types_to_wstring<std::basic_string_view<wchar_t>>();
#endif
}
int main()
{
test_metafunctions();
return boost::report_errors();
}
+49
View File
@@ -0,0 +1,49 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2012-2026.
//
// 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/utility/string_view.hpp>
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
#include <string_view>
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
template <class StringView>
void test_string_view_conversion() {
using boost::lexical_cast;
StringView sw = "1";
BOOST_TEST_EQ(lexical_cast<std::string>(sw), "1");
BOOST_TEST_EQ(lexical_cast<int>(sw), 1);
sw = StringView("a\0b", 3);
BOOST_TEST_EQ(lexical_cast<std::string>(sw), std::string("a\0b", 3));
sw = StringView("a\0b", 4);
BOOST_TEST_EQ(lexical_cast<std::string>(sw), std::string("a\0b", 4));
sw = StringView("\0a\0", 3);
BOOST_TEST_EQ(lexical_cast<std::string>(sw), std::string("\0a\0", 3));
}
int main() {
test_string_view_conversion<boost::string_view>();
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
test_string_view_conversion<std::string_view>();
#endif
return boost::report_errors();
}
@@ -2,22 +2,17 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2013.
// Copyright Antony Polukhin, 2013-2026.
//
// 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*[])
int main()
{
boost::lexical_cast<char*>("Hello");
BOOST_CHECK(false); // suppressing warning about 'boost::unit_test::{anonymous}::unit_test_log' defined but not used
return 0;
return 1;
}
+75
View File
@@ -0,0 +1,75 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2014-2026.
//
// 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/core/lightweight_test.hpp>
#include <boost/lexical_cast/try_lexical_convert.hpp>
using namespace boost::conversion;
void try_uncommon_cases()
{
std::string sres;
const bool res1 = try_lexical_convert(std::string("Test string"), sres);
BOOST_TEST(res1);
BOOST_TEST_EQ(sres, "Test string");
volatile int vires;
const bool res2 = try_lexical_convert(100, vires);
BOOST_TEST(res2);
BOOST_TEST_EQ(vires, 100);
const bool res3 = try_lexical_convert("Test string", sres);
BOOST_TEST(res3);
BOOST_TEST_EQ(sres, "Test string");
const bool res4 = try_lexical_convert("Test string", sizeof("Test string") - 1, sres);
BOOST_TEST(res4);
BOOST_TEST_EQ(sres, "Test string");
int ires;
BOOST_TEST(!try_lexical_convert("Test string", ires));
BOOST_TEST(!try_lexical_convert(1.1, ires));
BOOST_TEST(!try_lexical_convert(-1.9, ires));
BOOST_TEST(!try_lexical_convert("1.1", ires));
BOOST_TEST(!try_lexical_convert("1000000000000000000000000000000000000000", ires));
}
void try_common_cases()
{
int ires = 0;
const bool res1 = try_lexical_convert(std::string("100"), ires);
BOOST_TEST(res1);
BOOST_TEST_EQ(ires, 100);
ires = 0;
const bool res2 = try_lexical_convert("-100", ires);
BOOST_TEST(res2);
BOOST_TEST_EQ(ires, -100);
float fres = 1.0f;
const bool res3 = try_lexical_convert("0.0", fres);
BOOST_TEST(res3);
BOOST_TEST_EQ(fres, 0.0f);
fres = 1.0f;
const bool res4 = try_lexical_convert("0.0", sizeof("0.0") - 1, fres);
BOOST_TEST(res4);
BOOST_TEST_EQ(fres, 0.0f);
}
int main()
{
try_uncommon_cases();
try_common_cases();
return boost::report_errors();
}
+2 -8
View File
@@ -2,17 +2,15 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011.
// Copyright Antony Polukhin, 2011-2026.
//
// 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/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
@@ -29,10 +27,6 @@ void parseDate()
int main()
{
#ifdef BOOST_MSVC
BOOST_STATIC_ASSERT((boost::is_same<wchar_t, unsigned short>::value));
#endif
parseDate();
return ::boost::lexical_cast<int>(L"1000") == 1000;
}
+53
View File
@@ -0,0 +1,53 @@
// Unit test for boost::lexical_cast.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2026.
//
// 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/core/lightweight_test.hpp>
void test_typedefed_wchar_t(unsigned short) // wchar_t is a typedef for unsigned short
{
BOOST_TEST(boost::lexical_cast<int>(L'A') == 65);
BOOST_TEST(boost::lexical_cast<int>(L'B') == 66);
BOOST_TEST(boost::lexical_cast<wchar_t>(L"65") == 65);
BOOST_TEST(boost::lexical_cast<wchar_t>(L"66") == 66);
}
template <class T>
void test_typedefed_wchar_t(T)
{
BOOST_TEST(1);
}
void test_typedefed_wchar_t_runtime()
{
test_typedefed_wchar_t(L'0');
}
void test_unsigned_short_to_wstring()
{
// Test case from https://github.com/boostorg/lexical_cast/issues/89
unsigned short number = 4550;
auto res1 = boost::lexical_cast<std::wstring>(number);
BOOST_TEST(res1 == L"4550");
auto res2 = boost::lexical_cast<std::string>(number);
BOOST_TEST_EQ(res2, "4550");
}
int main()
{
test_typedefed_wchar_t_runtime();
test_unsigned_short_to_wstring();
return boost::report_errors();
}
@@ -12,12 +12,18 @@
// implementation has changed and it does not use stringstream for casts
// to integral types
#include <boost/config.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/cstdint.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string>
#include <sstream>
#include <boost/lexical_cast.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4127) // conditional expression is constant
#endif
using namespace boost;
@@ -33,22 +39,22 @@ void test_too_long_number(CharT zero)
std::basic_ostringstream<CharT> o;
o << (limits::max)() << zero;
s = o.str();
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s), bad_lexical_cast);
s[s.size()-1] += static_cast<CharT>(9); // '0' -> '9'
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s), bad_lexical_cast);
if(limits::is_signed)
if (limits::is_signed)
{
std::basic_ostringstream<CharT> o;
o << (limits::min)() << zero;
s = o.str();
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
std::basic_ostringstream<CharT> o2;
o2 << (limits::min)() << zero;
s = o2.str();
BOOST_TEST_THROWS(lexical_cast<T>(s), bad_lexical_cast);
s[s.size()-1] += static_cast<CharT>(9); // '0' -> '9'
BOOST_CHECK_THROW(lexical_cast<T>(s), bad_lexical_cast);
BOOST_TEST_THROWS(lexical_cast<T>(s), bad_lexical_cast);
}
}
void test_vc8_bug()
int main()
{
test_too_long_number<boost::intmax_t>('0');
test_too_long_number<boost::uintmax_t>('0');
@@ -56,12 +62,6 @@ void test_vc8_bug()
test_too_long_number<boost::intmax_t>(L'0');
test_too_long_number<boost::uintmax_t>(L'0');
#endif
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast vc8 bug unit test");
suite->add(BOOST_TEST_CASE(test_vc8_bug));
return suite;
return boost::report_errors();
}
@@ -2,24 +2,20 @@
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2011-2012.
// Copyright Antony Polukhin, 2011-2026.
//
// 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/config.hpp>
#if defined(__INTEL_COMPILER)
#pragma warning(disable: 193 383 488 981 1418 1419)
#elif defined(BOOST_MSVC)
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost;
#if defined(BOOST_USE_MODULES)
#undef BOOST_USE_MODULES
#endif
#include <boost/lexical_cast/detail/lcast_char_constants.hpp>
#if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
#define BOOST_LCAST_NO_WCHAR_T
@@ -36,14 +32,14 @@ void test_impl(const CharT* wc_arr)
// Following tests depend on realization of std::locale
// and pass for popular compilers and STL realizations
BOOST_CHECK(boost::lexical_cast<wide_char>(c_arr[0]) == wc_arr[0]);
BOOST_CHECK(boost::lexical_cast<wide_string>(c_arr) == wide_string(wc_arr));
BOOST_TEST(boost::lexical_cast<wide_char>(c_arr[0]) == wc_arr[0]);
BOOST_TEST(boost::lexical_cast<wide_string>(c_arr) == wide_string(wc_arr));
BOOST_CHECK(boost::lexical_cast<wide_string>(sc_arr) == wide_string(wc_arr) );
BOOST_CHECK(boost::lexical_cast<wide_string>(uc_arr) == wide_string(wc_arr) );
BOOST_TEST(boost::lexical_cast<wide_string>(sc_arr) == wide_string(wc_arr) );
BOOST_TEST(boost::lexical_cast<wide_string>(uc_arr) == wide_string(wc_arr) );
BOOST_CHECK_EQUAL(boost::lexical_cast<wide_char>(uc_arr[0]), wc_arr[0]);
BOOST_CHECK_EQUAL(boost::lexical_cast<wide_char>(sc_arr[0]), wc_arr[0]);
BOOST_TEST(boost::lexical_cast<wide_char>(uc_arr[0]) == wc_arr[0]);
BOOST_TEST(boost::lexical_cast<wide_char>(sc_arr[0]) == wc_arr[0]);
}
@@ -52,25 +48,25 @@ void test_char_types_conversions_wchar_t()
#ifndef BOOST_LCAST_NO_WCHAR_T
test_impl(L"Test array of chars");
wchar_t c = boost::detail::lcast_char_constants<wchar_t>::zero;
BOOST_CHECK_EQUAL(L'0', c);
BOOST_TEST(L'0' == c);
c = boost::detail::lcast_char_constants<wchar_t>::minus;
BOOST_CHECK_EQUAL(L'-', c);
BOOST_TEST(L'-' == c);
c = boost::detail::lcast_char_constants<wchar_t>::plus;
BOOST_CHECK_EQUAL(L'+', c);
BOOST_TEST(L'+' == c);
c = boost::detail::lcast_char_constants<wchar_t>::lowercase_e;
BOOST_CHECK_EQUAL(L'e', c);
BOOST_TEST(L'e' == c);
c = boost::detail::lcast_char_constants<wchar_t>::capital_e;
BOOST_CHECK_EQUAL(L'E', c);
BOOST_TEST(L'E' == c);
c = boost::detail::lcast_char_constants<wchar_t>::c_decimal_separator;
BOOST_CHECK_EQUAL(L'.', c);
BOOST_TEST(L'.' == c);
#endif
BOOST_CHECK(true);
BOOST_TEST(true);
}
void test_char_types_conversions_char16_t()
@@ -78,25 +74,25 @@ void test_char_types_conversions_char16_t()
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
test_impl(u"Test array of chars");
char16_t c = boost::detail::lcast_char_constants<char16_t>::zero;
BOOST_CHECK_EQUAL(u'0', c);
BOOST_TEST(u'0' == c);
c = boost::detail::lcast_char_constants<char16_t>::minus;
BOOST_CHECK_EQUAL(u'-', c);
BOOST_TEST(u'-' == c);
c = boost::detail::lcast_char_constants<char16_t>::plus;
BOOST_CHECK_EQUAL(u'+', c);
BOOST_TEST(u'+' == c);
c = boost::detail::lcast_char_constants<char16_t>::lowercase_e;
BOOST_CHECK_EQUAL(u'e', c);
BOOST_TEST(u'e' == c);
c = boost::detail::lcast_char_constants<char16_t>::capital_e;
BOOST_CHECK_EQUAL(u'E', c);
BOOST_TEST(u'E' == c);
c = boost::detail::lcast_char_constants<char16_t>::c_decimal_separator;
BOOST_CHECK_EQUAL(u'.', c);
BOOST_TEST(u'.' == c);
#endif
BOOST_CHECK(true);
BOOST_TEST(true);
}
void test_char_types_conversions_char32_t()
@@ -104,34 +100,32 @@ void test_char_types_conversions_char32_t()
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS) && defined(BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES)
test_impl(U"Test array of chars");
char32_t c = boost::detail::lcast_char_constants<char32_t>::zero;
BOOST_CHECK_EQUAL(U'0', c);
BOOST_TEST(U'0' == c);
c = boost::detail::lcast_char_constants<char32_t>::minus;
BOOST_CHECK_EQUAL(U'-', c);
BOOST_TEST(U'-' == c);
c = boost::detail::lcast_char_constants<char32_t>::plus;
BOOST_CHECK_EQUAL(U'+', c);
BOOST_TEST(U'+' == c);
c = boost::detail::lcast_char_constants<char32_t>::lowercase_e;
BOOST_CHECK_EQUAL(U'e', c);
BOOST_TEST(U'e' == c);
c = boost::detail::lcast_char_constants<char32_t>::capital_e;
BOOST_CHECK_EQUAL(U'E', c);
BOOST_TEST(U'E', == c);
c = boost::detail::lcast_char_constants<char32_t>::c_decimal_separator;
BOOST_CHECK_EQUAL(U'.', c);
BOOST_TEST(U'.' == c);
#endif
BOOST_CHECK(true);
BOOST_TEST(true);
}
unit_test::test_suite *init_unit_test_suite(int, char *[])
int main()
{
unit_test::test_suite *suite =
BOOST_TEST_SUITE("lexical_cast char => wide characters unit test (widening test)");
suite->add(BOOST_TEST_CASE(&test_char_types_conversions_wchar_t));
suite->add(BOOST_TEST_CASE(&test_char_types_conversions_char16_t));
suite->add(BOOST_TEST_CASE(&test_char_types_conversions_char32_t));
test_char_types_conversions_wchar_t();
test_char_types_conversions_char16_t();
test_char_types_conversions_char32_t();
return suite;
return boost::report_errors();
}