From 6b84c4155c3d61cbda2a6f1f002f482eebccc78e Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 8 Dec 2016 09:37:23 +0100 Subject: [PATCH] :hammer: refactored get_from_vector function Snippet from http://stackoverflow.com/a/41031865/266378 --- src/json.hpp | 65 +++++++++++++++++++++++++---------------------- src/json.hpp.re2c | 57 ++++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 59 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index a6e5e44e..1fd3b916 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6262,36 +6262,35 @@ class basic_json } } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) + /* + Precondition: + + vec: | | | a | b | c | d | | | T: | | | | | + ^ ^ ^ ^ + current_index idx ptr sizeof(T) + + + Postcondition: + + vec: | | | a | b | c | d | | | T: | d | c | b | a | + ^ ^ ^ + | idx ptr + current_index + + + Code from + */ + template + static T get_from_vector(const std::vector& vec, const size_t current_index) { - return static_cast(vec[current_idx + 1]); - } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) - { - return static_cast((static_cast(vec[current_idx + 1]) << 010) + - static_cast(vec[current_idx + 2])); - } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) - { - return static_cast((static_cast(vec[current_idx + 1]) << 030) + - (static_cast(vec[current_idx + 2]) << 020) + - (static_cast(vec[current_idx + 3]) << 010) + - static_cast(vec[current_idx + 4])); - } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) - { - return static_cast((static_cast(vec[current_idx + 1]) << 070) + - (static_cast(vec[current_idx + 2]) << 060) + - (static_cast(vec[current_idx + 3]) << 050) + - (static_cast(vec[current_idx + 4]) << 040) + - (static_cast(vec[current_idx + 5]) << 030) + - (static_cast(vec[current_idx + 6]) << 020) + - (static_cast(vec[current_idx + 7]) << 010) + - static_cast(vec[current_idx + 8])); + T result; + uint8_t* ptr = reinterpret_cast(&result); + size_t idx = current_index + 1 + sizeof(T); + while (idx > current_index) + { + *ptr++ = vec[--idx]; + } + return result; } static void to_msgpack_internal(const basic_json& j, std::vector& v) @@ -7173,7 +7172,13 @@ class basic_json { idx += 2; // skip two content bytes - // code from RFC 7049, Appendix D + // code from RFC 7049, Appendix D, Figure 3: + // As half-precision floating-point numbers were only added to IEEE + // 754 in 2008, today's programming platforms often still only have + // limited support for them. It is very easy to include at least + // decoding support for them even without such support. An example + // of a small decoder for half-precision floating-point numbers in + // the C language is shown in Figure 3. const int half = (v[current_idx + 1] << 8) + v[current_idx + 2]; const int exp = (half >> 10) & 0x1f; const int mant = half & 0x3ff; diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 95a5027e..4859d946 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -6262,36 +6262,35 @@ class basic_json } } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) + /* + Precondition: + + vec: | | | a | b | c | d | | | T: | | | | | + ^ ^ ^ ^ + current_index idx ptr sizeof(T) + + + Postcondition: + + vec: | | | a | b | c | d | | | T: | d | c | b | a | + ^ ^ ^ + | idx ptr + current_index + + + Code from + */ + template + static T get_from_vector(const std::vector& vec, const size_t current_index) { - return static_cast(vec[current_idx + 1]); - } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) - { - return static_cast((static_cast(vec[current_idx + 1]) << 010) + - static_cast(vec[current_idx + 2])); - } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) - { - return static_cast((static_cast(vec[current_idx + 1]) << 030) + - (static_cast(vec[current_idx + 2]) << 020) + - (static_cast(vec[current_idx + 3]) << 010) + - static_cast(vec[current_idx + 4])); - } - template::type = 0> - static constexpr T get_from_vector(const std::vector& vec, const size_t current_idx) - { - return static_cast((static_cast(vec[current_idx + 1]) << 070) + - (static_cast(vec[current_idx + 2]) << 060) + - (static_cast(vec[current_idx + 3]) << 050) + - (static_cast(vec[current_idx + 4]) << 040) + - (static_cast(vec[current_idx + 5]) << 030) + - (static_cast(vec[current_idx + 6]) << 020) + - (static_cast(vec[current_idx + 7]) << 010) + - static_cast(vec[current_idx + 8])); + T result; + uint8_t* ptr = reinterpret_cast(&result); + size_t idx = current_index + 1 + sizeof(T); + while (idx > current_index) + { + *ptr++ = vec[--idx]; + } + return result; } static void to_msgpack_internal(const basic_json& j, std::vector& v)