1// 2// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 3// 4// Distributed under the Boost Software License, Version 1.0. (See accompanying 5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6// 7// Official repository: https://github.com/boostorg/json 8// 9 10#ifndef BOOST_JSON_IMPL_VALUE_REF_IPP 11#define BOOST_JSON_IMPL_VALUE_REF_IPP 12 13#include <boost/json/value_ref.hpp> 14#include <boost/json/array.hpp> 15#include <boost/json/value.hpp> 16 17BOOST_JSON_NS_BEGIN 18 19value_ref:: 20operator 21value() const 22{ 23 return make_value({}); 24} 25 26value 27value_ref:: 28from_init_list( 29 void const* p, 30 storage_ptr sp) 31{ 32 return make_value( 33 *reinterpret_cast< 34 init_list const*>(p), 35 std::move(sp)); 36} 37 38bool 39value_ref:: 40is_key_value_pair() const noexcept 41{ 42 if(what_ != what::ini) 43 return false; 44 if(arg_.init_list_.size() != 2) 45 return false; 46 auto const& e = 47 *arg_.init_list_.begin(); 48 if( e.what_ != what::str && 49 e.what_ != what::strfunc) 50 return false; 51 return true; 52} 53 54bool 55value_ref:: 56maybe_object( 57 std::initializer_list< 58 value_ref> init) noexcept 59{ 60 for(auto const& e : init) 61 if(! e.is_key_value_pair()) 62 return false; 63 return true; 64} 65 66string_view 67value_ref:: 68get_string() const noexcept 69{ 70 BOOST_ASSERT( 71 what_ == what::str || 72 what_ == what::strfunc); 73 if (what_ == what::strfunc) 74 return *static_cast<const string*>(f_.p); 75 return arg_.str_; 76} 77 78value 79value_ref:: 80make_value( 81 storage_ptr sp) const 82{ 83 switch(what_) 84 { 85 default: 86 case what::str: 87 return string( 88 arg_.str_, 89 std::move(sp)); 90 91 case what::ini: 92 return make_value( 93 arg_.init_list_, 94 std::move(sp)); 95 96 case what::func: 97 return f_.f(f_.p, 98 std::move(sp)); 99 100 case what::strfunc: 101 return f_.f(f_.p, 102 std::move(sp)); 103 104 case what::cfunc: 105 return cf_.f(cf_.p, 106 std::move(sp)); 107 } 108} 109 110value 111value_ref:: 112make_value( 113 std::initializer_list< 114 value_ref> init, 115 storage_ptr sp) 116{ 117 if(maybe_object(init)) 118 return make_object( 119 init, std::move(sp)); 120 return make_array( 121 init, std::move(sp)); 122} 123 124object 125value_ref:: 126make_object( 127 std::initializer_list<value_ref> init, 128 storage_ptr sp) 129{ 130 object obj(std::move(sp)); 131 obj.reserve(init.size()); 132 for(auto const& e : init) 133 obj.emplace( 134 e.arg_.init_list_.begin()[0].get_string(), 135 e.arg_.init_list_.begin()[1].make_value( 136 obj.storage())); 137 return obj; 138} 139 140array 141value_ref:: 142make_array( 143 std::initializer_list< 144 value_ref> init, 145 storage_ptr sp) 146{ 147 array arr(std::move(sp)); 148 arr.reserve(init.size()); 149 for(auto const& e : init) 150 arr.emplace_back( 151 e.make_value( 152 arr.storage())); 153 return arr; 154} 155 156void 157value_ref:: 158write_array( 159 value* dest, 160 std::initializer_list< 161 value_ref> init, 162 storage_ptr const& sp) 163{ 164 struct undo 165 { 166 value* const base; 167 value* pos; 168 ~undo() 169 { 170 if(pos) 171 while(pos > base) 172 (--pos)->~value(); 173 } 174 }; 175 undo u{dest, dest}; 176 for(auto const& e : init) 177 { 178 ::new(u.pos) value( 179 e.make_value(sp)); 180 ++u.pos; 181 } 182 u.pos = nullptr; 183} 184 185BOOST_JSON_NS_END 186 187#endif 188