1 #pragma once 2 3 #include <cstdint> // uint8_t 4 #include <tuple> // tie 5 #include <utility> // move 6 7 namespace nlohmann 8 { 9 10 /*! 11 @brief an internal type for a backed binary type 12 13 This type extends the template parameter @a BinaryType provided to `basic_json` 14 with a subtype used by BSON and MessagePack. This type exists so that the user 15 does not have to specify a type themselves with a specific naming scheme in 16 order to override the binary type. 17 18 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by 19 default) 20 21 @since version 3.8.0 22 */ 23 template<typename BinaryType> 24 class byte_container_with_subtype : public BinaryType 25 { 26 public: 27 /// the type of the underlying container 28 using container_type = BinaryType; 29 byte_container_with_subtype()30 byte_container_with_subtype() noexcept(noexcept(container_type())) 31 : container_type() 32 {} 33 byte_container_with_subtype(const container_type & b)34 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) 35 : container_type(b) 36 {} 37 byte_container_with_subtype(container_type && b)38 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) 39 : container_type(std::move(b)) 40 {} 41 byte_container_with_subtype(const container_type & b,std::uint8_t subtype)42 byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b))) 43 : container_type(b) 44 , m_subtype(subtype) 45 , m_has_subtype(true) 46 {} 47 byte_container_with_subtype(container_type && b,std::uint8_t subtype)48 byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b)))) 49 : container_type(std::move(b)) 50 , m_subtype(subtype) 51 , m_has_subtype(true) 52 {} 53 operator ==(const byte_container_with_subtype & rhs) const54 bool operator==(const byte_container_with_subtype& rhs) const 55 { 56 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) == 57 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype); 58 } 59 operator !=(const byte_container_with_subtype & rhs) const60 bool operator!=(const byte_container_with_subtype& rhs) const 61 { 62 return !(rhs == *this); 63 } 64 65 /*! 66 @brief sets the binary subtype 67 68 Sets the binary subtype of the value, also flags a binary JSON value as 69 having a subtype, which has implications for serialization. 70 71 @complexity Constant. 72 73 @exceptionsafety No-throw guarantee: this member function never throws 74 exceptions. 75 76 @sa @ref subtype() -- return the binary subtype 77 @sa @ref clear_subtype() -- clears the binary subtype 78 @sa @ref has_subtype() -- returns whether or not the binary value has a 79 subtype 80 81 @since version 3.8.0 82 */ set_subtype(std::uint8_t subtype)83 void set_subtype(std::uint8_t subtype) noexcept 84 { 85 m_subtype = subtype; 86 m_has_subtype = true; 87 } 88 89 /*! 90 @brief return the binary subtype 91 92 Returns the numerical subtype of the value if it has a subtype. If it does 93 not have a subtype, this function will return size_t(-1) as a sentinel 94 value. 95 96 @return the numerical subtype of the binary value 97 98 @complexity Constant. 99 100 @exceptionsafety No-throw guarantee: this member function never throws 101 exceptions. 102 103 @sa @ref set_subtype() -- sets the binary subtype 104 @sa @ref clear_subtype() -- clears the binary subtype 105 @sa @ref has_subtype() -- returns whether or not the binary value has a 106 subtype 107 108 @since version 3.8.0 109 */ subtype() const110 constexpr std::uint8_t subtype() const noexcept 111 { 112 return m_subtype; 113 } 114 115 /*! 116 @brief return whether the value has a subtype 117 118 @return whether the value has a subtype 119 120 @complexity Constant. 121 122 @exceptionsafety No-throw guarantee: this member function never throws 123 exceptions. 124 125 @sa @ref subtype() -- return the binary subtype 126 @sa @ref set_subtype() -- sets the binary subtype 127 @sa @ref clear_subtype() -- clears the binary subtype 128 129 @since version 3.8.0 130 */ has_subtype() const131 constexpr bool has_subtype() const noexcept 132 { 133 return m_has_subtype; 134 } 135 136 /*! 137 @brief clears the binary subtype 138 139 Clears the binary subtype and flags the value as not having a subtype, which 140 has implications for serialization; for instance MessagePack will prefer the 141 bin family over the ext family. 142 143 @complexity Constant. 144 145 @exceptionsafety No-throw guarantee: this member function never throws 146 exceptions. 147 148 @sa @ref subtype() -- return the binary subtype 149 @sa @ref set_subtype() -- sets the binary subtype 150 @sa @ref has_subtype() -- returns whether or not the binary value has a 151 subtype 152 153 @since version 3.8.0 154 */ clear_subtype()155 void clear_subtype() noexcept 156 { 157 m_subtype = 0; 158 m_has_subtype = false; 159 } 160 161 private: 162 std::uint8_t m_subtype = 0; 163 bool m_has_subtype = false; 164 }; 165 166 } // namespace nlohmann 167