1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4 
5 #pragma once
6 
7 #include "../lib/vstguibase.h"
8 #include <cstring>
9 
10 namespace VSTGUI {
11 
12 //-----------------------------------------------------------------------------
13 struct MallocAllocator
14 {
15 	static void* allocate (size_t size) { return std::malloc (size); }
16 	static void deallocate (void* ptr, size_t size) { std::free (ptr); }
17 };
18 
19 //-----------------------------------------------------------------------------
20 template <typename T, typename Allocator = MallocAllocator>
21 class Buffer final
22 {
23 public:
24 	Buffer () = default;
25 	Buffer (size_t objectCount) : count (objectCount)
26 	{
27 		if (objectCount)
28 			allocate (objectCount);
29 	}
30 	Buffer (Buffer&& other) { *this = std::move (other); }
31 	Buffer& operator= (Buffer&& other)
32 	{
33 		buffer = other.buffer;
34 		count = other.count;
35 		other.buffer = nullptr;
36 		other.count = 0;
37 		return *this;
38 	}
39 	Buffer (const Buffer&) = delete;
40 	Buffer& operator= (const Buffer&) = delete;
41 	~Buffer () noexcept { deallocate (); }
42 
43 	T* data () { return buffer; }
44 	const T* data () const { return buffer; }
45 	T* get () { return data (); }
46 	const T* get () const { return data (); }
47 	T& operator[] (size_t index) { vstgui_assert (index < count); return buffer[index]; }
48 	const T& operator[] (size_t index) const { vstgui_assert (index < count); return buffer[index]; }
49 	T* begin () noexcept { return buffer; }
50 	T* end () noexcept { return buffer + count; }
51 	const T* begin () const noexcept { return buffer; }
52 	const T* end () const noexcept { return buffer + count; }
53 
54 	size_t size () const { return count; }
55 	bool empty () const { return count == 0; }
56 
57 	void allocate (size_t objectCount)
58 	{
59 		if (count == objectCount)
60 			return;
61 		if (buffer)
62 			deallocate ();
63 		if (objectCount)
64 			buffer = static_cast<T*> (Allocator::allocate (objectCount * sizeof (T)));
65 		count = objectCount;
66 	}
67 
68 	void deallocate ()
69 	{
70 		if (buffer)
71 		{
72 			Allocator::deallocate (buffer, count * sizeof (T));
73 			buffer = nullptr;
74 			count = 0;
75 		}
76 	}
77 
78 private:
79 	T* buffer {nullptr};
80 	size_t count {0};
81 };
82 
83 } // VSTGUI
84