]> git.sesse.net Git - casparcg/blobdiff - common/array.h
ffmpeg_producer: Multiple audio streams are now merged (flattened) before the audio...
[casparcg] / common / array.h
index d298705a55288908433ed8e2919c6cbc5dd5c696..3c84fdd34a39193c4e98f5a56191838320b7b028 100644 (file)
-#pragma once\r
-\r
-#include "memory.h"\r
-#include "forward.h"\r
-\r
-#include <boost/any.hpp>\r
-\r
-#include <cstddef>\r
-#include <cstdint>\r
-\r
-namespace caspar {\r
-       \r
-template<typename T>\r
-class array sealed\r
-{\r
-       array(const array<std::uint8_t>&);\r
-       array& operator=(const array<std::uint8_t>&);\r
-\r
-       template<typename> friend class array;\r
-public:\r
-\r
-       // Static Members\r
-\r
-       // Constructors\r
-       \r
-       template<typename T>\r
-       explicit array(std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
-               : ptr_(ptr)\r
-               , size_(size)\r
-               , cacheable_(cacheable)\r
-               , storage_(new boost::any(std::forward<T>(storage)))\r
-       {\r
-       }\r
-\r
-       array(array&& other)\r
-               : ptr_(other.ptr_)\r
-               , size_(other.size_)\r
-               , cacheable_(other.cacheable_)\r
-               , storage_(std::move(other.storage_))\r
-       {\r
-               CASPAR_ASSERT(storage_);\r
-       }\r
-\r
-       // Methods\r
-       \r
-       array& operator=(array&& other)\r
-       {\r
-               std::swap(ptr_, other.ptr_);\r
-               std::swap(size_, other.size_);\r
-               std::swap(storage_,     other.storage_);\r
-               std::swap(cacheable_, other.cacheable_);\r
-\r
-               CASPAR_ASSERT(storage_);\r
-\r
-               return *this;\r
-       }\r
-\r
-       // Properties   \r
-                       \r
-       T* begin() const                        {return ptr_;}          \r
-       T* data() const                         {return ptr_;}\r
-       T* end() const                          {return reinterpret_cast<T*>(reinterpret_cast<char*>(ptr_) + size_);}\r
-       std::size_t size() const        {return size_;}\r
-       bool empty() const                      {return size() == 0;}\r
-       bool cacheable() const          {return cacheable_;}\r
-       \r
-       template<typename T>\r
-       T storage() const\r
-       {\r
-               return boost::any_cast<T>(*storage_);\r
-       }\r
-private:\r
-       T*                      ptr_;\r
-       std::size_t     size_;\r
-       bool            cacheable_;\r
-       std::unique_ptr<boost::any>     storage_;\r
-};\r
-\r
-template<typename T>\r
-class array<const T> sealed\r
-{\r
-public:\r
-\r
-       // Static Members\r
-\r
-       // Constructors\r
-\r
-       template<typename T>\r
-       explicit array(const std::uint8_t* ptr, std::size_t size, bool cacheable, T&& storage)\r
-               : ptr_(ptr)\r
-               , size_(size)\r
-               , cacheable_(cacheable)\r
-               , storage_(new boost::any(std::forward<T>(storage)))\r
-       {\r
-       }\r
-       \r
-       array(const array& other)\r
-               : ptr_(other.ptr_)\r
-               , size_(other.size_)\r
-               , cacheable_(other.cacheable_)\r
-               , storage_(other.storage_)\r
-       {\r
-               CASPAR_ASSERT(storage_);\r
-       }\r
-\r
-       array(array<T>&& other)\r
-               : ptr_(other.ptr_)\r
-               , size_(other.size_)\r
-               , cacheable_(other.cacheable_)\r
-               , storage_(std::move(other.storage_))\r
-       {\r
-               CASPAR_ASSERT(storage_);\r
-       }\r
-\r
-       // Methods\r
-\r
-       array& operator=(array other)\r
-       {\r
-               other.swap(*this);\r
-               return *this;\r
-       }\r
-\r
-       void swap(array& other)\r
-       {\r
-               std::swap(ptr_, other.ptr_);\r
-               std::swap(size_, other.size_);\r
-               std::swap(storage_,     other.storage_);\r
-               std::swap(cacheable_, other.cacheable_);\r
-       }\r
-\r
-       // Properties\r
-                       \r
-       const T* begin() const          {return ptr_;}          \r
-       const T* data() const           {return ptr_;}\r
-       const T* end() const            {return reinterpret_cast<const T*>(reinterpret_cast<const char*>(ptr_) + size_);}\r
-       std::size_t size() const        {return size_;}\r
-       bool empty() const                      {return size() == 0;}\r
-       bool cacheable() const          {return cacheable_;}\r
-       \r
-       template<typename T>\r
-       T storage() const\r
-       {\r
-               return boost::any_cast<T>(*storage_);\r
-       }\r
-\r
-private:\r
-       const T*        ptr_;\r
-       std::size_t     size_;\r
-       bool            cacheable_;\r
-       std::shared_ptr<boost::any>     storage_;\r
-};\r
-\r
-}\r
-\r
-namespace std {\r
-       \r
-template<typename T>\r
-void swap(caspar::array<const T>& lhs, caspar::array<const T>& rhs)\r
-{\r
-       lhs.swap(rhs);\r
-}\r
-\r
-}\r
-\r
+#pragma once
+
+#include "memory.h"
+#include "forward.h"
+
+#include <boost/any.hpp>
+
+#include <cstddef>
+#include <cstdint>
+
+#include "assert.h"
+
+namespace caspar {
+       
+template<typename T>
+class array final
+{
+       array(const array<T>&);
+       array& operator=(const array<T>&);
+
+       template<typename> friend class array;
+public:
+
+       // Boost Range support
+
+       typedef T*                      iterator;
+       typedef const T*        const_iterator;
+
+       // Static Members
+
+       // Constructors
+       
+       template<typename T2>
+       explicit array(T* ptr, std::size_t size, bool cacheable, T2&& storage)
+               : ptr_(ptr)
+               , size_(size)
+               , cacheable_(cacheable)
+               , storage_(new boost::any(std::forward<T2>(storage)))
+       {
+       }
+
+       array(array&& other)
+               : ptr_(other.ptr_)
+               , size_(other.size_)
+               , cacheable_(other.cacheable_)
+               , storage_(std::move(other.storage_))
+       {
+               CASPAR_ASSERT(storage_);
+       }
+
+       // Methods
+       
+       array& operator=(array&& other)
+       {
+               std::swap(ptr_, other.ptr_);
+               std::swap(size_, other.size_);
+               std::swap(storage_,     other.storage_);
+               std::swap(cacheable_, other.cacheable_);
+
+               CASPAR_ASSERT(storage_);
+
+               return *this;
+       }
+
+       // Properties   
+                       
+       T* begin() const                        {return ptr_;}          
+       T* data() const                         {return ptr_;}
+       T* end() const                          {return ptr_ + size_;}
+       std::size_t size() const        {return size_;}
+       bool empty() const                      {return size() == 0;}
+       bool cacheable() const          {return cacheable_;}
+       
+       template<typename T2>
+       T2* storage() const
+       {
+               return boost::any_cast<T2>(storage_.get());
+       }
+private:
+       T*                                                      ptr_;
+       std::size_t                                     size_;
+       bool                                            cacheable_;
+       std::unique_ptr<boost::any>     storage_;
+};
+
+template<typename T>
+class array<const T> final
+{
+public:
+
+       // Boost Range support
+
+       typedef const T*        iterator;
+       typedef const T*        const_iterator;
+
+       // Static Members
+
+       // Constructors
+       array() = default; // Needed by std::future
+
+       template<typename T2>
+       explicit array(const T* ptr, std::size_t size, bool cacheable, T2&& storage)
+               : ptr_(ptr)
+               , size_(size)
+               , cacheable_(cacheable)
+               , storage_(new boost::any(std::forward<T2>(storage)))
+       {
+       }
+
+       explicit array(const T* ptr, std::size_t size, bool cacheable)
+               : ptr_(ptr)
+               , size_(size)
+               , cacheable_(cacheable)
+               , storage_(new boost::any)
+       {
+       }
+
+       array(const array& other)
+               : ptr_(other.ptr_)
+               , size_(other.size_)
+               , cacheable_(other.cacheable_)
+               , storage_(other.storage_)
+       {
+               CASPAR_ASSERT(storage_);
+       }
+
+       array(array<T>&& other)
+               : ptr_(other.ptr_)
+               , size_(other.size_)
+               , cacheable_(other.cacheable_)
+               , storage_(std::move(other.storage_))
+       {
+               CASPAR_ASSERT(storage_);
+       }
+
+       // Methods
+
+       array& operator=(array other)
+       {
+               other.swap(*this);
+               return *this;
+       }
+
+       void swap(array& other)
+       {
+               std::swap(ptr_, other.ptr_);
+               std::swap(size_, other.size_);
+               std::swap(storage_,     other.storage_);
+               std::swap(cacheable_, other.cacheable_);
+       }
+
+       // Properties
+                       
+       const T* begin() const          {return ptr_;}          
+       const T* data() const           {return ptr_;}
+       const T* end() const            {return ptr_ + size_;}
+       std::size_t size() const        {return size_;}
+       bool empty() const                      {return size() == 0;}
+       bool cacheable() const          {return cacheable_;}
+       
+       template<typename T2>
+       T2* storage() const
+       {
+               return boost::any_cast<T2>(storage_.get());
+       }
+
+private:
+       const T*                                        ptr_            = nullptr;
+       std::size_t                                     size_           = 0;
+       bool                                            cacheable_      = false;
+       std::shared_ptr<boost::any>     storage_;
+};
+
+}
+
+namespace std {
+       
+template<typename T>
+void swap(caspar::array<const T>& lhs, caspar::array<const T>& rhs)
+{
+       lhs.swap(rhs);
+}
+
+}
+