ArrayList.hpp
Go to the documentation of this file.
1 /*
2  * Original work Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
3  * Modified work Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  * 1. The origin of this software must not be misrepresented; you must not
12  * claim that you wrote the original software. If you use this software
13  * in a product, an acknowledgment in the product documentation would be
14  * appreciated but is not required.
15  * 2. Altered source versions must be plainly marked as such, and must not be
16  * misrepresented as being the original software.
17  * 3. This notice may not be removed or altered from any source distribution.
18  */
19 
20 #ifndef PLAYRHO_COMMON_ARRAYLIST_HPP
21 #define PLAYRHO_COMMON_ARRAYLIST_HPP
22 
23 #include <PlayRho/Defines.hpp>
24 
25 #include <array>
26 #include <cassert>
27 #include <initializer_list>
28 #include <type_traits>
29 
30 namespace playrho
31 {
33  template <typename VALUE_TYPE, std::size_t MAXSIZE, typename SIZE_TYPE = std::size_t>
34  class ArrayList
35  {
36  public:
38  using size_type = SIZE_TYPE;
39 
41  using value_type = VALUE_TYPE;
42 
45 
47  using const_reference = const value_type&;
48 
50  using pointer = value_type*;
51 
53  using const_pointer = const value_type*;
54 
55  PLAYRHO_CONSTEXPR inline ArrayList() noexcept
56  {
57  // Intentionally empty.
58  // Note that defaulting this method instead of writing it out here,
59  // causes issues with gcc.
60  }
61 
62  template <std::size_t COPY_MAXSIZE, typename COPY_SIZE_TYPE, typename = std::enable_if_t< COPY_MAXSIZE <= MAXSIZE >>
63  PLAYRHO_CONSTEXPR inline explicit ArrayList(const ArrayList<VALUE_TYPE, COPY_MAXSIZE, SIZE_TYPE>& copy):
64  m_size{size(copy)},
65  m_elements{data(copy)}
66  {
67  // Intentionally empty
68  }
69 
71  template <std::size_t COPY_MAXSIZE, typename COPY_SIZE_TYPE, typename = std::enable_if_t< COPY_MAXSIZE <= MAXSIZE >>
72  ArrayList& operator= (const ArrayList<VALUE_TYPE, COPY_MAXSIZE, COPY_SIZE_TYPE>& copy)
73  {
74  m_size = static_cast<SIZE_TYPE>(size(copy));
75  m_elements = data(copy);
76  return *this;
77  }
78 
79  template <std::size_t SIZE, typename = std::enable_if_t< SIZE <= MAXSIZE >>
80  explicit ArrayList(value_type (&value)[SIZE]) noexcept
81  {
82  for (auto&& elem: value)
83  {
84  push_back(elem);
85  }
86  }
87 
88  ArrayList(std::initializer_list<value_type> list)
89  {
90  for (auto&& elem: list)
91  {
92  push_back(elem);
93  }
94  }
95 
96  PLAYRHO_CONSTEXPR inline ArrayList& Append(const value_type& value)
97  {
98  push_back(value);
99  return *this;
100  }
101 
102  PLAYRHO_CONSTEXPR inline void push_back(const value_type& value) noexcept
103  {
104  assert(m_size < MAXSIZE);
105  m_elements[m_size] = value;
106  ++m_size;
107  }
108 
109  void size(size_type value) noexcept
110  {
111  assert(value <= MAXSIZE);
112  m_size = value;
113  }
114 
115  void clear() noexcept
116  {
117  m_size = 0;
118  }
119 
120  bool empty() const noexcept { return m_size == 0; }
121 
122  bool add(value_type value) noexcept
123  {
124  if (m_size < MAXSIZE)
125  {
126  m_elements[m_size] = value;
127  ++m_size;
128  return true;
129  }
130  return false;
131  }
132 
133  reference operator[](size_type index) noexcept
134  {
135  assert(index < MAXSIZE);
136  return m_elements[index];
137  }
138 
139  PLAYRHO_CONSTEXPR inline const_reference operator[](size_type index) const noexcept
140  {
141  assert(index < MAXSIZE);
142  return m_elements[index];
143  }
144 
149  PLAYRHO_CONSTEXPR inline size_type size() const noexcept { return m_size; }
150 
153  PLAYRHO_CONSTEXPR inline size_type max_size() const noexcept { return MAXSIZE; }
154 
155  auto data() const noexcept { return m_elements.data(); }
156 
157  pointer begin() noexcept { return m_elements.data(); }
158  pointer end() noexcept { return m_elements.data() + m_size; }
159 
160  const_pointer begin() const noexcept { return m_elements.data(); }
161  const_pointer end() const noexcept { return m_elements.data() + m_size; }
162 
163  private:
164  size_type m_size = size_type{0};
165  std::array<value_type,MAXSIZE> m_elements;
166  };
167 
169  template <typename T, std::size_t S>
171  {
172  lhs.push_back(rhs);
173  return lhs;
174  }
175 
177  template <typename T, std::size_t S>
179  {
180  lhs.push_back(rhs);
181  return lhs;
182  }
183 
184 } /* namespace playrho */
185 
186 namespace std {
187 
189  template< class T, std::size_t N, typename SIZE_TYPE >
190  class tuple_size< playrho::ArrayList<T, N, SIZE_TYPE> >: public integral_constant<std::size_t, N>
191  {
192  // Intentionally empty.
193  };
194 
195 } // namespace std
196 
197 #endif // PLAYRHO_COMMON_ARRAYLIST_HPP