src/Lib/shttl/array2d.h

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #ifndef SHTTL_ARRAY2D_H
00033 #define SHTTL_ARRAY2D_H
00034 
00035 #include <cmath>
00036 #include <limits>
00037 #include <stdexcept>
00038 #include <iterator>
00039 #include <memory>
00040 
00041 #include "shttl_types.h"
00042 
00043 namespace shttl 
00044 {
00045 
00046 
00047     template<class T, class Allocator = std::allocator<T> >
00048     class array2d 
00049     {
00050     public:
00051 
00052         // Types
00053 
00054         typedef T            value_type;
00055         typedef size_t       size_type;
00056         typedef std::allocator<T> allocator_type;
00057         typedef T&           reference;
00058         typedef const T&     const_reference;
00059         typedef ssize_t      difference_type;
00060         typedef T*           pointer;
00061         typedef const T*     const_pointer;
00062 
00063         typedef array2d<T>   this_type;
00064 
00065         static const std::numeric_limits<size_type> size_info;
00066 
00067 
00068     protected:
00069 
00070         // iterators
00071         class _iterator_base 
00072         {
00073         protected:
00074 
00075             size_type  _r;
00076             size_type  _c;
00077 
00078             const size_type  _col;
00079 
00080             // Constructor
00081             _iterator_base(
00082                 const size_type r, 
00083                 const size_type c,
00084                 const size_type col
00085             ) :
00086                 _r(r), _c(c), _col(col)
00087             {
00088             }
00089 
00090         public:
00091 
00092             // Accessors
00093 
00094             size_type row() const  { return _r; }
00095             size_type col() const  { return _c; }
00096 
00097             // Comparing Operators
00098 
00099             bool operator==(const _iterator_base& rhs) const 
00100             {   return  _r == rhs._r && _c == rhs._c;   }
00101             bool operator!=(const _iterator_base& rhs) const 
00102             {   return !(*this == rhs);                 }
00103             bool operator<(const _iterator_base& rhs) const 
00104             {   return std::make_pair(_r, _c) <  std::make_pair(rhs._r, rhs._c);    }
00105             bool operator<=(const _iterator_base& rhs) const  
00106             {   return std::make_pair(_r, _c) <= std::make_pair(rhs._r, rhs._c);    }
00107             bool operator>(const _iterator_base& rhs) const  
00108             {   return std::make_pair(_r, _c) >  std::make_pair(rhs._r, rhs._c);    }
00109             bool operator>=(const _iterator_base& rhs) const  
00110             {   return std::make_pair(_r, _c) >= std::make_pair(rhs._r, rhs._c);    }
00111 
00112             _iterator_base& operator+=(const size_type c) 
00113             {
00114                 const size_type cc = _c + c;
00115                 if (cc < _col) {
00116                     _c = cc;
00117                 } else {
00118                     _c  = cc % _col;
00119                     _r += cc / _col;
00120                 }
00121                 return *this;
00122             }
00123 
00124             _iterator_base& operator-=(const size_type c) 
00125             {
00126                 const size_type cc = _c - c;
00127                 if (cc > 0) {
00128                     _c = cc;
00129                 } else {
00130                     _c  = cc % _col;
00131                     _r += cc / _col;
00132                 }
00133                 return *this;
00134             }
00135         };
00136 
00137     public:
00138 
00139         class const_iterator :
00140             public _iterator_base,
00141             public std::iterator<std::random_access_iterator_tag, T> 
00142         {
00143         private:
00144 
00145             const this_type* const _a;
00146 
00147             using _iterator_base::_r; 
00148             using _iterator_base::_c; 
00149 
00150         public:
00151 
00152             const_iterator(
00153                 const this_type* const a, 
00154                 const size_type r,
00155                 const size_type c
00156             )  :
00157                 _iterator_base(r, c, a->cols()),
00158                 _a(a)
00159             {
00160             }
00161 
00162             bool operator==(const const_iterator& rhs) const  
00163             {
00164                 return _iterator_base::operator==(rhs) && _a == rhs._a;
00165             }
00166 
00167             bool operator!=(const const_iterator& rhs) const  
00168             {
00169                 return _iterator_base::operator!=(rhs) || _a != rhs._a;
00170             }
00171 
00172             const_iterator operator+(const size_type c) const 
00173             {
00174                 const_iterator r = *this;
00175                 return r._iterator_base.operator+=(c);
00176             }
00177 
00178             const_iterator operator-(const size_type c) const 
00179             {
00180                 const_iterator r = *this;
00181                 return r._iterator_base::operator-=(c);
00182             }
00183 
00184             const T& operator[](const size_type c) const
00185             {
00186                 const_iterator i = *this + c;
00187                 return *i;
00188             }
00189             /*
00190             operator const T*(){ 
00191                 if (_r < 0 || _a->rows() < _r ||
00192                     _c < 0 || _a->cols() < _c
00193                 ){
00194                     throw std::out_of_range("array2d::const_iterator::operator T*");
00195                 }
00196 
00197                 return &(_a->_ptr[(_r << _a->_col_bit) + _c]); 
00198             }
00199             */
00200             const_reference operator*()
00201             {
00202             #ifdef SHTTL_DEBUG
00203                 if (_r < 0 || _a->rows() < _r ||
00204                     _c < 0 || _a->cols() < _c
00205                 ){
00206                     throw std::out_of_range("array2d::const_iterator::operator T*");
00207                 }
00208             #endif
00209 
00210                 return _a->_ptr[(_r << _a->_col_bit) + _c]; 
00211             }
00212         };    
00213 
00214 
00215         class iterator :
00216             public _iterator_base,
00217             public std::iterator<std::random_access_iterator_tag, T> 
00218         {
00219         private:
00220 
00221             this_type* const _a;
00222 
00223             using _iterator_base::_r; 
00224             using _iterator_base::_c; 
00225 
00226         public:
00227 
00228             iterator(
00229                 this_type* const a, 
00230                 const size_type r, 
00231                 const size_type c
00232             )  :
00233                 _iterator_base(r, c, a->cols()),
00234                 _a(a) 
00235             {
00236             }
00237 
00238             iterator operator+(const size_type c) const 
00239             {
00240                 iterator r = *this;
00241                 r._iterator_base::operator+=(c);
00242                 return r;
00243             }
00244 
00245             iterator operator-(const size_type c) const 
00246             {
00247                 iterator r = *this;
00248                 r._iterator_base::operaotr-=(c);
00249                 return r;
00250             }
00251 
00252             iterator& operator+=(const size_type c)  
00253             {
00254                 this->_iterator_base::operator+=(c);
00255                 return *this;
00256             }
00257 
00258             iterator& operator-=(const size_type c) 
00259             {
00260                 this->_iterator_base::operator-=(c);
00261                 return *this;
00262             }
00263 
00264             iterator& operator++() 
00265             {
00266                 return *this += 1;
00267             }
00268 
00269             iterator& operator--() 
00270             {
00271                 return *this -= 1;
00272             }
00273 
00274             iterator& operator++(int)  
00275             {
00276                 iterator r = *this;
00277                 *this += 1;
00278                 return r;
00279             }
00280 
00281             iterator& operator--(int)  
00282             {
00283                 iterator r = *this;
00284                 *this -= 1;
00285                 return r;
00286             }
00287 
00288             T& operator[](const size_type c) 
00289             {
00290                 iterator i = *this + c;
00291                 return *i;
00292             }      
00293 
00294             /*
00295             operator T*()
00296             { 
00297                 if (_r < 0 || _a->rows() < _r ||
00298                     _c < 0 || _a->cols() < _c
00299                 ){
00300                     throw stdf::out_of_range("array2d::const_iterator::operator T*");
00301                 }
00302 
00303                 return &(_a->_ptr[(_r << _a->_col_bit) + _c]); 
00304             }*/
00305 
00306             T& operator *()
00307             { 
00308             #ifdef SHTTL_DEBUG
00309                 if (_r < 0 || _a->rows() < _r ||
00310                     _c < 0 || _a->cols() < _c
00311                 ){
00312                     throw std::out_of_range("array2d::const_iterator::operator T*");
00313                 }
00314             #endif
00315 
00316                 return _a->_ptr[(_r << _a->_col_bit) + _c]; 
00317             }
00318         };
00319 
00320     protected:
00321 
00322         // Data Members
00323 
00324         const size_type _row;
00325         const size_type _col;
00326         const size_type _col_bit;
00327 
00328         value_type* const _ptr;
00329 
00330         allocator_type _a;
00331 
00332     public:
00333 
00334         // Accessors
00335 
00336         size_type  rows()      const  { return _row; }
00337         size_type  cols()      const  { return _col; }
00338         size_type  size()      const  { return rows() * cols(); }
00339         size_type  max_size()  const  { return size(); }
00340 
00341 
00342         // Constructors
00343 
00344     private:
00345 
00346         // c    | 1 2 3 4 5 6 7 8 ...
00347         // _c2b | 0 1 2 2 3 3 3 3 ...
00348         // log_2(c) | 0 1   2       3 ...
00349 
00350         size_type _c2b(const size_type c) const
00351         {
00352             if (c <= 0) 
00353                 throw std::invalid_argument("array2d::_c2b");
00354 
00355             const double log2c = log(static_cast<double>(c)) / log(2.0);
00356             return static_cast<size_type>(ceil(log2c));
00357         }
00358 
00359     public:
00360 
00361         explicit array2d(
00362             const size_type c, 
00363             const size_type r, 
00364             const T& t = T()
00365         ) :
00366             _row(r), _col(c),
00367             _col_bit(_c2b(c)),
00368             _ptr(_a.allocate((size_t)r << _col_bit))
00369         {
00370             if (r <= 0 || c <= 0)
00371                 throw std::invalid_argument("array2d::array2d");
00372 
00373             for (size_type i = 0; i < (r << _col_bit); ++i)
00374                 _ptr[i] = t;
00375         }
00376 
00377         ~array2d()
00378         {
00379             for (size_type i = 0; i < (rows() << _col_bit); ++i)
00380                 _a.destroy(_ptr + i);
00381             _a.deallocate(_ptr, (size_t)rows() << _col_bit);
00382         }
00383 
00384         // Reference
00385 
00386         const const_iterator operator[](const size_type r) const 
00387         {
00388         #ifdef SHTTL_DEBUG
00389             if (r < 0 || rows() <= r)
00390                 throw std::out_of_range("array2d::operator[]");
00391         #endif
00392 
00393             return const_iterator(this, r, 0);
00394         }
00395 
00396         iterator operator[](const size_type r) 
00397         {
00398         #ifdef SHTTL_DEBUG
00399             if (r < 0 || rows() <= r)
00400                 throw std::out_of_range("array2d::operator[]");
00401         #endif
00402 
00403             return iterator(this, r, 0);
00404         }
00405 
00406 
00407         // begin() & end()
00408 
00409         const_iterator begin() const  
00410         { 
00411             return const_iteraotr(this,      0, 0);
00412         }
00413         const_iterator end()   const  
00414         { 
00415             return const_iterator(this, size(), 0); 
00416         }
00417         iterator begin() 
00418         { 
00419             return iterator(this,      0, 0); 
00420         }
00421         iterator end()    
00422         { 
00423             return iterator(this, size(), 0); 
00424         }
00425 
00426 
00427         // NOT Supported.
00428 
00429         //     insert() {}
00430         //     erase() {}
00431         //     swap() {}
00432         //     empty() {}
00433         //     clear() {}
00434 
00435     }; // class array2d
00436 
00437 } // namespace shttl
00438 
00439 #endif // SHTTL_ARRAY2D_H

Onikiri2に対してTue Jun 18 14:34:21 2013に生成されました。  doxygen 1.4.7