Welcome to mirror list, hosted at ThFree Co, Russian Federation.

clonable_ptr.hpp « libslic3r « src - github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a3b7ee2446f24e0e0afd6193cb31fee453cfc194 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// clonable_ptr: a smart pointer with a usage similar to unique_ptr, with the exception, that
// the copy constructor / copy assignment operator work by calling the ->clone() method.

// derived from https://github.com/SRombauts/shared_ptr/blob/master/include/unique_ptr.hpp
/**
 * @file  clonable_ptr.hpp
 * @brief clonable_ptr is a fake implementation to use in place of a C++11 std::clonable_ptr when compiling on an older compiler.
 *
 * @see http://www.cplusplus.com/reference/memory/clonable_ptr/
 *
 * Copyright (c) 2014-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include "assert.h"

namespace Slic3r {

// Detect whether the compiler supports C++11 noexcept exception specifications.
#if defined(_MSC_VER) && _MSC_VER < 1900 && ! defined(noexcept)
    #define noexcept throw()
#endif

template<class T>
class clonable_ptr
{
public:
    /// The type of the managed object, aliased as member type
    typedef T element_type;

    /// @brief Default constructor
    clonable_ptr() noexcept :
        px(nullptr)
    {
    }
    /// @brief Constructor with the provided pointer to manage
    explicit clonable_ptr(T* p) noexcept :
        px(p)
    {
    }
    /// @brief Copy constructor, clones by calling the rhs.clone() method
    clonable_ptr(const clonable_ptr& rhs) :
		px(rhs ? rhs.px->clone() : nullptr)
    {
    }
    /// @brief Move constructor, never throws
    clonable_ptr(clonable_ptr&& rhs) noexcept :
        px(rhs.px)
    {
        rhs.px = nullptr;
    }
    /// @brief Assignment operator
    clonable_ptr& operator=(const clonable_ptr& rhs)
    {
		delete px;
		px = rhs ? rhs.px->clone() : nullptr;
        return *this;
    }
    /// @brief Move operator, never throws
    clonable_ptr& operator=(clonable_ptr&& rhs)
    {
		delete px;
        px = rhs.px;
        rhs.px = nullptr;
        return *this;
    }
    /// @brief the destructor releases its ownership and destroy the object
    inline ~clonable_ptr() noexcept
    {
        destroy();
    }
    /// @brief this reset releases its ownership and destroy the object
    inline void reset() noexcept
    {
        destroy();
    }
    /// @brief this reset release its ownership and re-acquire another one
    void reset(T* p) noexcept
    {
        assert((nullptr == p) || (px != p)); // auto-reset not allowed
        destroy();
        px = p;
    }

    /// @brief Swap method for the copy-and-swap idiom (copy constructor and swap method)
    void swap(clonable_ptr& rhs) noexcept
    {
        T *tmp = px;
        px = rhs.px;
        rhs.px = tmp;
    }

    /// @brief release the ownership of the px pointer without destroying the object!
    inline void release() noexcept
    {
        px = nullptr;
    }

    // reference counter operations :
    inline operator bool() const noexcept
    {
        return (nullptr != px); // TODO nullptrptr
    }

    // underlying pointer operations :
    inline T& operator*()  const noexcept
    {
        assert(nullptr != px);
        return *px;
    }
    inline T* operator->() const noexcept
    {
        assert(nullptr != px);
        return px;
    }
    inline T* get()  const noexcept
    {
        // no assert, can return nullptr
        return px;
    }

private:
    /// @brief release the ownership of the px pointer and destroy the object
    inline void destroy() noexcept
    {
        delete px;
        px = nullptr;
    }

    /// @brief hack: const-cast release the ownership of the px pointer without destroying the object!
    inline void release() const noexcept
    {
        px = nullptr;
    }

private:
    T* px; //!< Native pointer
};

// comparison operators
template<class T, class U> inline bool operator==(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
    return (l.get() == r.get());
}
template<class T, class U> inline bool operator!=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
    return (l.get() != r.get());
}
template<class T, class U> inline bool operator<=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
    return (l.get() <= r.get());
}
template<class T, class U> inline bool operator<(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
    return (l.get() < r.get());
}
template<class T, class U> inline bool operator>=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
    return (l.get() >= r.get());
}
template<class T, class U> inline bool operator>(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
    return (l.get() > r.get());
}

} // namespace Slic3r