$extrastylesheet
stored_range.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 #ifndef LIBMESH_STORED_RANGE_H
00021 #define LIBMESH_STORED_RANGE_H
00022 
00023 // Local includes
00024 #include "libmesh/threads.h"
00025 
00026 // C++ includes
00027 #include <vector>
00028 
00029 namespace libMesh
00030 {
00031 
00032 
00050 template <typename iterator_type, typename object_type>
00051 class StoredRange
00052 {
00053 public:
00057   typedef typename std::vector<object_type>::const_iterator const_iterator;
00058 
00064   StoredRange (const unsigned int new_grainsize = 1000) :
00065     _end(),
00066     _begin(),
00067     _last(),
00068     _first(),
00069     _grainsize(new_grainsize),
00070     _objs()
00071   {}
00072 
00079   StoredRange (const iterator_type &first,
00080                const iterator_type &last,
00081                const unsigned int new_grainsize = 1000) :
00082     _end(),
00083     _begin(),
00084     _last(),
00085     _first(),
00086     _grainsize(new_grainsize),
00087     _objs()
00088   {
00089     this->reset(first, last);
00090   }
00091 
00105   StoredRange (const StoredRange<iterator_type,object_type> &er):
00106     _end(er._end),
00107     _begin(er._begin),
00108     _last(er._last),
00109     _first(er._first),
00110     _grainsize(er._grainsize),
00111     _objs()
00112   {
00113     // specifically, do *not* copy the vector
00114   }
00115 
00133   StoredRange (const StoredRange<iterator_type,object_type> &er,
00134                const const_iterator &begin_range,
00135                const const_iterator &end_range):
00136     _end(end_range),
00137     _begin(begin_range),
00138     _last(0), // Initialize these in a moment
00139     _first(0),
00140     _grainsize(er._grainsize),
00141     _objs()
00142   {
00143     // specifically, do *not* copy the vector
00144 
00145     _first = std::distance(er._begin, _begin);
00146     _last = _first + std::distance(_begin, _end);
00147   }
00148 
00154   StoredRange (StoredRange<iterator_type,object_type> &r, Threads::split ) :
00155     _end(r._end),
00156     _begin(r._begin),
00157     _last(r._last),
00158     _first(r._first),
00159     _grainsize(r._grainsize),
00160     _objs()
00161   {
00162     const_iterator
00163       beginning = r._begin,
00164       ending    = r._end,
00165       middle    = beginning + std::distance(beginning, ending)/2u;
00166 
00167     r._end = _begin = middle;
00168 
00169     std::size_t
00170       first = r._first,
00171       last  = r._last,
00172       half  = first + (last-first)/2u;
00173 
00174     r._last = _first = half;
00175   }
00176 
00182   StoredRange<iterator_type, object_type> &
00183   reset (const iterator_type &first,
00184          const iterator_type &last)
00185   {
00186     _objs.clear();
00187 
00188     for (iterator_type it=first; it!=last; ++it)
00189       _objs.push_back(*it);
00190 
00191     _begin = _objs.begin();
00192     _end   = _objs.end();
00193 
00194     _first = 0;
00195     _last  = _objs.size();
00196 
00197     return *this;
00198   }
00199 
00207   StoredRange<iterator_type, object_type> & reset ()
00208   {
00209     _begin = _objs.begin();
00210     _end   = _objs.end();
00211 
00212     _first = 0;
00213     _last  = _objs.size();
00214 
00215     return *this;
00216   }
00217 
00221   const_iterator begin () const { return _begin; }
00222 
00226   const_iterator end () const { return _end; }
00227 
00231   std::size_t first_idx () const { return _first; }
00232 
00236   std::size_t last_idx () const { return _last; }
00237 
00242   std::size_t grainsize () const {return _grainsize;}
00243 
00247   void grainsize (const unsigned int &gs) {_grainsize = gs;}
00248 
00252   std::size_t size () const { return std::distance(_begin, _end); }
00253 
00254   //------------------------------------------------------------------------
00255   // Methods that implement Range concept
00256   //------------------------------------------------------------------------
00257 
00261   bool empty() const { return (_begin == _end); }
00262 
00266   bool is_divisible() const { return this->grainsize() < static_cast<unsigned int>(std::distance(_begin, _end)); }
00267 
00268 private:
00269 
00270   const_iterator _end;
00271   const_iterator _begin;
00272   std::size_t _last;
00273   std::size_t _first;
00274   std::size_t _grainsize;
00275   std::vector<object_type> _objs;
00276 };
00277 
00278 } // namespace libMesh
00279 
00280 #endif // LIBMESH_STORED_RANGE_H