/* * 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 2010-2018 Danny Robson */ #pragma once #include "../debug/assert.hpp" #include "../cast.hpp" #include #include #include #include namespace cruft { /////////////////////////////////////////////////////////////////////////// /// A pascal style array consisting of a size and a bare pointer. template < typename DataT, typename SizeT = std::size_t > class parray { public: using value_type = DataT; using size_type = SizeT; using reference = DataT&; using const_reference = DataT const&; using iterator = DataT*; using const_iterator = DataT const*; using difference_type = std::ptrdiff_t; parray (SizeT size, DataT *data); template explicit parray (DataT (&data)[SizeV]): parray (SizeV, data+0) { ; } parray (parray const&) noexcept = default; parray& operator= (parray const&) noexcept = default; parray (parray &&) noexcept = default; parray& operator= (parray &&) noexcept = default; // Only allows shrinking currently. void resize (SizeT count) { CHECK_LE (count, m_size); for (auto cursor = count; cursor < m_size; ++cursor) m_data[cursor].~DataT (); m_size = count; } DataT& operator[] (SizeT idx); const DataT& operator[] (SizeT idx) const; DataT& at (SizeT idx); const DataT& at (SizeT idx) const; DataT* begin (void); DataT* end (void); DataT const* begin (void) const { return cbegin (); } DataT const* end (void) const { return cend (); } const DataT* cbegin (void) const; const DataT* cend (void) const; const DataT* data (void) const; DataT* data (void); SizeT size (void) const; bool empty (void) const { return size () == 0; } template < typename T = DataT, typename = std::enable_if_t> > DataT* erase (DataT *first, DataT *last) { DataT *newend = std::move (last, m_data + m_size, first); for (auto cursor = newend; cursor != end (); ++cursor) cursor->~DataT (); m_size = cruft::cast::lossless (newend - m_data); return newend; } template < typename T = DataT, typename = std::enable_if_t> > DataT* erase (DataT *item) { return erase (item, item + 1); } private: SizeT m_size; DataT *m_data; }; template bool equal (parray const &a, ValueB const (&b)[SizeB]) { return std::equal ( std::begin (a), std::end (b), std::begin (b), std::end (b) ); } template bool equal (ValueB const (&a)[SizeB], parray const &b) { return std::equal ( std::begin (a), std::end (b), std::begin (b), std::end (b) ); } //------------------------------------------------------------------------- template parray (DataT (&)[SizeV]) -> parray; /////////////////////////////////////////////////////////////////////////// template std::ostream& operator<< (std::ostream&, cruft::parray); //------------------------------------------------------------------------- template std::ostream& operator<< (std::ostream&, cruft::parray); //------------------------------------------------------------------------- template std::ostream& operator<< (std::ostream&, cruft::parray); }