File indexing completed on 2025-01-18 09:39:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_JSON_IMPL_VALUE_REF_IPP
0011 #define BOOST_JSON_IMPL_VALUE_REF_IPP
0012
0013 #include <boost/json/value_ref.hpp>
0014 #include <boost/json/array.hpp>
0015 #include <boost/json/value.hpp>
0016
0017 namespace boost {
0018 namespace json {
0019
0020 value_ref::
0021 operator
0022 value() const
0023 {
0024 return make_value({});
0025 }
0026
0027 value
0028 value_ref::
0029 from_init_list(
0030 void const* p,
0031 storage_ptr sp)
0032 {
0033 return make_value(
0034 *reinterpret_cast<
0035 init_list const*>(p),
0036 std::move(sp));
0037 }
0038
0039 bool
0040 value_ref::
0041 is_key_value_pair() const noexcept
0042 {
0043 if(what_ != what::ini)
0044 return false;
0045 if(arg_.init_list_.size() != 2)
0046 return false;
0047 auto const& e =
0048 *arg_.init_list_.begin();
0049 if( e.what_ != what::str &&
0050 e.what_ != what::strfunc)
0051 return false;
0052 return true;
0053 }
0054
0055 bool
0056 value_ref::
0057 maybe_object(
0058 std::initializer_list<
0059 value_ref> init) noexcept
0060 {
0061 for(auto const& e : init)
0062 if(! e.is_key_value_pair())
0063 return false;
0064 return true;
0065 }
0066
0067 string_view
0068 value_ref::
0069 get_string() const noexcept
0070 {
0071 BOOST_ASSERT(
0072 what_ == what::str ||
0073 what_ == what::strfunc);
0074 if (what_ == what::strfunc)
0075 return *static_cast<const string*>(f_.p);
0076 return arg_.str_;
0077 }
0078
0079 value
0080 value_ref::
0081 make_value(
0082 storage_ptr sp) const
0083 {
0084 switch(what_)
0085 {
0086 default:
0087 case what::str:
0088 return string(
0089 arg_.str_,
0090 std::move(sp));
0091
0092 case what::ini:
0093 return make_value(
0094 arg_.init_list_,
0095 std::move(sp));
0096
0097 case what::func:
0098 return f_.f(f_.p,
0099 std::move(sp));
0100
0101 case what::strfunc:
0102 return f_.f(f_.p,
0103 std::move(sp));
0104
0105 case what::cfunc:
0106 return cf_.f(cf_.p,
0107 std::move(sp));
0108 }
0109 }
0110
0111 value
0112 value_ref::
0113 make_value(
0114 std::initializer_list<
0115 value_ref> init,
0116 storage_ptr sp)
0117 {
0118 if(maybe_object(init))
0119 return make_object(
0120 init, std::move(sp));
0121 return make_array(
0122 init, std::move(sp));
0123 }
0124
0125 object
0126 value_ref::
0127 make_object(
0128 std::initializer_list<value_ref> init,
0129 storage_ptr sp)
0130 {
0131 object obj(std::move(sp));
0132 obj.reserve(init.size());
0133 for(auto const& e : init)
0134 obj.emplace(
0135 e.arg_.init_list_.begin()[0].get_string(),
0136 e.arg_.init_list_.begin()[1].make_value(
0137 obj.storage()));
0138 return obj;
0139 }
0140
0141 array
0142 value_ref::
0143 make_array(
0144 std::initializer_list<
0145 value_ref> init,
0146 storage_ptr sp)
0147 {
0148 array arr(std::move(sp));
0149 arr.reserve(init.size());
0150 for(auto const& e : init)
0151 arr.emplace_back(
0152 e.make_value(
0153 arr.storage()));
0154 return arr;
0155 }
0156
0157 void
0158 value_ref::
0159 write_array(
0160 value* dest,
0161 std::initializer_list<
0162 value_ref> init,
0163 storage_ptr const& sp)
0164 {
0165 struct undo
0166 {
0167 value* const base;
0168 value* pos;
0169 ~undo()
0170 {
0171 if(pos)
0172 while(pos > base)
0173 (--pos)->~value();
0174 }
0175 };
0176 undo u{dest, dest};
0177 for(auto const& e : init)
0178 {
0179 ::new(u.pos) value(
0180 e.make_value(sp));
0181 ++u.pos;
0182 }
0183 u.pos = nullptr;
0184 }
0185
0186 }
0187 }
0188
0189 #endif