Skip to content

Commit

Permalink
Merge pull request #95 from cppalliance/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
mborland authored Oct 27, 2023
2 parents 9188199 + 0ff29f5 commit 0005843
Show file tree
Hide file tree
Showing 36 changed files with 547 additions and 242 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,31 +192,31 @@ jobs:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20,2b"
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20,2b"
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-14
- toolset: clang
compiler: clang++-14
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu,2b-gnu"
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu"
os: ubuntu-22.04
install:
- clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-15
Expand Down
41 changes: 25 additions & 16 deletions doc/charconv/benchmarks.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ Larger numbers are more performant (e.g. 2.00 means twice as fast, and 0.50 mean
== How to run the Benchmarks

To run the benchmarks yourself, navigate to the test folder and define `BOOST_CHARCONV_RUN_BENCHMARKS` when running the tests.
An example on Linux with b2: `../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_CHARCONV_RUN_BENCHMARKS STL_benchmark -a release` .
An example on Linux with b2: `../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_CHARCONV_RUN_BENCHMARKS STL_benchmark linkflags="-lfmt" -a release` .

Additionally, you will need the following:

* A compiler with full `<charconv>` support:
** GCC 11 or newer
** MSVC 19.24 or newer
* https://github.com/google/double-conversion[libdouble-conversion]
* https://github.com/fmtlib/fmt[{fmt}]

== x86_64 Linux

Expand All @@ -35,15 +36,17 @@ Data in tables 1 - 4 were run on Ubuntu 23.04 with x86_64 architecture using GCC
|std::printf
|1.00 / 1.00
|Boost.lexical_cast
|0.55 / 0.46
|0.56 / 0.49
|Boost.spirit.karma
|1.80 / 2.62
|1.70 / 2.62
|std::to_chars
|3.53 / 4.87
|4.01 / 6.03
|Boost.Charconv.to_chars
|3.64 / 4.92
|4.46 / 6.20
|Google double-conversion
|1.19 / 1.85
|1.26 / 1.91
|{fmt}
|2.52 / 3.63
|===

.from_chars floating point with scientific formatting
Expand Down Expand Up @@ -73,13 +76,15 @@ Data in tables 1 - 4 were run on Ubuntu 23.04 with x86_64 architecture using GCC
|std::printf
|1.00 / 1.00
|Boost.lexical_cast
|1.77 / 1.41
|1.80 / 1.38
|Boost.spirit.karma
|2.55 / 1.47
|2.81 / 1.62
|std::to_chars
|3.86 / 2.25
|4.06 / 2.45
|Boost.Charconv.to_chars
|3.81 / 2.25
|4.13 / 2.48
|{fmt}
|2.88 / 2.21
|===

.from_chars base 10 integers
Expand Down Expand Up @@ -172,7 +177,7 @@ Data in tables 5 - 8 were run on Windows 11 with x86_64 architecture using MSVC

== ARM MacOS

Data in tables 9-12 were run on MacOS Ventura 13.5 with M1 Pro architecture using Homebrew GCC 13.1.0 with libstdc++.
Data in tables 9-12 were run on MacOS Ventura 13.5.2 with M1 Pro architecture using Homebrew GCC 13.2.0 with libstdc++.

=== Floating Point

Expand All @@ -183,15 +188,17 @@ Data in tables 9-12 were run on MacOS Ventura 13.5 with M1 Pro architecture usin
|std::printf
|1.00 / 1.00
|Boost.lexical_cast
|0.52 / 0.12
|0.58 / 0.16
|Boost.spirit.karma
|1.40 / 1.40
|1.39 / 1.22
|std::to_chars
|3.01 / 2.96
|6.78 / 6.47
|Boost.Charconv.to_chars
|3.03 / 2.96
|7.25 / 6.86
|Google double-conversion
|1.22 / 1.16
|2.26 / 2.16
|{fmt}
|3.78 / 3.38
|===

.from_chars floating point with scientific formatting
Expand Down Expand Up @@ -229,6 +236,8 @@ Data in tables 9-12 were run on MacOS Ventura 13.5 with M1 Pro architecture usin
|6.25 / 4.12
|Boost.Charconv.to_chars
|6.25 / 4.12
|{fmt}
|5.29 / 3.47
|===

.from_chars base 10 integers
Expand Down
6 changes: 3 additions & 3 deletions doc/charconv/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ This library requires a minimum of C++11.
const char* buffer = "42";
int v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
boost::charconv::from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(v == 42);
char buffer[64];
int v = 123456;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
boost::charconv:to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc());
assert(!strncmp(buffer, "123456", 6)); // Strncmp returns 0 on match
Expand All @@ -46,4 +46,4 @@ Tested on https://github.com/cppalliance/charconv/actions[Github Actions] and ht
Currently only https://en.cppreference.com/w/cpp/compiler_support/17[GCC 11+ and MSVC 19.24+] support both integer and floating-point conversions in their implementation of `<charconv>`. +

If you are using either of those compilers, Boost.Charconv is at least as performant as `<charconv>`, and can be up to several times faster.
See: <<Benchmarks>>
See: <<Benchmarks>>
19 changes: 16 additions & 3 deletions include/boost/charconv/detail/apply_sign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,32 @@
#define BOOST_CHARCONV_DETAIL_APPLY_SIGN_HPP

#include <boost/config.hpp>
#include <boost/charconv/detail/emulated128.hpp>
#include <boost/charconv/detail/type_traits.hpp>
#include <type_traits>

// We are purposefully converting values here
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4146)
#elif defined(__GNUC__) && __GNUC__ >= 5
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wconversion"
#elif defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wconversion"
#endif

namespace boost { namespace charconv { namespace detail {

template <typename Integer, typename Unsigned_Integer = typename std::make_unsigned<Integer>::type,
typename std::enable_if<std::is_signed<Integer>::value, bool>::type = true>
template <typename Integer, typename Unsigned_Integer = detail::make_unsigned_t<Integer>,
typename std::enable_if<detail::is_signed<Integer>::value, bool>::type = true>
constexpr Unsigned_Integer apply_sign(Integer val) noexcept
{
return -(static_cast<Unsigned_Integer>(val));
}

template <typename Unsigned_Integer, typename std::enable_if<std::is_unsigned<Unsigned_Integer>::value, bool>::type = true>
template <typename Unsigned_Integer, typename std::enable_if<!detail::is_signed<Unsigned_Integer>::value, bool>::type = true>
constexpr Unsigned_Integer apply_sign(Unsigned_Integer val) noexcept
{
return val;
Expand All @@ -32,6 +41,10 @@ constexpr Unsigned_Integer apply_sign(Unsigned_Integer val) noexcept

#ifdef BOOST_MSVC
# pragma warning(pop)
#elif defined(__GNUC__) && __GNUC__ >= 5
# pragma GCC diagnostic pop
#elif defined(__clang__)
# pragma clang diagnostic pop
#endif

#endif // BOOST_CHARCONV_DETAIL_APPLY_SIGN_HPP
12 changes: 6 additions & 6 deletions include/boost/charconv/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
# define BOOST_CHARCONV_DEBUG_ASSERT(expr)
#endif

// Use 128 bit integers and supress warnings for using extensions
// Use 128-bit integers and suppress warnings for using extensions
#if defined(BOOST_HAS_INT128)
# define BOOST_CHARCONV_HAS_INT128
# define BOOST_CHARCONV_INT128_MAX (boost::int128_type)(((boost::uint128_type) 1 << 127) - 1)
# define BOOST_CHARCONV_INT128_MAX static_cast<boost::int128_type>((static_cast<boost::uint128_type>(1) << 127) - 1)
# define BOOST_CHARCONV_INT128_MIN (-BOOST_CHARCONV_INT128_MAX - 1)
# define BOOST_CHARCONV_UINT128_MAX ((2 * (boost::uint128_type) BOOST_CHARCONV_INT128_MAX) + 1)
# define BOOST_CHARCONV_UINT128_MAX (2 * static_cast<boost::uint128_type>(BOOST_CHARCONV_INT128_MAX) + 1)
#endif

#if defined(BOOST_HAS_FLOAT128) && !defined(__STRICT_ANSI__) && !defined(BOOST_CHARCONV_CMAKE_TESTING)
Expand Down Expand Up @@ -110,7 +110,7 @@ static_assert((BOOST_CHARCONV_ENDIAN_BIG_BYTE || BOOST_CHARCONV_ENDIAN_LITTLE_BY
#endif

// Workaround for errors in MSVC 14.3 with gotos in if constexpr blocks
#if BOOST_MSVC == 1933 || BOOST_MSVC == 1934
#if defined(BOOST_MSVC) && (BOOST_MSVC == 1933 || BOOST_MSVC == 1934)
# define BOOST_CHARCONV_IF_CONSTEXPR if
#else
# define BOOST_CHARCONV_IF_CONSTEXPR BOOST_IF_CONSTEXPR
Expand Down Expand Up @@ -146,15 +146,15 @@ static_assert((BOOST_CHARCONV_ENDIAN_BIG_BYTE || BOOST_CHARCONV_ENDIAN_LITTLE_BY
//
// As does GCC-9:
//
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9) && !defined(BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED)
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(__GNUC__) && (__GNUC__ >= 9) && !defined(BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED)
# define BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED
#endif

#if defined(BOOST_CHARCONV_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR)
# define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) std::is_constant_evaluated()
#elif defined(BOOST_CHARCONV_HAS_BUILTIN_IS_CONSTANT_EVALUATED)
# define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) __builtin_is_constant_evaluated()
#elif !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 6)
#elif !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(__GNUC__) && (__GNUC__ >= 6)
# define BOOST_CHARCONV_IS_CONSTANT_EVALUATED(x) __builtin_constant_p(x)
# define BOOST_CHARCONV_USING_BUILTIN_CONSTANT_P
#else
Expand Down
12 changes: 6 additions & 6 deletions include/boost/charconv/detail/dragonbox/dragonbox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ using signed_decimal_fp = decimal_fp<UInt, true, false>;
// Computed cache entries.
////////////////////////////////////////////////////////////////////////////////////////

#if BOOST_MSVC != 1900
#if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
template <bool b>
struct cache_holder_ieee754_binary32_impl
#else
Expand Down Expand Up @@ -519,7 +519,7 @@ struct cache_holder_ieee754_binary32
0xb35dbf821ae4f38c, 0xe0352f62a19e306f};
};

#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && BOOST_MSVC != 1900
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)

template <bool b> constexpr int cache_holder_ieee754_binary32_impl<b>::cache_bits;
template <bool b> constexpr int cache_holder_ieee754_binary32_impl<b>::min_k;
Expand All @@ -528,11 +528,11 @@ template <bool b> constexpr typename cache_holder_ieee754_binary32_impl<b>::cach

#endif

#if BOOST_MSVC != 1900
#if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
using cache_holder_ieee754_binary32 = cache_holder_ieee754_binary32_impl<true>;
#endif

#if BOOST_MSVC != 1900
#if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
template <bool b>
struct cache_holder_ieee754_binary64_impl
#else
Expand Down Expand Up @@ -856,7 +856,7 @@ struct cache_holder_ieee754_binary64
{0xf70867153aa2db38, 0xb8cbee4fc66d1ea8}};
};

#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && BOOST_MSVC != 1900
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)

template <bool b> constexpr int cache_holder_ieee754_binary64_impl<b>::cache_bits;
template <bool b> constexpr int cache_holder_ieee754_binary64_impl<b>::min_k;
Expand All @@ -865,7 +865,7 @@ template <bool b> constexpr typename cache_holder_ieee754_binary64_impl<b>::cach

#endif

#if BOOST_MSVC != 1900
#if (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)
using cache_holder_ieee754_binary64 = cache_holder_ieee754_binary64_impl<true>;
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ struct main_cache_holder_impl
{0xf70867153aa2db38, 0xb8cbee4fc66d1ea8}};
};

