1#pragma once
2
3#include <initializer_list>
4#include <utility>
5
6#include <nlohmann/detail/meta/type_traits.hpp>
7
8namespace nlohmann
9{
10namespace detail
11{
12template<typename BasicJsonType>
13class json_ref
14{
15 public:
16 using value_type = BasicJsonType;
17
18 json_ref(value_type&& value)
19 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
20 {}
21
22 json_ref(const value_type& value)
23 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
24 {}
25
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 >
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
44 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
53 value_type const& operator*() const
54 {
55 return *static_cast<value_type const*>(value_ref);
56 }
57
58 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