libcruft-util/array/varray.hpp
Danny Robson fdaa5e1392 assert: split CHECK_LIMIT into INCLUSIVE and INDEX
LIMIT hid an off-by-one bug when tests used end iterators. We rename the
assertion to uncover all uses of the flawed implementation, and split it
into an identical assertion, and one intended to protect against
iterator ends.
2020-09-24 08:03:41 +10:00

85 lines
2.4 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include "../debug/assert.hpp"
#include <array>
#include <cstddef>
#include <iterator>
namespace cruft {
/// A view of a compile-time sized array.
///
/// \tparam S the number of elements
/// \tparam T the data type of the elements
template <std::size_t S, typename T>
class varray {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using reference_type = T&;
using pointer = T*;
using difference_type = std::size_t;
using size_type = std::size_t;
//---------------------------------------------------------------------
varray (varray const &rhs)
: m_data (rhs.m_data)
{ ; }
//-------------------------------------------------------------------------
varray (std::array<T,S> &rhs)
: m_data (std::data (rhs))
{ ; }
varray (std::array<T,S> &&) = delete;
//-------------------------------------------------------------------------
varray (T (&_data)[S])
: m_data (_data)
{ ; }
template <typename ContainerT>
varray (ContainerT &_container)
: varray (_container.data ())
{ CHECK_GE (_container.size (), size ()); }
//---------------------------------------------------------------------
std::size_t size (void) const { return S; }
T& operator[] (std::size_t i) { CHECK_INDEX (i, S); return m_data[i]; }
const T& operator[] (std::size_t i) const { CHECK_INDEX (i, S); return m_data[i]; }
auto data (void) { return m_data; }
auto data (void) const { return m_data; }
auto begin (void) { return data (); }
auto end (void) { return data () + size (); }
auto begin (void) const { return data (); }
auto end (void) const { return data () + size (); }
auto cbegin (void) const { return data (); }
auto cend (void) const { return data () + size (); }
private:
T *m_data;
};
template <typename T, std::size_t S>
varray (T(&)[S]) -> varray<S,T>;
}