#if (defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (BOOST_MSVC != 1900)) || \
#if (defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)) || \
(defined(__clang_major__) && __clang_major__ == 5)

template <bool b> constexpr int main_cache_holder_impl<b>::cache_bits;
Expand Down
4 changes: 2 additions & 2 deletions include/boost/charconv/detail/dragonbox/floff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ struct additional_static_data_holder_impl
};
};

#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (BOOST_MSVC != 1900)
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)

template <bool b> constexpr char additional_static_data_holder_impl<b>::radix_100_table[];
template <bool b> constexpr std::uint32_t additional_static_data_holder_impl<b>::fractional_part_rounding_thresholds32[];
Expand Down Expand Up @@ -1010,7 +1010,7 @@ struct extended_cache_long_impl
{27245, 29296}, {27294, 29344}, {27320, 29370}, {27324, 0}};
};

#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (BOOST_MSVC != 1900)
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES) && (!defined(BOOST_MSVC) || BOOST_MSVC != 1900)

template <bool b> constexpr std::size_t extended_cache_long_impl<b>::max_cache_blocks;
template <bool b> constexpr std::size_t extended_cache_long_impl<b>::cache_bits_unit;
Expand Down
14 changes: 12 additions & 2 deletions include/boost/charconv/detail/from_chars_float_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <boost/charconv/detail/parser.hpp>
#include <boost/charconv/detail/compute_float32.hpp>
#include <boost/charconv/detail/compute_float64.hpp>
#include <boost/charconv/detail/bit_layouts.hpp>
#include <boost/charconv/chars_format.hpp>
#include <system_error>
#include <cstdlib>
Expand All @@ -21,9 +22,16 @@ namespace boost { namespace charconv { namespace detail {
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4244) // Implict converion when BOOST_IF_CONSTEXPR expands to if
#elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
#elif defined(__GNUC__) && __GNUC__ >= 5
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
# pragma GCC diagnostic ignored "-Wfloat-conversion"
#elif defined(__clang__) && __clang_major__ > 7
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wimplicit-float-conversion"
#elif defined(__clang__) && __clang_major__ <= 7
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wconversion"
#endif

template <typename T>
Expand Down Expand Up @@ -239,8 +247,10 @@ from_chars_result from_chars_float_impl(const char* first, const char* last, T&

#ifdef BOOST_MSVC
# pragma warning(pop)
#elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
#elif defined(__GNUC__) && __GNUC__ >= 5
# pragma GCC diagnostic pop
#elif defined(__clang__)
# pragma clang diagnostic pop
#endif

}}} // Namespace boost::charconv::detail
Expand Down
Loading

0 comments on commit 0005843

Please sign in to comment.