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