From daf2d296ddf3b6574abd682fe61a0af19a7a7c63 Mon Sep 17 00:00:00 2001
From: Niels Lohmann <mail@nlohmann.me>
Date: Fri, 15 May 2020 14:12:32 +0200
Subject: [PATCH] :recycle: move wrapped binary type to separate file

---
 .../nlohmann/detail/conversions/from_json.hpp |  13 +-
 .../nlohmann/detail/conversions/to_json.hpp   |  14 +-
 include/nlohmann/detail/input/json_sax.hpp    |   4 -
 include/nlohmann/detail/wrapped_binary_t.hpp  |  52 +++++++
 include/nlohmann/json.hpp                     |  62 +-------
 single_include/nlohmann/json.hpp              | 146 ++++++++++--------
 test/src/unit-constructor1.cpp                |  17 ++
 test/src/unit-pointer_access.cpp              |  38 ++---
 8 files changed, 192 insertions(+), 154 deletions(-)
 create mode 100644 include/nlohmann/detail/wrapped_binary_t.hpp

diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp
index c389dca7..53eb40e3 100644
--- a/include/nlohmann/detail/conversions/from_json.hpp
+++ b/include/nlohmann/detail/conversions/from_json.hpp
@@ -228,9 +228,9 @@ template <typename BasicJsonType, typename ConstructibleArrayType,
               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
               not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
               not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
+              not std::is_same<ConstructibleArrayType, typename BasicJsonType::internal_binary_t>::value and
               not is_basic_json<ConstructibleArrayType>::value,
               int > = 0 >
-
 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
 j.template get<typename ConstructibleArrayType::value_type>(),
@@ -245,6 +245,17 @@ void())
     from_json_array_impl(j, arr, priority_tag<3> {});
 }
 
+template <typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::internal_binary_t& bin)
+{
+    if (JSON_HEDLEY_UNLIKELY(not j.is_binary()))
+    {
+        JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
+    }
+
+    bin = *j.template get_ptr<const typename BasicJsonType::internal_binary_t*>();
+}
+
 template<typename BasicJsonType, typename ConstructibleObjectType,
          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp
