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