]> git.sesse.net Git - casparcg/blob - common/memory/array.h
2.1.0: changed "const_array" and "mutable_array" into generic "array" with const...
[casparcg] / common / memory / array.h
1 #pragma once\r
2 \r
3 #include "../spl/memory.h"\r
4 #include "../forward.h"\r
5 \r
6 #include <boost/any.hpp>\r
7 \r
8 #include <cstddef>\r
9 #include <cstdint>\r
10 \r
11 FORWARD1(boost, template<typename> class shared_future);\r
12 \r
13 namespace caspar {\r
14         \r
15 template<typename T>\r
16 class array sealed\r
17 {\r
18         array(const array<std::uint8_t>&);\r
19         array& operator=(const array<std::uint8_t>&);\r
20 \r
21         template<typename> friend class array;\r
22 public:\r
23 \r
24         // Static Members\r
25 \r
26         // Constructors\r
27         \r
28         template<typename T>\r
29         explicit array(std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
30                 : ptr_(ptr)\r
31                 , size_(size)\r
32                 , cacheable_(cacheable)\r
33                 , storage_(new boost::any(std::forward<T>(storage)))\r
34         {\r
35         }\r
36 \r
37         array(array&& other)\r
38                 : ptr_(other.ptr_)\r
39                 , size_(other.size_)\r
40                 , cacheable_(other.cacheable_)\r
41                 , storage_(std::move(other.storage_))\r
42         {\r
43                 CASPAR_ASSERT(storage_);\r
44         }\r
45 \r
46         // Methods\r
47         \r
48         array& operator=(array&& other)\r
49         {\r
50                 ptr_            = other.ptr_;\r
51                 size_           = other.size_;\r
52                 cacheable_  = other.cacheable_;\r
53                 storage_        = std::move(other.storage_);\r
54 \r
55                 CASPAR_ASSERT(storage_);\r
56 \r
57                 return *this;\r
58         }\r
59 \r
60         // Properties   \r
61                         \r
62         T* begin() const                        {return ptr_;}          \r
63         T* data() const                         {return ptr_;}\r
64         T* end() const                          {return reinterpret_cast<T*>(reinterpret_cast<char*>(ptr_) + size_);}\r
65         std::size_t size() const        {return size_;}\r
66         bool empty() const                      {return size() == 0;}\r
67         bool cacheable() const          {return cacheable_;}\r
68         \r
69         template<typename T>\r
70         T storage() const\r
71         {\r
72                 return boost::any_cast<T>(*storage_);\r
73         }\r
74 private:\r
75         T*                      ptr_;\r
76         std::size_t     size_;\r
77         bool            cacheable_;\r
78         std::unique_ptr<boost::any>     storage_;\r
79 };\r
80 \r
81 template<typename T>\r
82 class array<const T> sealed\r
83 {\r
84 public:\r
85 \r
86         // Static Members\r
87 \r
88         // Constructors\r
89 \r
90         template<typename T>\r
91         explicit array(const std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
92                 : ptr_(ptr)\r
93                 , size_(size)\r
94                 , cacheable_(cacheable)\r
95                 , storage_(new boost::any(std::forward<T>(storage)))\r
96         {\r
97         }\r
98         \r
99         array(const array& other)\r
100                 : ptr_(other.ptr_)\r
101                 , size_(other.size_)\r
102                 , cacheable_(other.cacheable_)\r
103                 , storage_(other.storage_)\r
104         {\r
105                 CASPAR_ASSERT(storage_);\r
106         }\r
107 \r
108         array(array<T>&& other)\r
109                 : ptr_(other.ptr_)\r
110                 , size_(other.size_)\r
111                 , cacheable_(other.cacheable_)\r
112                 , storage_(std::move(other.storage_))\r
113         {\r
114                 CASPAR_ASSERT(storage_);\r
115         }\r
116 \r
117         // Methods\r
118 \r
119         array& operator=(array other)\r
120         {\r
121                 other.swap(*this);\r
122                 return *this;\r
123         }\r
124 \r
125         void swap(array& other)\r
126         {\r
127                 ptr_            = other.ptr_;\r
128                 size_           = other.size_;\r
129                 storage_        = other.storage_;\r
130                 cacheable_      = other.cacheable_;\r
131         }\r
132 \r
133         // Properties\r
134                         \r
135         const T* begin() const          {return ptr_;}          \r
136         const T* data() const           {return ptr_;}\r
137         const T* end() const            {return reinterpret_cast<const T*>(reinterpret_cast<const char*>(ptr_) + size_);}\r
138         std::size_t size() const        {return size_;}\r
139         bool empty() const                      {return size() == 0;}\r
140         bool cacheable() const          {return cacheable_;}\r
141         \r
142         template<typename T>\r
143         T storage() const\r
144         {\r
145                 return boost::any_cast<T>(*storage_);\r
146         }\r
147 \r
148 private:\r
149         const T*        ptr_;\r
150         std::size_t     size_;\r
151         bool            cacheable_;\r
152         std::shared_ptr<boost::any>     storage_;\r
153 };\r
154 \r
155 }\r
156 \r
157 namespace std {\r
158         \r
159 template<typename T>\r
160 void swap(caspar::array<const T>& lhs, caspar::array<const T>& rhs)\r
161 {\r
162         lhs.swap(rhs);\r
163 }\r
164 \r
165 }\r
166 \r