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)) 20 , value_ref(&owned_value) 21 , is_rvalue(true) 22 {} 23 json_ref(const value_type & value)24 json_ref(const value_type& value) 25 : value_ref(const_cast<value_type*>(&value)) 26 , is_rvalue(false) 27 {} 28 json_ref(std::initializer_list<json_ref> init)29 json_ref(std::initializer_list<json_ref> init) 30 : owned_value(init) 31 , value_ref(&owned_value) 32 , is_rvalue(true) 33 {} 34 35 template < 36 class... Args, 37 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 > json_ref(Args &&...args)38 json_ref(Args && ... args) 39 : owned_value(std::forward<Args>(args)...) 40 , value_ref(&owned_value) 41 , is_rvalue(true) 42 {} 43 44 // class should be movable only 45 json_ref(json_ref&&) = default; 46 json_ref(const json_ref&) = delete; 47 json_ref& operator=(const json_ref&) = delete; 48 json_ref& operator=(json_ref&&) = delete; 49 ~json_ref() = default; 50 moved_or_copied() const51 value_type moved_or_copied() const 52 { 53 if (is_rvalue) 54 { 55 return std::move(*value_ref); 56 } 57 return *value_ref; 58 } 59 operator *() const60 value_type const& operator*() const 61 { 62 return *static_cast<value_type const*>(value_ref); 63 } 64 operator ->() const65 value_type const* operator->() const 66 { 67 return static_cast<value_type const*>(value_ref); 68 } 69 70 private: 71 mutable value_type owned_value = nullptr; 72 value_type* value_ref = nullptr; 73 const bool is_rvalue = true; 74 }; 75 } // namespace detail 76 } // namespace nlohmann 77