summaryrefslogtreecommitdiff
path: root/include/llmr/util/recursive_wrapper.hpp
blob: b87dc5699aa815b8d5217e5e24311bd184fce257 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
#define MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP

#include <utility>

namespace llmr { namespace util {

template <typename T>
class recursive_wrapper
{
public:
    using type = T;
private:

    T* p_;

public:

    ~recursive_wrapper();
    recursive_wrapper();

    recursive_wrapper(recursive_wrapper const& operand);
    recursive_wrapper(T const& operand);
    recursive_wrapper(recursive_wrapper&& operand);
    recursive_wrapper(T&& operand);

private:

    void assign(const T& rhs);

public:

    inline recursive_wrapper& operator=(recursive_wrapper const& rhs)
    {
        assign( rhs.get() );
        return *this;
    }

    inline recursive_wrapper& operator=(T const& rhs)
    {
        assign( rhs );
        return *this;
    }

    inline void swap(recursive_wrapper& operand) noexcept
    {
        T* temp = operand.p_;
        operand.p_ = p_;
        p_ = temp;
    }


    recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept
    {
        swap(rhs);
        return *this;
    }

    recursive_wrapper& operator=(T&& rhs)
    {
        get() = std::move(rhs);
        return *this;
    }


public:

    T& get() { return *get_pointer(); }
    const T& get() const { return *get_pointer(); }
    T* get_pointer() { return p_; }
    const T* get_pointer() const { return p_; }
    operator T const&() const { return this->get(); }
    operator T&() { return this->get(); }
};

template <typename T>
recursive_wrapper<T>::~recursive_wrapper()
{
    delete p_;
}

template <typename T>
recursive_wrapper<T>::recursive_wrapper()
    : p_(new T)
{
}

template <typename T>
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper const& operand)
    : p_(new T( operand.get() ))
{
}

template <typename T>
recursive_wrapper<T>::recursive_wrapper(T const& operand)
    : p_(new T(operand))
{
}

template <typename T>
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
    : p_(operand.p_)
{
    operand.p_ = nullptr;
}

template <typename T>
recursive_wrapper<T>::recursive_wrapper(T&& operand)
    : p_(new T( std::move(operand) ))
{
}

template <typename T>
void recursive_wrapper<T>::assign(const T& rhs)
{
    this->get() = rhs;
}

template <typename T>
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept
{
    lhs.swap(rhs);
}

}}

#endif // MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP