1// vi:set ft=cpp: -*- Mode: C++ -*-
2
3#pragma once
4
5#include "type_traits"
6
7namespace cxx {
8
9/**
10 * Simple encapsulation for a dynamically allocated array.
11 *
12 * The main purpose of this class is to support C++11 range for
13 * for simple dynamically allocated array with static size.
14 */
15template<typename T, typename IDX = unsigned>
16class static_vector
17{
18private:
19  template<typename X, typename IDX2> friend class static_vector;
20  T *_v;
21  IDX _l;
22
23public:
24  typedef T value_type;
25  typedef IDX index_type;
26
27  static_vector() = default;
28  static_vector(value_type *v, index_type length) : _v(v), _l(length) {}
29
30  template<typename Z,
31           typename = typename enable_if<is_same<typename remove_extent<Z>::type, T>::value>::type>
32  constexpr static_vector(Z &v) : _v(v), _l(array_size(v))
33  {}
34
35  /// Conversion from compatible arrays
36  template<typename X,
37           typename = typename enable_if<is_convertible<X, T>::value>::type>
38  static_vector(static_vector<X, IDX> const &o) : _v(o._v), _l(o._l) {}
39
40  index_type size() const { return _l; }
41  bool empty() const { return _l == 0; }
42
43  value_type &operator [] (index_type idx) { return _v[idx]; }
44  value_type const &operator [] (index_type idx) const { return _v[idx]; }
45
46  value_type *begin() { return _v; }
47  value_type *end() { return _v + _l; }
48  value_type const *begin() const { return _v; }
49  value_type const *end() const { return _v + _l; }
50  value_type const *cbegin() const { return _v; }
51  value_type const *cend() const { return _v + _l; }
52
53  /// Get the index of the given element of the array
54  index_type index(value_type const *o) const { return o - _v; }
55  index_type index(value_type const &o) const { return &o - _v; }
56};
57
58}
59