Bond
 
Loading...
Searching...
No Matches
simple_array.h
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#pragma once
5
6#include <bond/core/config.h>
7
8#include <boost/static_assert.hpp>
9
10#include <limits>
11#include <new>
12#include <stdexcept>
13#include <string.h>
14
15namespace bond
16{
17namespace detail
18{
19
20template <typename T, uint32_t N = 64>
21class SimpleArray
22{
23public:
24 SimpleArray()
25 : _size(0),
26 _capacity(N),
27 _data(_insitu)
28 {
29 BOOST_STATIC_ASSERT(N != 0);
30 }
31
32 ~SimpleArray()
33 {
34 memfree();
35 }
36
37 uint32_t size() const
38 {
39 return _size;
40 }
41
42 const T* begin() const
43 {
44 return _data;
45 }
46
47 T pop()
48 {
49 if (_size == 0)
50 {
51 throw std::underflow_error("Can't pop empty array");
52 }
53 return _data[--_size];
54 }
55
56 T& operator[](uint32_t i)
57 {
58 return _data[i];
59 }
60
61 void push(T x)
62 {
63 if (_size < _capacity)
64 _data[_size++] = x;
65 else
66 grow(x);
67 }
68
69private:
70 void grow(T x)
71 {
72 // cap elements to prevent overflow
73 if (_capacity >= ((std::numeric_limits<uint32_t>::max)() >> 1))
74 {
75 throw std::bad_alloc();
76 }
77
78 T* new_data = new T[_capacity <<= 1];
79 memcpy(new_data, _data, _size * sizeof(T));
80 memfree();
81 (_data = new_data)[_size++] = x;
82 }
83
84 void memfree()
85 {
86 if (_data != _insitu)
87 {
88 delete [] _data;
89 _data = nullptr;
90 }
91 }
92
93 BOOST_STATIC_ASSERT(std::is_pod<T>::value);
94
95 uint32_t _size;
96 uint32_t _capacity;
97 T _insitu[N];
98 T* _data;
99};
100
101} // namespace detail
102} // namespace bond
namespace bond
Definition: apply.h:17