• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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