From f8f0834c544113cec21e7cf5a2a548b81ca02989 Mon Sep 17 00:00:00 2001 From: Dmitry Arkhipov Date: Tue, 11 Jul 2023 17:27:11 +0300 Subject: [PATCH] temp --- CMakeLists.txt | 1 + include/boost/json/basic_parser_impl.hpp | 7 +++-- .../detail/fast_float/ascii_number.hpp | 14 ++------- include/boost/json/detail/config.hpp | 19 +----------- include/boost/json/detail/sse2.hpp | 9 ++---- include/boost/json/detail/utf8.hpp | 31 ++++++------------- test/utf8.cpp | 31 ------------------- 7 files changed, 20 insertions(+), 92 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95ae6c77a..4e65fcb00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ function(boost_json_setup_properties target) Boost::container Boost::core Boost::describe + Boost::endian Boost::mp11 Boost::system Boost::throw_exception diff --git a/include/boost/json/basic_parser_impl.hpp b/include/boost/json/basic_parser_impl.hpp index f4cb1e1ca..754e992f3 100644 --- a/include/boost/json/basic_parser_impl.hpp +++ b/include/boost/json/basic_parser_impl.hpp @@ -1303,8 +1303,8 @@ parse_escaped( { // KRYSTIAN TODO: this could be done // with fewer instructions - digit = detail::load_little_endian<4>( - cs.begin() + 1); + digit = endian::endian_load( + reinterpret_cast(cs.begin() + 1) ); int d4 = detail::hex_digit(static_cast< unsigned char>(digit >> 24)); int d3 = detail::hex_digit(static_cast< @@ -1366,7 +1366,8 @@ parse_escaped( return fail(cs.begin(), error::syntax, &loc); } ++cs; - digit = detail::load_little_endian<4>(cs.begin()); + digit = endian::endian_load( + reinterpret_cast(cs.begin()) ); d4 = detail::hex_digit(static_cast< unsigned char>(digit >> 24)); d3 = detail::hex_digit(static_cast< diff --git a/include/boost/json/detail/charconv/detail/fast_float/ascii_number.hpp b/include/boost/json/detail/charconv/detail/fast_float/ascii_number.hpp index bec6402d4..a36707723 100644 --- a/include/boost/json/detail/charconv/detail/fast_float/ascii_number.hpp +++ b/include/boost/json/detail/charconv/detail/fast_float/ascii_number.hpp @@ -44,12 +44,8 @@ uint64_t read_u64(const char *chars) { } return val; } - uint64_t val; - ::memcpy(&val, chars, sizeof(uint64_t)); -#ifdef BOOST_JSON_BIG_ENDIAN - // Need to read as-if the number was in little-endian order. - val = byteswap(val); -#endif + uint64_t val = endian::load_little_u64( + reinterpret_cast(chars) ); return val; } @@ -63,11 +59,7 @@ void write_u64(uint8_t *chars, uint64_t val) { } return; } -#ifdef BOOST_JSON_BIG_ENDIAN - // Need to read as-if the number was in little-endian order. - val = byteswap(val); -#endif - ::memcpy(chars, &val, sizeof(uint64_t)); + endian::store_little_u64( reinterpret_cast(chars), val ); } // credit @aqrit diff --git a/include/boost/json/detail/config.hpp b/include/boost/json/detail/config.hpp index b5390e297..8bffef35f 100644 --- a/include/boost/json/detail/config.hpp +++ b/include/boost/json/detail/config.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -244,24 +245,6 @@ # endif #endif - -#if ! defined(BOOST_JSON_BIG_ENDIAN) && ! defined(BOOST_JSON_LITTLE_ENDIAN) -// Copied from Boost.Endian -# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define BOOST_JSON_LITTLE_ENDIAN -# elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define BOOST_JSON_BIG_ENDIAN -# elif defined(__LITTLE_ENDIAN__) -# define BOOST_JSON_LITTLE_ENDIAN -# elif defined(__BIG_ENDIAN__) -# define BOOST_JSON_BIG_ENDIAN -# elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__) -# define BOOST_JSON_LITTLE_ENDIAN -# else -# error The Boost.JSON library could not determine the endianness of this platform. Define either BOOST_JSON_BIG_ENDIAN or BOOST_JSON_LITTLE_ENDIAN. -# endif -#endif - #if defined(__cpp_constinit) && __cpp_constinit >= 201907L # define BOOST_JSON_CONSTINIT constinit #elif defined(__has_cpp_attribute) && defined(__clang__) diff --git a/include/boost/json/detail/sse2.hpp b/include/boost/json/detail/sse2.hpp index d8d88f5ce..20fc10f2b 100644 --- a/include/boost/json/detail/sse2.hpp +++ b/include/boost/json/detail/sse2.hpp @@ -325,9 +325,8 @@ inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noex r = r * 10 + p[2] - '0'; r = r * 10 + p[3] - '0'; #else - uint32_t v; - std::memcpy( &v, p, 4 ); - + uint32_t v = endian::load_little_u32( + reinterpret_cast(p) ); v -= 0x30303030; unsigned w0 = v & 0xFF; @@ -335,11 +334,7 @@ inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noex unsigned w2 = (v >> 16) & 0xFF; unsigned w3 = (v >> 24); -#ifdef BOOST_JSON_BIG_ENDIAN - r = (((r * 10 + w3) * 10 + w2) * 10 + w1) * 10 + w0; -#else r = (((r * 10 + w0) * 10 + w1) * 10 + w2) * 10 + w3; -#endif #endif p += 4; n -= 4; diff --git a/include/boost/json/detail/utf8.hpp b/include/boost/json/detail/utf8.hpp index e3ed2cad2..ba34ec118 100644 --- a/include/boost/json/detail/utf8.hpp +++ b/include/boost/json/detail/utf8.hpp @@ -20,21 +20,6 @@ namespace boost { namespace json { namespace detail { -template -std::uint32_t -load_little_endian(void const* p) -{ - std::uint32_t v = 0; - std::memcpy(&v, p, N); -#ifdef BOOST_JSON_BIG_ENDIAN - v = ((v & 0xFF000000) >> 24) | - ((v & 0x00FF0000) >> 8) | - ((v & 0x0000FF00) << 8) | - ((v & 0x000000FF) << 24); -#endif - return v; -} - inline uint16_t classify_utf8(char c) @@ -74,6 +59,8 @@ inline bool is_valid_utf8(const char* p, uint16_t first) { + auto const up = reinterpret_cast(p); + uint32_t v; switch(first >> 8) { @@ -82,37 +69,37 @@ is_valid_utf8(const char* p, uint16_t first) // 2 bytes, second byte [80, BF] case 1: - v = load_little_endian<2>(p); + v = endian::endian_load(up); return (v & 0xC000) == 0x8000; // 3 bytes, second byte [A0, BF] case 2: - v = load_little_endian<3>(p); + v = endian::endian_load(up); return (v & 0xC0E000) == 0x80A000; // 3 bytes, second byte [80, BF] case 3: - v = load_little_endian<3>(p); + v = endian::endian_load(up); return (v & 0xC0C000) == 0x808000; // 3 bytes, second byte [80, 9F] case 4: - v = load_little_endian<3>(p); + v = endian::endian_load(up); return (v & 0xC0E000) == 0x808000; // 4 bytes, second byte [90, BF] case 5: - v = load_little_endian<4>(p); + v = endian::endian_load(up); return (v & 0xC0C0FF00) + 0x7F7F7000 <= 0x2F00; // 4 bytes, second byte [80, BF] case 6: - v = load_little_endian<4>(p); + v = endian::endian_load(up); return (v & 0xC0C0C000) == 0x80808000; // 4 bytes, second byte [80, 8F] case 7: - v = load_little_endian<4>(p); + v = endian::endian_load(up); return (v & 0xC0C0F000) == 0x80808000; } } diff --git a/test/utf8.cpp b/test/utf8.cpp index d16943cca..e94a58035 100644 --- a/test/utf8.cpp +++ b/test/utf8.cpp @@ -18,36 +18,6 @@ namespace json { class utf8_test { public: - void - testLoadLittleEndian() - { - BOOST_TEST( - detail::load_little_endian<4>("\x01\x02\x03\x04\xFF") - == 0x04030201); - - BOOST_TEST( - detail::load_little_endian<4>("\x12\x34\x56\x78\xFF") - == 0x78563412); - - BOOST_TEST( - detail::load_little_endian<4>("\xFE\xDC\xBA\x98\xFF") - == 0x98BADCFE); - - BOOST_TEST( - detail::load_little_endian<3>("\x12\x45\xFE\xFF") - == 0x00FE4512); - - BOOST_TEST( - detail::load_little_endian<3>("\xE0\xA0\x80\xFF") - == 0x0080A0E0); - - BOOST_TEST( - detail::load_little_endian<2>("\x37\xFC\xFF") - == 0x0000FC37); - - BOOST_TEST(detail::load_little_endian<1>("\xF1\xFF") == 0x000000F1); - } - void testClassifyUtf8() { @@ -166,7 +136,6 @@ class utf8_test void run() { - testLoadLittleEndian(); testClassifyUtf8(); testIsValidUtf8(); testUtf8Sequence();