lottie/vector: move pixman code to separate pixman folder.
[platform/core/uifw/lottie-player.git] / src / vector / vcowptr.h
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef VCOWPTR_H
18 #define VCOWPTR_H
19
20 #include <assert.h>
21 #include "vglobal.h"
22
23 template <typename T>
24 class vcow_ptr {
25     struct model {
26         std::atomic<std::size_t> mRef{1};
27
28         model() = default;
29
30         template <class... Args>
31         explicit model(Args&&... args) : mValue(std::forward<Args>(args)...)
32         {
33         }
34
35         T mValue;
36     };
37     model* mModel;
38
39 public:
40     using element_type = T;
41
42     vcow_ptr()
43     {
44         static model default_s;
45         mModel = &default_s;
46         ++mModel->mRef;
47     }
48
49     ~vcow_ptr()
50     {
51         if (mModel && (--mModel->mRef == 0)) delete mModel;
52     }
53
54     template <class... Args>
55     vcow_ptr(Args&&... args) : mModel(new model(std::forward<Args>(args)...))
56     {
57     }
58
59     vcow_ptr(const vcow_ptr& x) noexcept : mModel(x.mModel)
60     {
61         assert(mModel);
62         ++mModel->mRef;
63     }
64     vcow_ptr(vcow_ptr&& x) noexcept : mModel(x.mModel)
65     {
66         assert(mModel);
67         x.mModel = nullptr;
68     }
69
70     auto operator=(const vcow_ptr& x) noexcept -> vcow_ptr&
71     {
72         return *this = vcow_ptr(x);
73     }
74
75     auto operator=(vcow_ptr&& x) noexcept -> vcow_ptr&
76     {
77         auto tmp = std::move(x);
78         swap(*this, tmp);
79         return *this;
80     }
81
82     auto operator*() const noexcept -> const element_type& { return read(); }
83
84     auto operator-> () const noexcept -> const element_type* { return &read(); }
85
86     int refCount() const noexcept
87     {
88         assert(mModel);
89
90         return mModel->mRef;
91     }
92
93     bool unique() const noexcept
94     {
95         assert(mModel);
96
97         return mModel->mRef == 1;
98     }
99
100     auto write() -> element_type&
101     {
102         if (!unique()) *this = vcow_ptr(read());
103
104         return mModel->mValue;
105     }
106
107     auto read() const noexcept -> const element_type&
108     {
109         assert(mModel);
110
111         return mModel->mValue;
112     }
113
114     friend inline void swap(vcow_ptr& x, vcow_ptr& y) noexcept
115     {
116         std::swap(x.mModel, y.mModel);
117     }
118 };
119
120 #endif  // VCOWPTR_H