index 10b21d16..0a087c22 100644
--- a/include/nlohmann/detail/conversions/to_json.hpp
+++ b/include/nlohmann/detail/conversions/to_json.hpp
@@ -71,7 +71,7 @@ template<>
 struct external_constructor<value_t::binary>
 {
     template<typename BasicJsonType>
-    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
+    static void construct(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& b)
     {
         j.m_type = value_t::binary;
         typename BasicJsonType::internal_binary_t value{b};
@@ -80,7 +80,7 @@ struct external_constructor<value_t::binary>
     }
 
     template<typename BasicJsonType>
-    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
+    static void construct(BasicJsonType& j, typename BasicJsonType::internal_binary_t&& b)
     {
         j.m_type = value_t::binary;
         typename BasicJsonType::internal_binary_t value{std::move(b)};
@@ -278,9 +278,9 @@ void to_json(BasicJsonType& j, const std::vector<bool>& e)
 template <typename BasicJsonType, typename CompatibleArrayType,
           enable_if_t<is_compatible_array_type<BasicJsonType,
                       CompatibleArrayType>::value and
-                      not is_compatible_object_type<
-                          BasicJsonType, CompatibleArrayType>::value and
+                      not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
                       not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
+                      not std::is_same<typename BasicJsonType::internal_binary_t, CompatibleArrayType>::value and
                       not is_basic_json<CompatibleArrayType>::value,
                       int> = 0>
 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
@@ -288,6 +288,12 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
     external_constructor<value_t::array>::construct(j, arr);
 }
 
+template <typename BasicJsonType>
+void to_json(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& bin)
+{
+    external_constructor<value_t::binary>::construct(j, bin);
+}
+
 template<typename BasicJsonType, typename T,
          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp
index c54b80df..ac41e6bb 100644
--- a/include/nlohmann/detail/input/json_sax.hpp
+++ b/include/nlohmann/detail/input/json_sax.hpp
@@ -23,13 +23,9 @@ input.
 template<typename BasicJsonType>
 struct json_sax
 {
-    /// type for (signed) integers
     using number_integer_t = typename BasicJsonType::number_integer_t;
-    /// type for unsigned integers
     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-    /// type for floating-point numbers
     using number_float_t = typename BasicJsonType::number_float_t;
-    /// type for strings
     using string_t = typename BasicJsonType::string_t;
     using binary_t = typename BasicJsonType::binary_t;
 
diff --git a/include/nlohmann/detail/wrapped_binary_t.hpp b/include/nlohmann/detail/wrapped_binary_t.hpp
new file mode 100644
index 00000000..f0ccba27
--- /dev/null
+++ b/include/nlohmann/detail/wrapped_binary_t.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <cstdint> // uint8_t
+#include <utility> // move
+
+namespace nlohmann
+{
+namespace detail
+{
+
+/*!
+@brief an internal type for a backed binary type
+
+This type is designed to be `binary_t` but with the subtype implementation
+detail.  This type exists so that the user does not have to specify a struct
+his- or herself with a specific naming scheme in order to override the
+binary type.  I.e. it's for ease of use.
+*/
+template<typename BinaryType>
+struct wrapped_binary_t : public BinaryType
+{
+    using binary_t = BinaryType;
+
+    wrapped_binary_t() noexcept(noexcept(binary_t())) = default;
+
+    wrapped_binary_t(const binary_t& bint) noexcept(noexcept(binary_t(bint)))
+        : binary_t(bint)
+    {}
+
+    wrapped_binary_t(binary_t&& bint) noexcept(noexcept(binary_t(std::move(bint))))
+        : binary_t(std::move(bint))
+    {}
+
+    wrapped_binary_t(const binary_t& bint,
+                     std::uint8_t st) noexcept(noexcept(binary_t(bint)))
+        : binary_t(bint)
+        , subtype(st)
+        , has_subtype(true)
+    {}
+
+    wrapped_binary_t(binary_t&& bint, std::uint8_t st) noexcept(noexcept(binary_t(std::move(bint))))
+        : binary_t(std::move(bint))
+        , subtype(st)
+        , has_subtype(true)
+    {}
+
+    std::uint8_t subtype = 0;
+    bool has_subtype = false;
+};
+
+}  // namespace detail
+}  // namespace nlohmann
diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index b72ea58d..e9650165 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -70,6 +70,7 @@ SOFTWARE.
 #include <nlohmann/detail/output/output_adapters.hpp>
 #include <nlohmann/detail/output/serializer.hpp>
 #include <nlohmann/detail/value_t.hpp>
+#include <nlohmann/detail/wrapped_binary_t.hpp>
 #include <nlohmann/json_fwd.hpp>
 
 /*!
@@ -839,7 +840,7 @@ class basic_json
     This type is a type designed to carry binary data that appears in various
     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
     BSON's generic binary subtype.  This type is NOT a part of standard JSON and
-    exists solely for compatibility with these binary types.  As such, it is
+    exists solely for compatibility with these binary types. As such, it is
     simply defined as an ordered sequence of zero or more byte values.
 
     Additionally, as an implementation detail, the subtype of the binary data is
@@ -850,9 +851,8 @@ class basic_json
 
     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
     as:
-    > Major type 2:  a byte string.  The string's length in bytes is
-    > represented following the rules for positive integers (major type
-    > 0).
+    > Major type 2: a byte string. The string's length in bytes is represented
+    > following the rules for positive integers (major type 0).
 
     [MessagePack's documentation on the bin type
     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
@@ -868,7 +868,7 @@ class basic_json
 
     None of these impose any limitations on the internal representation other
     than the basic unit of storage be some type of array whose parts are
-    decomposible into bytes.
+    decomposable into bytes.
 
     The default representation of this binary format is a
     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
@@ -880,7 +880,7 @@ class basic_json
 
     #### Storage
 
-    Binary Arrays are stored as pointers in a @ref basic_json type.  That is,
+    Binary Arrays are stored as pointers in a @ref basic_json type. That is,
     for any access to array values, a pointer of the type `binary_t*` must be
     dereferenced.
 
@@ -890,43 +890,7 @@ class basic_json
     */
     using binary_t = BinaryType;
 
-    /*!
-    @brief an internal type for a backed binary type
-
-    This type is designed to be `binary_t` but with the subtype implementation
-    detail.  This type exists so that the user does not have to specify a struct
-    his- or herself with a specific naming scheme in order to override the
-    binary type.  I.e. it's for ease of use.
-    */
-    struct internal_binary_t : public BinaryType
-    {
-        using BinaryType::BinaryType;
-        internal_binary_t() noexcept(noexcept(BinaryType()))
-            : BinaryType()
-        {}
-        internal_binary_t(const BinaryType& bint) noexcept(noexcept(BinaryType(bint)))
-            : BinaryType(bint)
-        {}
-        internal_binary_t(BinaryType&& bint) noexcept(noexcept(BinaryType(std::move(bint))))
-            : BinaryType(std::move(bint))
-        {}
-        internal_binary_t(const BinaryType& bint, std::uint8_t st) noexcept(noexcept(BinaryType(bint)))
-            : BinaryType(bint)
-            , subtype(st)
-            , has_subtype(true)
-        {}
-        internal_binary_t(BinaryType&& bint, std::uint8_t st) noexcept(noexcept(BinaryType(std::move(bint))))
-            : BinaryType(std::move(bint))
-            , subtype(st)
-            , has_subtype(true)
-        {}
-
-        // TOOD: If minimum C++ version is ever bumped to C++17, this field
-        // deserves to be a std::optional
-        std::uint8_t subtype = 0;
-        bool has_subtype = false;
-    };
-
+    using internal_binary_t = nlohmann::detail::wrapped_binary_t<BinaryType>;
     /// @}
 
   private:
@@ -2802,18 +2766,6 @@ class basic_json
         return is_number_float() ? &m_value.number_float : nullptr;
     }
 
-    /// get a pointer to the value (binary)
-    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
-    {
-        return is_binary() ? reinterpret_cast<binary_t*>(m_value.binary) : nullptr;
-    }
-
-    /// get a pointer to the value (binary)
-    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
-    {
-        return is_binary() ? m_value.binary : nullptr;
-    }
-
     /// get a pointer to the value (binary)
     internal_binary_t* get_impl_ptr(internal_binary_t* /*unused*/) noexcept
     {
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index c21a4308..0727b005 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -3435,9 +3435,9 @@ template <typename BasicJsonType, typename ConstructibleArrayType,
               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
               not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
               not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
+              not std::is_same<ConstructibleArrayType, typename BasicJsonType::internal_binary_t>::value and
               not is_basic_json<ConstructibleArrayType>::value,
               int > = 0 >
-
 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
 j.template get<typename ConstructibleArrayType::value_type>(),
@@ -3452,6 +3452,17 @@ void())
     from_json_array_impl(j, arr, priority_tag<3> {});
 }
 
