Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
FlexGrid.hpp
Go to the documentation of this file.
00001 
00014 #ifndef FLEXGRID_HPP
00015 #define FLEXGRID_HPP
00016 
00017 #include <deque>
00018 #include <stdexcept>
00019 #include <iterator>
00020 
00021 #include <sys/types.h>
00022 
00023 namespace jafar {
00024   namespace lgl {
00025 
00026     /* 
00027      * Copyright (C) 2007 Roland Philippsen <roland dot philippsen at gmx net>
00028      * 
00029      * This program is free software; you can redistribute it and/or modify
00030      * it under the terms of the GNU General Public License as published by
00031      * the Free Software Foundation; either version 2 of the License, or
00032      * (at your option) any later version.
00033      * 
00034      * This program is distributed in the hope that it will be useful,
00035      * but WITHOUT ANY WARRANTY; without even the implied warranty of
00036      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00037      * GNU General Public License for more details.
00038      * 
00039      * You should have received a copy of the GNU General Public License
00040      * along with this program; if not, write to the Free Software
00041      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00042      * USA
00043      */ 
00044 
00045     // ==================================================
00046     // copy-pasted from estar/sdeque.hpp
00047     // ==================================================
00048     template<typename value_t>
00049     class sdeque
00050     {
00051       public:
00052         typedef std::deque<value_t> deque_t;
00053         typedef typename deque_t::iterator iterator;
00054         typedef typename deque_t::const_iterator const_iterator;
00055 
00056         sdeque(): m_ibegin(0), m_iend(0) {}
00057 
00058         sdeque(sdeque const & orig)
00059           : m_ibegin(orig.m_ibegin), m_iend(orig.m_iend), m_deque(orig.m_deque) {}
00060 
00061         value_t & at(ssize_t ii)
00062         { return m_deque.at(static_cast<size_t>(ii - m_ibegin)); }
00063 
00064         value_t const & at(ssize_t ii) const
00065         { return m_deque.at(static_cast<size_t>(ii - m_ibegin)); }
00066 
00067         void resize_begin(ssize_t ibegin, value_t const & value) {
00068           if (ibegin > m_iend)
00069             throw std::out_of_range("estar::sdeque::resize_begin() range error");
00070           ssize_t delta(m_ibegin - ibegin);
00071           m_ibegin = ibegin;
00072           if (0 < delta)
00073             m_deque.insert(m_deque.begin(), static_cast<size_t>(delta), value);
00074           else if (0 > delta)
00075             m_deque.erase(m_deque.begin(),
00076                           m_deque.begin() + static_cast<size_t>(-delta));
00077           // else nothing to do
00078         }
00079 
00080         void resize_begin(ssize_t ibegin) { resize_begin(ibegin, value_t()); }
00081 
00082         void resize_end(ssize_t iend, value_t const & value) {
00083           if (iend < m_ibegin)
00084             throw std::out_of_range("estar::sdeque::resize_end() range error");
00085           m_iend = iend;
00086           m_deque.resize(static_cast<size_t>(m_iend - m_ibegin), value);
00087         }
00088 
00089         void resize_end(ssize_t iend) { resize_end(iend, value_t()); }
00090 
00094         void resize(ssize_t ibegin, ssize_t iend, value_t const & value) {
00095           resize_begin(ibegin, value);
00096           resize_end(iend, value);
00097         }
00098 
00099         void resize(ssize_t ibegin, ssize_t iend)
00100         { resize(ibegin, iend, value_t()); }
00101 
00102         ssize_t ibegin() const { return m_ibegin; }
00103 
00104         ssize_t iend() const { return m_iend; }
00105 
00106         deque_t const & get() const { return m_deque; }
00107 
00108         iterator begin() { return m_deque.begin(); }
00109 
00110         const_iterator begin() const { return m_deque.begin(); }
00111 
00112         iterator end() { return m_deque.end(); }
00113 
00114         const_iterator end() const { return m_deque.end(); }
00115 
00116       protected:
00117         ssize_t m_ibegin, m_iend;
00118         deque_t m_deque;
00119     };
00120 
00121 
00122     // ==================================================
00123     // copy-pasted from estar/flexgrid_traits.hpp
00124     // ==================================================
00125 
00126 
00127     template<typename value_t>
00128     class flexgrid_traits
00129     {
00130       public:
00131         typedef sdeque<value_t> line_t;
00132         typedef typename line_t::iterator cell_iterator;
00133         typedef typename line_t::const_iterator const_cell_iterator;
00134 
00135         typedef sdeque<line_t> grid_t;
00136         typedef typename grid_t::iterator line_iterator;
00137         typedef typename grid_t::const_iterator const_line_iterator;
00138     };
00139 
00140 
00141     // ==================================================
00142     // copy-pasted from estar/flexgrid_iterator.hpp
00143     // ==================================================
00144 
00145 
00146     template<typename blah>
00147     struct flexgrid_iterator_traits {
00148       typedef flexgrid_traits<blah> traits;
00149       typedef blah value_t;
00150       typedef value_t * pointer_t;
00151       typedef value_t & reference_t;
00152       typedef typename traits::grid_t & grid_ref_t;
00153       typedef typename traits::line_t & line_ref_t;
00154     };
00155 
00156 
00157     template<typename blah>
00158     struct flexgrid_const_iterator_traits {
00159       typedef flexgrid_traits<blah> traits;
00160       typedef blah value_t;
00161       typedef value_t const * pointer_t;
00162       typedef value_t const & reference_t;
00163       typedef typename traits::grid_t const & grid_ref_t;
00164       typedef typename traits::line_t const & line_ref_t;
00165     };
00166 
00167 
00168     template<typename value_t, typename traits>
00169     class base_flexgrid_iterator
00170     {
00171       public:
00172         // shortcut
00173         typedef base_flexgrid_iterator<value_t, traits> self;
00174 
00175         // for std iterator compliance... needed?
00176         typedef std::bidirectional_iterator_tag iterator_category;
00177         typedef typename traits::value_t        value_type;
00178         typedef typename std::ptrdiff_t         difference_type;
00179         typedef typename traits::pointer_t      pointer;
00180         typedef typename traits::reference_t    reference;
00181 
00182         // for const / non-const
00183         typedef typename traits::grid_ref_t     grid_ref_t;
00184         typedef typename traits::line_ref_t     line_ref_t;
00185 
00186 
00187         base_flexgrid_iterator(grid_ref_t grid, line_ref_t line,
00188                                ssize_t ix, ssize_t iy)
00189           : m_grid(grid), m_line(line), m_ix(ix), m_iy(iy) {}
00190 
00191         base_flexgrid_iterator(base_flexgrid_iterator const & orig)
00192           : m_grid(orig.m_grid), m_line(orig.m_line),
00193             m_ix(orig.m_ix), m_iy(orig.m_iy) {}
00194 
00195         bool at_end() const
00196         { return (m_ix >= xend()) || (m_iy >= yend()); }
00197 
00198         bool at_begin() const
00199         { return (m_ix <= xbegin()) && (m_iy <= ybegin()); }
00200 
00201         reference operator*() const
00202         { return m_grid.at(m_iy).at(m_ix); }
00203 
00204         pointer operator->() const
00205         { return &(m_grid.at(m_iy).at(m_ix)); }
00206 
00207         self & operator++() {
00208           increment();
00209           return *this;
00210         }
00211 
00212         self operator++(int) {
00213           self tmp(*this);
00214           increment();
00215           return tmp;
00216         }
00217 
00218         self & operator--() {
00219           decrement();
00220           return *this;
00221         }
00222 
00223         self operator--(int) {
00224           self tmp(*this);
00225           decrement();
00226           return tmp;
00227         }
00228 
00229         template<typename other_t>
00230         bool operator==(other_t const & other) const {
00231           if (&m_grid != &other.m_grid)
00232             return false;
00233           if (at_end() && other.at_end())
00234             return true;
00235           if (at_begin() && other.at_begin())
00236             return true;
00237           return (m_ix == other.m_ix) && (m_iy == other.m_iy);
00238         }
00239 
00240         template<typename other_t>
00241         bool operator!=(other_t const & other) const
00242         { return ! (*this == other); }
00243 
00245         grid_ref_t m_grid;
00246         line_ref_t m_line;
00247         ssize_t m_ix, m_iy;
00248 
00249         ssize_t xend() const { return m_line.iend(); }
00250         ssize_t xbegin() const { return m_line.ibegin(); }
00251         ssize_t yend() const { return m_grid.iend(); }
00252         ssize_t ybegin() const { return m_grid.ibegin(); }
00253 
00254         void increment() {
00255           if (at_end())
00256             return;
00257           if (at_begin()) {
00258             m_ix = xbegin() + 1;
00259             m_iy = ybegin();
00260             return;
00261           }
00262           ++m_ix;
00263           if (m_ix >= xend()) {
00264             ++m_iy;
00265             if (m_iy >= yend())
00266               return;   // at end
00267             m_ix = xbegin();
00268           }
00269         }
00270 
00271         void decrement() {
00272           if (at_begin())
00273             return;
00274           if (at_end()) {
00275             m_ix = xend() - 1;
00276             m_iy = yend() - 1;
00277             return;
00278           }
00279           --m_ix;
00280           if (m_ix < xbegin()) {
00281             --m_iy;
00282             if (m_iy < ybegin())
00283               return;   // at begin
00284             m_ix = xend() - 1;
00285           }
00286         }
00287     };
00288 
00289 
00290     template<typename value_t>
00291     class flexgrid_iterator
00292       : public base_flexgrid_iterator<value_t, flexgrid_iterator_traits<value_t> >
00293     {
00294       public:
00295         typedef base_flexgrid_iterator<value_t, flexgrid_iterator_traits<value_t> > base;
00296 
00297         typedef typename base::grid_ref_t grid_ref_t;
00298         typedef typename base::line_ref_t line_ref_t;
00299 
00300         flexgrid_iterator(grid_ref_t grid, line_ref_t line, ssize_t ix, ssize_t iy)
00301           : base(grid, line, ix, iy) {}
00302 
00303         flexgrid_iterator(flexgrid_iterator const & orig)
00304           : base(orig) {}
00305     };
00306 
00307 
00308     template<typename value_t>
00309     class const_flexgrid_iterator
00310       : public base_flexgrid_iterator<value_t, flexgrid_const_iterator_traits<value_t> >
00311     {
00312       public:
00313         typedef
00314         base_flexgrid_iterator<value_t, flexgrid_const_iterator_traits<value_t> > base;
00315 
00316         typedef typename base::grid_ref_t grid_ref_t;
00317         typedef typename base::line_ref_t line_ref_t;
00318 
00319         const_flexgrid_iterator(grid_ref_t grid, line_ref_t line,
00320                                 ssize_t ix, ssize_t iy)
00321           : base(grid, line, ix, iy) {}
00322 
00323         const_flexgrid_iterator(const_flexgrid_iterator const & orig)
00324           : base(orig) {}
00325 
00326         const_flexgrid_iterator(flexgrid_iterator<value_t> const & orig)
00327           : base(reinterpret_cast<base const &>(orig)) {}
00328     };
00329 
00330 
00331     // ==================================================
00332     // copy-pasted from estar/flexgrid.hpp
00333     // ==================================================
00334 
00335     template<typename value_t>
00336     class FlexGrid
00337     {
00338       public:
00339         typedef flexgrid_traits<value_t>             traits;
00340         typedef typename traits::line_t              line_t;
00341         typedef typename traits::cell_iterator       cell_iterator;
00342         typedef typename traits::const_cell_iterator const_cell_iterator;
00343         typedef typename traits::grid_t              grid_t;
00344         typedef typename traits::line_iterator       line_iterator;
00345         typedef typename traits::const_line_iterator const_line_iterator;
00346         typedef flexgrid_iterator<value_t>           iterator;
00347         typedef const_flexgrid_iterator<value_t>     const_iterator;
00348 
00349         bool set(ssize_t ix, ssize_t iy, value_t const & value) { 
00350           if (!valid(ix,iy)) {
00351             return false;
00352           }
00353           
00354           m_grid.at(iy).at(ix) = value;
00355 
00356           return true;
00357           
00358         }
00359 
00360         value_t & at(ssize_t ix, ssize_t iy) { return m_grid.at(iy).at(ix); }
00361 
00362         value_t const & at(ssize_t ix, ssize_t iy) const
00363         { return m_grid.at(iy).at(ix); }
00364 
00365         value_t get(ssize_t ix, ssize_t iy) { 
00366           return m_grid.at(iy).at(ix); 
00367         }
00368 
00369         void resize_xbegin(ssize_t xbegin, value_t const & value) {
00370           for (line_iterator ii(m_grid.begin()); ii != m_grid.end(); ++ii)
00371             ii->resize_begin(xbegin, value);
00372           m_default.resize_begin(xbegin);
00373         }
00374 
00375         void resize_xbegin(ssize_t xbegin) { resize_xbegin(xbegin, value_t()); }
00376 
00377         void resize_xend(ssize_t xend, value_t const & value) {
00378           for (line_iterator ii(m_grid.begin()); ii != m_grid.end(); ++ii)
00379             ii->resize_end(xend, value);
00380           m_default.resize_end(xend);
00381         }
00382 
00383         void resize_xend(ssize_t xend) { resize_xend(xend, value_t()); }
00384 
00385         void resize_x(ssize_t xbegin, ssize_t xend, value_t const & value) {
00386           if (xbegin < m_default.ibegin())
00387             resize_xbegin(xbegin, value);
00388           if (xend > m_default.iend())
00389             resize_xend(xend, value);
00390         }
00391 
00392         void resize_x(ssize_t xbegin, ssize_t xend) {
00393           if (xbegin < m_default.ibegin())
00394             resize_xbegin(xbegin);
00395           if (xend > m_default.iend())
00396             resize_xend(xend);
00397         }
00398 
00401         void resize_ybegin(ssize_t ybegin, value_t const & value) {
00402           if (ybegin > m_grid.ibegin()) // shrink
00403             m_grid.resize_begin(ybegin, m_default);
00404           else if (ybegin < m_grid.ibegin()) { // grow
00405             line_t vline(m_default);
00406             fill(vline.begin(), vline.end(), value);
00407             m_grid.resize_begin(ybegin, vline);
00408           }
00409           // else do nothing
00410         }
00411 
00412         void resize_ybegin(ssize_t ybegin)
00413         { m_grid.resize_begin(ybegin, m_default); }
00414 
00417         void resize_yend(ssize_t yend, value_t const & value) {
00418           if (yend < m_grid.iend()) // shrink
00419             m_grid.resize_end(yend, m_default);
00420           else if (yend > m_grid.iend()) { // grow
00421             line_t vline(m_default);
00422             fill(vline.begin(), vline.end(), value);
00423             m_grid.resize_end(yend, vline);
00424           }
00425           // else do nothing
00426         }
00427 
00428         void resize_yend(ssize_t yend)
00429         { m_grid.resize_end(yend, m_default); }
00430 
00431         void resize_y(ssize_t ybegin, ssize_t yend, value_t const & value) {
00432           if (ybegin < m_grid.ibegin())
00433             resize_ybegin(ybegin, value);
00434           if (yend > m_grid.iend())
00435             resize_yend(yend, value);
00436         }
00437 
00438         void resize_y(ssize_t ybegin, ssize_t yend) {
00439           if (ybegin < m_grid.ibegin())
00440             resize_ybegin(ybegin);
00441           if (yend > m_grid.iend())
00442             resize_yend(yend);
00443         }
00444 
00447         void resize(ssize_t xbegin, ssize_t xend,
00448                     ssize_t ybegin, ssize_t yend,
00449                     value_t const & value) {
00450           if (xbegin < m_default.ibegin())
00451             resize_xbegin(xbegin, value);
00452           if (xend > m_default.iend())
00453             resize_xend(xend, value);
00454           if (ybegin < m_grid.ibegin())
00455             resize_ybegin(ybegin, value);
00456           if (yend > m_grid.iend())
00457             resize_yend(yend, value);
00458         }
00459 
00462         void resize(ssize_t xbegin, ssize_t xend,
00463                     ssize_t ybegin, ssize_t yend) {
00464           if (xbegin < m_default.ibegin())
00465             resize_xbegin(xbegin);
00466           if (xend > m_default.iend())
00467             resize_xend(xend);
00468           if (ybegin < m_grid.ibegin())
00469             resize_ybegin(ybegin);
00470           if (yend > m_grid.iend())
00471             resize_yend(yend);
00472         }
00473 
00474         ssize_t xbegin() const { return m_default.ibegin(); }
00475 
00476         ssize_t xend() const { return m_default.iend(); }
00477 
00478         ssize_t ybegin() const { return m_grid.ibegin(); }
00479 
00480         ssize_t yend() const { return m_grid.iend(); }
00481 
00482         ssize_t x_size() const {
00483           return (xend()-xbegin());
00484         }
00485 
00486         ssize_t y_size() const {
00487           return (yend()-ybegin());
00488         }
00489 
00490         ssize_t size() const {
00491           return (x_size()*y_size());
00492         }
00493 
00496         value_t & smart_at(ssize_t ix, ssize_t iy) {
00497           if (ix < m_default.ibegin())
00498             resize_xbegin(ix);
00499           else if (ix >= m_default.iend())
00500             resize_xend(ix + 1);
00501           if (iy < m_grid.ibegin())
00502             resize_ybegin(iy);
00503           else if (iy >= m_grid.iend())
00504             resize_yend(iy + 1);
00505           return m_grid.at(iy).at(ix);
00506         }
00507 
00508         line_iterator line_begin() { return m_grid.begin(); }
00509 
00510         const_line_iterator line_begin() const { return m_grid.begin(); }
00511 
00512         line_iterator line_end() { return m_grid.end(); }
00513 
00514         const_line_iterator line_end() const { return m_grid.end(); }
00515 
00516         iterator begin() {
00517           return iterator(m_grid, m_default, m_default.ibegin(), m_grid.ibegin());
00518         }
00519 
00520         const_iterator begin() const {
00521           return const_iterator(m_grid, m_default,
00522                                 m_default.ibegin(), m_grid.ibegin());
00523         }
00524 
00525         iterator end()
00526         { return iterator(m_grid, m_default, m_default.iend(), m_grid.iend()); }
00527 
00528         const_iterator end() const {
00529           return const_iterator(m_grid, m_default,
00530                                 m_default.iend(), m_grid.iend());
00531         }
00532 
00533         bool valid(ssize_t ix, ssize_t iy) const {
00534           return (ix >= m_default.ibegin())
00535             &&   (ix <  m_default.iend())
00536             &&   (iy >= m_grid.ibegin())
00537             &&   (iy <  m_grid.iend());
00538         }
00539 
00540         bool valid_range(ssize_t xbegin, ssize_t xend,
00541                          ssize_t ybegin, ssize_t yend) const {
00542           return (xbegin >= m_default.ibegin())
00543             &&   (xend   <= m_default.iend())
00544             &&   (ybegin >= m_grid.ibegin())
00545             &&   (yend   <= m_grid.iend());
00546         }
00547 
00548         bool valid_bbox(ssize_t x0, ssize_t y0, ssize_t x1, ssize_t y1) const {
00549           return (x0 >= m_default.ibegin())
00550             &&   (x1 <  m_default.iend())
00551             &&   (y0 >= m_grid.ibegin())
00552             &&   (y1 <  m_grid.iend());
00553         }
00554 
00555         void clear()
00556         {/*{{{*/
00557           //m_grid.clear();//erase(m_grid.ibegin(), m_grid.iend());
00558           m_grid.resize(0,0);
00559           m_default.resize(0,0);
00560         }/*}}}*/
00561 
00562       protected:
00563         friend class flexgrid_iterator<value_t>;
00564 
00565         grid_t m_grid;
00566         line_t m_default;
00567     };
00568   }
00569 }
00570 
00571 #endif /* FLEXGRID_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:24 for Jafar by doxygen 1.7.6.1
LAAS-CNRS