/** * @file ya_array.h * @brief 単純な唯の配列をstl風にしたもの. std::arrary/boost::arrayの変種. * @author tenk* (Masashi Kitamura) * @date 2003-07-19 , 2010 * @note * - UNUSE_THROW が定義されていれば, 例外でなくassertチェックになる. */ #ifndef YA_ARRAY_H #define YA_ARRAY_H #include <cstddef> #include <cassert> #include <iterator> #include <algorithm> #ifndef UNUSE_THROW #include <stdexcept> #endif #if defined __WATCOMC__ || defined __DMC__ #define YA_ARRAY_NO_MEMBER_TEMPLATES // メンバーテンプレートが使えない場合に定義. #endif /// 唯の配列を、stl風にしたもの。 template<class T, unsigned N> class ya_array { T ary_[N]; public: typedef unsigned size_type; typedef std::ptrdiff_t difference_type; typedef T& reference; typedef const T& const_reference; typedef T value_type; typedef T* iterator; typedef const T* const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; //ya_array() { std::fill_n(begin(),size(),T()); } //ya_array(const ya_array& r) { std::copy(r.begin(), r.end(), begin()); } size_type size() const { return N; } size_type max_size() const { return N; } size_type capacity() const { return N; } bool empty() const { return 0; } iterator begin() { return ary_;} const_iterator begin() const { return ary_;} const_iterator cbegin() const { return ary_;} iterator end() { return ary_ + N;} const_iterator end() const { return ary_ + N;} const_iterator cend() const { return ary_ + N;} reverse_iterator rbegin() { return reverse_iterator(ary_ + N);} const_reverse_iterator rbegin() const { return const_reverse_iterator(ary_ + N);} const_reverse_iterator crbegin() const { return const_reverse_iterator(ary_ + N);} reverse_iterator rend() { return reverse_iterator(ary_); } const_reverse_iterator rend() const { return const_reverse_iterator(ary_);} const_reverse_iterator crend() const { return const_reverse_iterator(ary_);} reference front() { return *ary_;} const_reference front() const { return *ary_;} reference back() { return *(ary_ + N - 1); } const_reference back() const { return *(ary_ + N - 1); } reference at(size_type n) { chkOutOfRng(n); return *(ary_ + n);} const_reference at(size_type n) const { chkOutOfRng(n); return *(ary_ + n);} reference operator[](size_type n) { assert(n < N ); return *(ary_ + n);} const_reference operator[](size_type n) const { assert(n < N ); return *(ary_ + n);} void swap(ya_array& x) { for (size_type i = 0; i < N; i++) std::swap(ary_[i], x[i]); } void assign(size_type sz, const T& t=T()) { assert(sz <= N); std::fill_n(begin(), sz, t); } // 比較演算子定義のための内部的な関数 bool operator==(const ya_array& r) const { return std::equal(begin(), end(), r.begin());} bool operator!=(const ya_array& r) const { return !(*this == r); } bool operator< (const ya_array& r) const { return std::lexicographical_compare(begin(),end(),r.begin(),r.end());} bool operator>=(const ya_array& r) const { return !(*this < r); } bool operator> (const ya_array& r) const { return r < *this ; } bool operator<=(const ya_array& r) const { return ! (r < *this); } #ifndef YA_ARRAY_NO_MEMBER_TEMPLATES template <typename T2> ya_array<T,N>& operator= (const ya_array<T2,N>& r) { std::copy(r.begin(),r.end(), begin()); return *this; } template<typename Ite> void assign(Ite b, Ite e) { size_type l = std::distance(b,e); assert(l <= N); std::copy(b,e,begin()); } #else ya_array& operator=(const ya_array& r) { std::copy(r.begin(),r.end(), begin()); return *this; } void assign(const_iterator b, const_iterator e) { size_type l = e-b; assert(l <= N); std::copy(b,e,begin()); } #endif private: #ifdef UNUSE_THROW // 例外投げずassertチェック void chkOutOfRng(size_type n) const { assert(n < N && "invalid array<T,N> subscript\n"); } #else void chkOutOfRng(size_type n) const { if (n >= N) throw std::out_of_range("invalid array<T,N> subscript"); } #endif }; #endif