+template <typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::internal_binary_t& bin)
+{
+    if (JSON_HEDLEY_UNLIKELY(not j.is_binary()))
+    {
+        JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
+    }
+
+    bin = *j.template get_ptr<const typename BasicJsonType::internal_binary_t*>();
+}
+
 template<typename BasicJsonType, typename ConstructibleObjectType,
          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
@@ -3851,7 +3862,7 @@ template<>
 struct external_constructor<value_t::binary>
 {
     template<typename BasicJsonType>
-    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
+    static void construct(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& b)
     {
         j.m_type = value_t::binary;
         typename BasicJsonType::internal_binary_t value{b};
@@ -3860,7 +3871,7 @@ struct external_constructor<value_t::binary>
     }
 
     template<typename BasicJsonType>
-    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
+    static void construct(BasicJsonType& j, typename BasicJsonType::internal_binary_t&& b)
     {
         j.m_type = value_t::binary;
         typename BasicJsonType::internal_binary_t value{std::move(b)};
@@ -4058,9 +4069,9 @@ void to_json(BasicJsonType& j, const std::vector<bool>& e)
 template <typename BasicJsonType, typename CompatibleArrayType,
           enable_if_t<is_compatible_array_type<BasicJsonType,
                       CompatibleArrayType>::value and
-                      not is_compatible_object_type<
-                          BasicJsonType, CompatibleArrayType>::value and
+                      not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
                       not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
+                      not std::is_same<typename BasicJsonType::internal_binary_t, CompatibleArrayType>::value and
                       not is_basic_json<CompatibleArrayType>::value,
                       int> = 0>
 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
@@ -4068,6 +4079,12 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
     external_constructor<value_t::array>::construct(j, arr);
 }
 
+template <typename BasicJsonType>
+void to_json(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& bin)
+{
+    external_constructor<value_t::binary>::construct(j, bin);
+}
+
 template<typename BasicJsonType, typename T,
          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
@@ -4727,13 +4744,9 @@ input.
 template<typename BasicJsonType>
 struct json_sax
 {
-    /// type for (signed) integers
     using number_integer_t = typename BasicJsonType::number_integer_t;
-    /// type for unsigned integers
     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
-    /// type for floating-point numbers
     using number_float_t = typename BasicJsonType::number_float_t;
-    /// type for strings
     using string_t = typename BasicJsonType::string_t;
     using binary_t = typename BasicJsonType::binary_t;
 
@@ -15560,6 +15573,60 @@ class serializer
 
 // #include <nlohmann/detail/value_t.hpp>
 
+// #include <nlohmann/detail/wrapped_binary_t.hpp>
+
+
+#include <cstdint> // uint8_t
+#include <utility> // move
+
+namespace nlohmann
+{
+namespace detail
+{
+
+/*!
+@brief an internal type for a backed binary type
+
+This type is designed to be `binary_t` but with the subtype implementation
+detail.  This type exists so that the user does not have to specify a struct
+his- or herself with a specific naming scheme in order to override the
+binary type.  I.e. it's for ease of use.
+*/
+template<typename BinaryType>
+struct wrapped_binary_t : public BinaryType
+{
+    using binary_t = BinaryType;
+
+    wrapped_binary_t() noexcept(noexcept(binary_t())) = default;
+
+    wrapped_binary_t(const binary_t& bint) noexcept(noexcept(binary_t(bint)))
+        : binary_t(bint)
+    {}
+
+    wrapped_binary_t(binary_t&& bint) noexcept(noexcept(binary_t(std::move(bint))))
+        : binary_t(std::move(bint))
+    {}
+
+    wrapped_binary_t(const binary_t& bint,
+                     std::uint8_t st) noexcept(noexcept(binary_t(bint)))
+        : binary_t(bint)
+        , subtype(st)
+        , has_subtype(true)
+    {}
+
+    wrapped_binary_t(binary_t&& bint, std::uint8_t st) noexcept(noexcept(binary_t(std::move(bint))))
+        : binary_t(std::move(bint))
+        , subtype(st)
+        , has_subtype(true)
+    {}
+
+    std::uint8_t subtype = 0;
+    bool has_subtype = false;
+};
+
+}  // namespace detail
+}  // namespace nlohmann
+
 // #include <nlohmann/json_fwd.hpp>
 
 
@@ -16330,7 +16397,7 @@ class basic_json
     This type is a type designed to carry binary data that appears in various
     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
     BSON's generic binary subtype.  This type is NOT a part of standard JSON and
-    exists solely for compatibility with these binary types.  As such, it is
+    exists solely for compatibility with these binary types. As such, it is
     simply defined as an ordered sequence of zero or more byte values.
 
     Additionally, as an implementation detail, the subtype of the binary data is
@@ -16341,9 +16408,8 @@ class basic_json
 
     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
     as:
-    > Major type 2:  a byte string.  The string's length in bytes is
-    > represented following the rules for positive integers (major type
-    > 0).
+    > Major type 2: a byte string. The string's length in bytes is represented
+    > following the rules for positive integers (major type 0).
 
     [MessagePack's documentation on the bin type
     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
@@ -16359,7 +16425,7 @@ class basic_json
 
     None of these impose any limitations on the internal representation other
     than the basic unit of storage be some type of array whose parts are
-    decomposible into bytes.
+    decomposable into bytes.
 
     The default representation of this binary format is a
     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
@@ -16371,7 +16437,7 @@ class basic_json
 
     #### Storage
 
-    Binary Arrays are stored as pointers in a @ref basic_json type.  That is,
+    Binary Arrays are stored as pointers in a @ref basic_json type. That is,
     for any access to array values, a pointer of the type `binary_t*` must be
     dereferenced.
 
@@ -16381,43 +16447,7 @@ class basic_json
     */
     using binary_t = BinaryType;
 
-    /*!
-    @brief an internal type for a backed binary type
-
-    This type is designed to be `binary_t` but with the subtype implementation
-    detail.  This type exists so that the user does not have to specify a struct
-    his- or herself with a specific naming scheme in order to override the
-    binary type.  I.e. it's for ease of use.
-    */
-    struct internal_binary_t : public BinaryType
-    {
-        using BinaryType::BinaryType;
-        internal_binary_t() noexcept(noexcept(BinaryType()))
-            : BinaryType()
-        {}
-        internal_binary_t(const BinaryType& bint) noexcept(noexcept(BinaryType(bint)))
-            : BinaryType(bint)
-        {}
-        internal_binary_t(BinaryType&& bint) noexcept(noexcept(BinaryType(std::move(bint))))
-            : BinaryType(std::move(bint))
-        {}
-        internal_binary_t(const BinaryType& bint, std::uint8_t st) noexcept(noexcept(BinaryType(bint)))
-            : BinaryType(bint)
-            , subtype(st)
-            , has_subtype(true)
-        {}
-        internal_binary_t(BinaryType&& bint, std::uint8_t st) noexcept(noexcept(BinaryType(std::move(bint))))
-            : BinaryType(std::move(bint))
-            , subtype(st)
-            , has_subtype(true)
-        {}
-
-        // TOOD: If minimum C++ version is ever bumped to C++17, this field
-        // deserves to be a std::optional
-        std::uint8_t subtype = 0;
-        bool has_subtype = false;
-    };
-
+    using internal_binary_t = nlohmann::detail::wrapped_binary_t<BinaryType>;
     /// @}
 
   private:
@@ -18293,18 +18323,6 @@ class basic_json
         return is_number_float() ? &m_value.number_float : nullptr;
     }
 
-    /// get a pointer to the value (binary)
-    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
-    {
-        return is_binary() ? reinterpret_cast<binary_t*>(m_value.binary) : nullptr;
-    }
-
-    /// get a pointer to the value (binary)
-    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
-    {
-        return is_binary() ? m_value.binary : nullptr;
-    }
-
     /// get a pointer to the value (binary)
     internal_binary_t* get_impl_ptr(internal_binary_t* /*unused*/) noexcept
     {
diff --git a/test/src/unit-constructor1.cpp b/test/src/unit-constructor1.cpp
index 96a0be0f..742bdcd9 100644
--- a/test/src/unit-constructor1.cpp
+++ b/test/src/unit-constructor1.cpp
@@ -481,6 +481,23 @@ TEST_CASE("constructors")
         }
     }
 
+    SECTION("create a binary (explicit)")
+    {
+        SECTION("empty binary")
+        {
+            json::internal_binary_t b{};
+            json j(b);
+            CHECK(j.type() == json::value_t::binary);
+        }
+
+        SECTION("filled binary")
+        {
+            json::internal_binary_t b({1, 2, 3});
+            json j(b);
+            CHECK(j.type() == json::value_t::binary);
+        }
+    }
+
     SECTION("create an integer number (explicit)")
     {
         SECTION("uninitialized value")
diff --git a/test/src/unit-pointer_access.cpp b/test/src/unit-pointer_access.cpp
index ed245dc6..5f3f9e31 100644
--- a/test/src/unit-pointer_access.cpp
+++ b/test/src/unit-pointer_access.cpp
@@ -60,7 +60,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -90,7 +89,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
@@ -120,7 +118,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -150,7 +147,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
@@ -180,7 +176,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -210,7 +205,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
@@ -240,7 +234,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -270,8 +263,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
@@ -301,7 +292,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -331,7 +321,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
@@ -361,7 +350,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -391,7 +379,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
@@ -421,7 +408,6 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
-        CHECK(value.get_ptr<json::binary_t*>() == nullptr);
         CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
     }
 
@@ -451,26 +437,26 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() != nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
+        CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
     }
 
-    SECTION("pointer access to const binary_t")
+    SECTION("pointer access to const internal_binary_t")
     {
-        using test_type = const json::binary_t;
-        const json value = json::binary_array({});
+        using test_type = const json::internal_binary_t;
+        const json value = json::binary_array({1, 2, 3});
 
         // check if pointers are returned correctly
         test_type* p1 = value.get_ptr<test_type*>();
         CHECK(p1 == value.get_ptr<test_type*>());
-        //CHECK(*p1 == value.get<test_type>());
+        CHECK(*p1 == value.get<test_type>());
 
         const test_type* p2 = value.get_ptr<const test_type*>();
         CHECK(p2 == value.get_ptr<const test_type*>());
-        //CHECK(*p2 == value.get<test_type>());
+        CHECK(*p2 == value.get<test_type>());
 
         const test_type* const p3 = value.get_ptr<const test_type* const>();
         CHECK(p3 == value.get_ptr<const test_type* const>());
-        //CHECK(*p3 == value.get<test_type>());
+        CHECK(*p3 == value.get<test_type>());
 
         // check if null pointers are returned correctly
         CHECK(value.get_ptr<const json::object_t*>() == nullptr);
@@ -480,10 +466,10 @@ TEST_CASE("pointer access")
         CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
         CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
-        CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
+        CHECK(value.get_ptr<const json::internal_binary_t*>() != nullptr);
     }
 
-    SECTION("pointer access to const binary_t")
+    SECTION("pointer access to const internal_binary_t")
     {
         using test_type = const json::internal_binary_t;
         const json value = json::binary_array({});
@@ -491,15 +477,15 @@ TEST_CASE("pointer access")
         // check if pointers are returned correctly
         test_type* p1 = value.get_ptr<test_type*>();
         CHECK(p1 == value.get_ptr<test_type*>());
-        //CHECK(*p1 == value.get<test_type>());
+        CHECK(*p1 == value.get<test_type>());
 
         const test_type* p2 = value.get_ptr<const test_type*>();
         CHECK(p2 == value.get_ptr<const test_type*>());
-        //CHECK(*p2 == value.get<test_type>());
+        CHECK(*p2 == value.get<test_type>());
 
         const test_type* const p3 = value.get_ptr<const test_type* const>();
         CHECK(p3 == value.get_ptr<const test_type* const>());
-        //CHECK(*p3 == value.get<test_type>());
+        CHECK(*p3 == value.get<test_type>());
 
         // check if null pointers are returned correctly
         CHECK(value.get_ptr<const json::object_t*>() == nullptr);