1 #pragma once 2 3 #include <initializer_list> 4 #include <utility> 5 6 #include <nlohmann/detail/meta/type_traits.hpp> 7 8 namespace nlohmann 9 { 10 namespace detail 11 { 12 template<typename BasicJsonType> 13 class json_ref 14 { 15 public: 16 using value_type = BasicJsonType; 17 json_ref(value_type && value)18 json_ref(value_type&& value) 19 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true) 20 {} 21 json_ref(const value_type & value)22 json_ref(const value_type& value) 23 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false) 24 {} 25 json_ref(std::initializer_list<json_ref> init)26 json_ref(std::initializer_list<json_ref> init) 27 : owned_value(init), value_ref(&owned_value), is_rvalue(true) 28 {} 29 30 template < 31 class... Args, 32 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 > json_ref(Args &&...args)33 json_ref(Args && ... args) 34 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), 35 is_rvalue(true) {} 36 37 // class should be movable only 38 json_ref(json_ref&&) = default; 39 json_ref(const json_ref&) = delete; 40 json_ref& operator=(const json_ref&) = delete; 41 json_ref& operator=(json_ref&&) = delete; 42 ~json_ref() = default; 43 moved_or_copied() const44 value_type moved_or_copied() const 45 { 46 if (is_rvalue) 47 { 48 return std::move(*value_ref); 49 } 50 return *value_ref; 51 } 52 operator *() const53 value_type const& operator*() const 54 { 55 return *static_cast<value_type const*>(value_ref); 56 } 57 operator ->() const58 value_type const* operator->() const 59 { 60 return static_cast<value_type const*>(value_ref); 61 } 62 63 private: 64 mutable value_type owned_value = nullptr; 65 value_type* value_ref = nullptr; 66 const bool is_rvalue; 67 }; 68 } // namespace detail 69 } // namespace nlohmann 70