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 | |
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 | |