// // Array.h // // Library: Foundation // Package: Core // Module: Array // // Definition of the Array class // // Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH. // and Contributors. // // SPDX-License-Identifier: BSL-1.0 // // ------------------------------------------------------------------------------ // (C) Copyright Nicolai M. Josuttis 2001. // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // ------------------------------------------------------------------------------ #ifndef Foundation_Array_INCLUDED #define Foundation_Array_INCLUDED #include #include "Poco/Bugcheck.h" #include "Poco/Exception.h" namespace Poco { template class Array /// STL container like C-style array replacement class. /// /// This implementation is based on the idea of Nicolai Josuttis. /// His original implementation can be found at http://www.josuttis.com/cppcode/array.html . { public: typedef T value_type; typedef T * iterator; typedef const T * const_iterator; typedef T & reference; typedef const T & const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; iterator begin() { return elems; } const_iterator begin() const { return elems; } iterator end() { return elems + N; } const_iterator end() const { return elems + N; } typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } reference operator[](size_type i) /// Element access without range check. If the index is not small than the given size, the behavior is undefined. { poco_assert(i < N && "out of range"); return elems[i]; } const_reference operator[](size_type i) const /// Element access without range check. If the index is not small than the given size, the behavior is undefined. { poco_assert(i < N && "out of range"); return elems[i]; } reference at(size_type i) /// Element access with range check. Throws Poco::InvalidArgumentException if the index is over range. { if (i >= size()) throw Poco::InvalidArgumentException("Array::at() range check failed: index is over range"); return elems[i]; } const_reference at(size_type i) const /// Element access with range check. Throws Poco::InvalidArgumentException if the index is over range. { if (i >= size()) throw Poco::InvalidArgumentException("Array::at() range check failed: index is over range"); return elems[i]; } reference front() { return elems[0]; } const_reference front() const { return elems[0]; } reference back() { return elems[N - 1]; } const_reference back() const { return elems[N - 1]; } static size_type size() { return N; } static bool empty() { return false; } static size_type max_size() { return N; } enum { static_size = N }; void swap(Array & y) { std::swap_ranges(begin(), end(), y.begin()); } const T * data() const /// Direct access to data (read-only) { return elems; } T * data() { return elems; } T * c_array() { /// Use array as C array (direct read/write access to data) return elems; } template Array & operator=(const Array & rhs) /// Assignment with type conversion { std::copy(rhs.begin(), rhs.end(), begin()); return *this; } void assign(const T & value) /// Assign one value to all elements { std::fill_n(begin(), size(), value); } public: T elems[N]; /// Fixed-size array of elements of type T, public specifier used to make this class a aggregate. }; // comparisons template bool operator==(const Array & x, const Array & y) { return std::equal(x.begin(), x.end(), y.begin()); } template bool operator<(const Array & x, const Array & y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } template bool operator!=(const Array & x, const Array & y) { return !(x == y); } template bool operator>(const Array & x, const Array & y) { return y < x; } template bool operator<=(const Array & x, const Array & y) { return !(y < x); } template bool operator>=(const Array & x, const Array & y) { return !(x < y); } template inline void swap(Array & x, Array & y) /// global swap() { x.swap(y); } } // namespace Poco #endif // Foundation_Array_INCLUDED