libcruft-util/array/parray.hpp

115 lines
3.1 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 2010-2018 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include <algorithm>
#include <iterator>
#include <cstddef>
#include <iosfwd>
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 (DataT *data, SizeT size);
template <SizeT SizeV>
explicit
parray (DataT (&data)[SizeV]):
parray (data+0, SizeV)
{ ; }
parray (parray const&) noexcept = default;
parray (parray &&) noexcept = default;
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;
private:
DataT *m_data;
SizeT m_size;
};
template <typename ValueA, typename SizeA, typename ValueB, std::size_t SizeB>
bool
equal (parray<ValueA,SizeA> const &a, ValueB const (&b)[SizeB])
{
return std::equal (
std::begin (a), std::end (b),
std::begin (b), std::end (b)
);
}
template <typename ValueA, typename SizeA, typename ValueB, std::size_t SizeB>
bool
equal (ValueB const (&a)[SizeB], parray<ValueA,SizeA> const &b)
{
return std::equal (
std::begin (a), std::end (b),
std::begin (b), std::end (b)
);
}
//-------------------------------------------------------------------------
template <typename DataT, std::size_t SizeV>
parray (DataT (&)[SizeV]) -> parray<DataT,std::size_t>;
///////////////////////////////////////////////////////////////////////////
template <typename SizeT>
std::ostream&
operator<< (std::ostream&, cruft::parray<const char, SizeT>);
//-------------------------------------------------------------------------
template <typename SizeT>
std::ostream&
operator<< (std::ostream&, cruft::parray<char, SizeT>);
//-------------------------------------------------------------------------
template <typename DataT, typename SizeT>
std::ostream&
operator<< (std::ostream&, cruft::parray<DataT, SizeT>);
}