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