FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

PackedList.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Class
00025     Foam::PackedList
00026 
00027 Description
00028     A dynamically allocatable list of packed unsigned integers.
00029 
00030     The list resizing is similar to DynamicList, thus the methods clear()
00031     and setSize() behave like their DynamicList counterparts and the methods
00032     reserve() and setCapacity() can be used to influence the allocation.
00033 
00034     The number of bits per item is specified by the template parameter nBits.
00035 
00036 Note
00037     In a const context, the '[]' operator simply returns the stored value,
00038     with out-of-range elements returned as zero.
00039     In a non-const context, the '[]' operator returns an iteratorBase, which
00040     might not have a valid reference for out-of-range elements.
00041     The iteratorBase class handles the assignment of new values.
00042 
00043     Using the iteratorBase as a proxy allows assignment of values
00044     between list elements. Thus the following bit of code works as expected:
00045     @code
00046         list[1] = list[5];      // value assignment, not iterator position
00047         list[2] = list[5] = 4;  // propagates value
00048         list[1] = list[5] = list[6];  // propagates value
00049     @endcode
00050 
00051     Using get() or the '[]' operator are similarly fast. Looping and reading
00052     via an iterator is approx. 15% slower, but can be more flexible.
00053 
00054     Using the set() operator (and the '[]' operator) are marginally slower
00055     (approx. 5%) than using an iterator, but the set() method has the
00056     advantage of also returning a bool if the value changed.  This can be
00057     useful for branching on changed values.
00058 
00059     @code
00060         list[5] = 4;
00061         changed = list.set(5, 8);
00062         if (changed) ...
00063     @endcode
00064 
00065     The lazy evaluation used means that reading an out-of-range element
00066     returns zero, but does not affect the list size.  Even in a non-const
00067     context, only the assigment itself causes the element to be created.
00068     For example,
00069     @code
00070         list.resize(4);
00071         Info<< list[10] << "\n";  // print zero, but doesn't adjust list
00072         list[8] = 1;
00073     @endcode
00074 
00075 SeeAlso
00076     Foam::DynamicList
00077 
00078 SourceFiles
00079     PackedListI.H
00080     PackedList.C
00081 
00082 \*---------------------------------------------------------------------------*/
00083 
00084 #ifndef PackedList_H
00085 #define PackedList_H
00086 
00087 #include <OpenFOAM/labelList.H>
00088 #include <OpenFOAM/StaticAssert.H>
00089 
00090 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00091 
00092 namespace Foam
00093 {
00094 
00095 // Forward declaration of friend functions and operators
00096 template<unsigned nBits> class PackedList;
00097 
00098 // template<unsigned nBits>
00099 // Ostream& operator<<(Ostream&, const PackedList<nBits>&);
00100 
00101 
00102 /*---------------------------------------------------------------------------*\
00103                       Class PackedListName Declaration
00104 \*---------------------------------------------------------------------------*/
00105 
00106 TemplateName(PackedList);
00107 
00108 /*---------------------------------------------------------------------------*\
00109                          Class PackedList Declaration
00110 \*---------------------------------------------------------------------------*/
00111 
00112 template<unsigned nBits=1>
00113 class PackedList
00114 :
00115     private List<unsigned int>
00116 {
00117     typedef unsigned int      StorageType;
00118     typedef List<StorageType> StorageList;
00119 
00120     //- nBits must be positive (non-zero) and fit within the storage
00121     //  For simplicity, assume 8-bit bytes
00122     StaticAssert(nBits && nBits < (sizeof(StorageType) << 3));
00123 
00124     // Private data
00125 
00126         //- Number of nBits entries
00127         label size_;
00128 
00129     // Private Member Functions
00130 
00131         //- Calculate the list length when packed
00132         inline static label packedLength(const label);
00133 
00134 public:
00135 
00136     // Public data
00137 
00138         //- The max. number of bits that can be templated.
00139         //  Might someday be useful for a template assert.
00140         inline static unsigned int max_bits();
00141 
00142         //- The max. value for an entry, which simultaneously the bit-mask
00143         //  eg, ((1 << 2) - 1) yields 0b0011
00144         inline static unsigned int max_value();
00145 
00146         //- The number of entries per packed storage element
00147         inline static unsigned int packing();
00148 
00149         //- Masking for all bits below the offset
00150         inline static unsigned int maskLower(unsigned offset);
00151 
00152     // Forward declaration of iterators
00153 
00154         class iteratorBase;
00155         class iterator;
00156         class const_iterator;
00157 
00158     // Constructors
00159 
00160         //- Null constructor
00161         inline PackedList();
00162 
00163         //- Construct with given size, initializes list to 0.
00164         explicit inline PackedList(const label size);
00165 
00166         //- Construct with given size and value for all elements.
00167         PackedList(const label size, const unsigned val);
00168 
00169         //- Copy constructor.
00170         inline PackedList(const PackedList<nBits>&);
00171 
00172         //- Construct by transferring the parameter contents
00173         inline PackedList(const Xfer< PackedList<nBits> >&);
00174 
00175         //- Construct from a list of labels
00176         explicit PackedList(const UList<label>&);
00177 
00178         //- Clone
00179         inline autoPtr< PackedList<nBits> > clone() const;
00180 
00181     // Member Functions
00182 
00183         // Access
00184 
00185         //- The number of elements that can be stored before reallocating
00186         inline label capacity() const;
00187 
00188         //- Number of entries.
00189         inline label size() const;
00190 
00191         //- Return true if the list is empty (ie, size() is zero).
00192         inline bool empty() const;
00193 
00194         //- Get value at index I.
00195         //  Never auto-vivify entries.
00196         inline unsigned int get(const label) const;
00197 
00198         //- Set value at index I. Return true if value changed.
00199         //  Does auto-vivify for non-existent entries.
00200         //  Default value set is the max_value.
00201         inline bool set(const label, const unsigned int val = ~0u);
00202 
00203         //- Unset the entry at index I. Return true if value changed.
00204         //  Never auto-vivify entries.
00205         inline bool unset(const label);
00206 
00207         //- Return the underlying packed storage
00208         inline List<unsigned int>& storage();
00209 
00210         //- Return the underlying packed storage
00211         inline const List<unsigned int>& storage() const;
00212 
00213         //- Count number of bits set, O(log(n))
00214         //  Uses the Hamming weight (population count) method
00215         //  http://en.wikipedia.org/wiki/Hamming_weight
00216         unsigned int count() const;
00217 
00218         //- Return the values as a labelList
00219         labelList values() const;
00220 
00221         //- Print values and information
00222         Ostream& print(Ostream&) const;
00223 
00224         // Edit
00225 
00226         //- Trim any trailing zero elements
00227         bool trim();
00228 
00229         //- Invert the bits in the addressable region.
00230         void flip();
00231 
00232         //- Alter the size of the underlying storage.
00233         //  The addressed size will be truncated if needed to fit, but will
00234         //  remain otherwise untouched.
00235         inline void setCapacity(const label);
00236 
00237         //- Reset addressable list size, does not shrink the allocated size.
00238         //  Optionally specify a value for new elements.
00239         inline void resize(const label, const unsigned int& val = 0);
00240 
00241         //- Alias for resize()
00242         inline void setSize(const label, const unsigned int& val = 0);
00243 
00244         //- Reserve allocation space for at least this size.
00245         //  Never shrinks the allocated size.
00246         //  The list size is adjusted as per DynamicList with
00247         //  SizeInc=0, SizeMult=2, SizeDiv=1
00248         inline void reserve(const label);
00249 
00250         //- Clear the list, i.e. set addressable size to zero.
00251         //  Does not adjust the underlying storage
00252         inline void clear();
00253 
00254         //- Clear the list and delete storage.
00255         inline void clearStorage();
00256 
00257         //- Shrink the allocated space to what is actually used.
00258         inline void shrink();
00259 
00260         //- Transfer the contents of the argument list into this list
00261         //  and annul the argument list.
00262         inline void transfer(PackedList<nBits>&);
00263 
00264         //- Transfer contents to the Xfer container
00265         inline Xfer< PackedList<nBits> > xfer();
00266 
00267 
00268     // Member operators
00269 
00270         //- Append a value at the end of the list
00271         inline void append(const unsigned int val);
00272 
00273         //- Remove and return the last element
00274         inline unsigned int remove();
00275 
00276         //- Get value at index I
00277         //  Never auto-vivify entries.
00278         inline unsigned int operator[](const label) const;
00279 
00280         //- Set value at index I.
00281         //  Returns iterator to perform the actual operation.
00282         //  Does not auto-vivify entries, but will when assigned to.
00283         inline iteratorBase operator[](const label);
00284 
00285         //- Assignment of all entries to the given value. Takes linear time.
00286         inline void operator=(const unsigned int val);
00287 
00288         //- Assignment operator. Takes linear time.
00289         void operator=(const PackedList<nBits>&);
00290 
00291         //- Assignment operator. Takes linear time.
00292         void operator=(const UList<label>&);
00293 
00294     // Ostream operator
00295 
00296 //      // Write PackedList to Ostream.
00297 //      friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&);
00298 
00299     // Iterators and helpers
00300 
00301         //- The iterator base for PackedList
00302         //  Note: data and functions are protected, to allow reuse by iterator
00303         //  and prevent most external usage.
00304         class iteratorBase
00305         {
00306             friend class PackedList;
00307 
00308         protected:
00309 
00310             // Protected Data
00311 
00312                 //- Pointer to original list
00313                 //  This also lets us use the default bitwise copy/assignment
00314                 PackedList* list_;
00315 
00316                 //- Element index
00317                 label index_;
00318 
00319             // Protected Member Functions
00320 
00321                 //- Get value as unsigned, no range-checking
00322                 inline unsigned int get() const;
00323 
00324                 //- Set value, returning true if changed, no range-checking
00325                 inline bool set(unsigned int);
00326 
00327             // Constructors
00328 
00329                 //- Construct null
00330                 inline iteratorBase();
00331 
00332                 //- Construct from base list and position index
00333                 inline iteratorBase(const PackedList*, const label);
00334 
00335         public:
00336 
00337             // Member Operators
00338 
00339                 //- Compare values (not positions)
00340                 inline bool operator==(const iteratorBase&) const;
00341                 inline bool operator!=(const iteratorBase&) const;
00342 
00343                 //- Assign value, not position.
00344                 //  This allows packed[0] = packed[3] for assigning values
00345                 inline unsigned int operator=(const iteratorBase&);
00346 
00347                 //- Assign value.
00348                 //  A non-existent entry will be auto-vivified.
00349                 inline unsigned int operator=(const unsigned int val);
00350 
00351                 //- Conversion operator
00352                 //  Never auto-vivify entries.
00353                 inline operator unsigned int () const;
00354 
00355             //- Print value and information
00356             Ostream& print(Ostream&) const;
00357         };
00358 
00359 
00360         //- The iterator class used for PackedList
00361         class iterator
00362         :
00363             public iteratorBase
00364         {
00365 
00366             //- Disallow copy constructor from const_iterator - violates const-ness!
00367             iterator(const const_iterator&);
00368 
00369             //- Disallow assignment from const_iterator - violates const-ness!
00370             void operator=(const const_iterator&);
00371 
00372         public:
00373 
00374             // Constructors
00375 
00376                 //- Construct null
00377                 inline iterator();
00378 
00379                 //- Construct from iterator base, eg iter(packedlist[i])
00380                 //  but also  "iterator iter = packedlist[i];"
00381                 //  An out-of-range iterator is assigned end()
00382                 inline iterator(const iteratorBase&);
00383 
00384                 //- Construct from base list and position index
00385                 inline iterator(const PackedList*, const label);
00386 
00387             // Member Operators
00388 
00389                 //- Compare positions (not values)
00390                 inline bool operator==(const iteratorBase&) const;
00391                 inline bool operator!=(const iteratorBase&) const;
00392 
00393                 //- Assign from iteratorBase, eg iter = packedlist[i]
00394                 //  An out-of-range iterator is assigned end()
00395                 inline iterator& operator=(const iteratorBase&);
00396 
00397                 //- Return value
00398                 inline unsigned int operator*() const;
00399 
00400                 //- Return value
00401                 inline unsigned int operator()() const;
00402 
00403                 //- Return iteratorBase for assigning values
00404                 inline iteratorBase& operator*();
00405 
00406                 //- Return iteratorBase for assigning values
00407                 inline iteratorBase& operator()();
00408 
00409                 inline iterator& operator++();
00410                 inline iterator operator++(int);
00411 
00412                 inline iterator& operator--();
00413                 inline iterator operator--(int);
00414 
00415         };
00416 
00417         //- iterator set to the beginning of the PackedList
00418         inline iterator begin();
00419 
00420         //- iterator set to beyond the end of the PackedList
00421         inline iterator end();
00422 
00423 
00424         //- The const_iterator for PackedList
00425         class const_iterator
00426         :
00427             public iteratorBase
00428         {
00429         public:
00430 
00431             // Constructors
00432 
00433                 //- Construct null
00434                 inline const_iterator();
00435 
00436                 //- Construct from iterator base, eg iter(packedlist[i])
00437                 //  but also  "const_iterator iter = packedlist[i];"
00438                 //  An out-of-range iterator is assigned cend()
00439                 inline const_iterator(const iteratorBase&);
00440 
00441                 //- Construct from base list and position index
00442                 inline const_iterator(const PackedList*, const label);
00443 
00444                 //- Construct from iterator
00445                 inline const_iterator(const iterator&);
00446 
00447             // Member operators
00448 
00449                 //- Compare positions (not values)
00450                 inline bool operator==(const iteratorBase&) const;
00451                 inline bool operator!=(const iteratorBase&) const;
00452 
00453                 //- Assign from iteratorBase or derived
00454                 //  eg, iter = packedlist[i] or even iter = list.begin()
00455                 inline const_iterator& operator=(const iteratorBase&);
00456 
00457                 //- Return referenced value directly
00458                 inline unsigned int operator*() const;
00459 
00460                 //- Return referenced value directly
00461                 inline unsigned int operator()() const;
00462 
00463                 inline const_iterator& operator++();
00464                 inline const_iterator operator++(int);
00465 
00466                 inline const_iterator& operator--();
00467                 inline const_iterator operator--(int);
00468 
00469         };
00470 
00471 
00472         //- const_iterator set to the beginning of the PackedList
00473         inline const_iterator cbegin() const;
00474 
00475         //- const_iterator set to beyond the end of the PackedList
00476         inline const_iterator cend() const;
00477 
00478         //- const_iterator set to the beginning of the PackedList
00479         inline const_iterator begin() const;
00480 
00481         //- const_iterator set to beyond the end of the PackedList
00482         inline const_iterator end() const;
00483 
00484 };
00485 
00486 
00487 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00488 
00489 } // End namespace Foam
00490 
00491 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00492 
00493 #include "PackedListI.H"
00494 
00495 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00496 
00497 #ifdef NoRepository
00498 #   include "PackedList.C"
00499 #endif
00500 
00501 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00502 
00503 #endif
00504 
00505 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines