Commit 6d57bb4e authored by Mark Olesen's avatar Mark Olesen
Browse files

added PackedBoolList typedef (used everywhere) and improved PackedList

- new members:  capacity(), two-argument resize()/setSize(), const storage()
- new static members: max_value(), packing(), etc.
parent 4da086b1
......@@ -119,7 +119,7 @@ scalar StCoNum = 0.0;
fvc::makeAbsolute(phi, rho, U);
// Test : disable refinement for some cells
PackedList<1>& protectedCell =
PackedBoolList& protectedCell =
refCast<dynamicRefineFvMesh>(mesh).protectedCell();
if (protectedCell.empty())
......
PackedListTest.C
EXE = $(FOAM_USER_APPBIN)/PackedListTest
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
Description
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "IOstreams.H"
#include "IStringStream.H"
#include "scalar.H"
#include "vector.H"
#include "ListOps.H"
#include "List.H"
#include "PackedBoolList.H"
#include <bitset>
using namespace Foam;
template <int nBits>
void printPackedList(const PackedList<nBits>& L)
{
const List<unsigned int>& stor = L.storage();
cout<< "PackedList<" << nBits << ">"
<< " max_bits:" << L.max_bits()
<< " max_value:" << L.max_value()
<< " packing:" << L.packing() << nl;
cout<< "values: " << L.size() << "/" << L.capacity() << " ( ";
forAll(L, i)
{
cout<< L[i] << ' ';
}
cout<< ")\n\n";
cout<< "storage: " << stor.size() << "( ";
forAll(stor, i)
{
cout<< std::bitset<32>(stor[i]) << ' ';
}
cout<< ")\n" << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
cout<< "PackedList::max_bits() = " << PackedList<0>::max_bits() << nl;
PackedList<3> list1(5,1);
printPackedList(list1);
list1 = 2;
printPackedList(list1);
list1.resize(6, 3);
printPackedList(list1);
list1 = false;
printPackedList(list1);
list1 = true;
printPackedList(list1);
list1.resize(12);
printPackedList(list1);
list1.resize(25, list1.max_value());
printPackedList(list1);
list1.resize(8);
printPackedList(list1);
return 0;
}
// ************************************************************************* //
......@@ -48,7 +48,7 @@ Description
#include "polyMesh.H"
#include "mapPolyMesh.H"
#include "mathematicalConstants.H"
#include "PackedList.H"
#include "PackedBoolList.H"
#include "SortableList.H"
using namespace Foam;
......@@ -177,7 +177,7 @@ label mergeEdges
// Return master point edge needs to be collapsed to (or -1)
label edgeMaster(const PackedList<1>& boundaryPoint, const edge& e)
label edgeMaster(const PackedBoolList& boundaryPoint, const edge& e)
{
label masterPoint = -1;
......@@ -215,7 +215,7 @@ label edgeMaster(const PackedList<1>& boundaryPoint, const edge& e)
label collapseSmallEdges
(
const polyMesh& mesh,
const PackedList<1>& boundaryPoint,
const PackedBoolList& boundaryPoint,
const scalar minLen,
edgeCollapser& collapser
)
......@@ -254,7 +254,7 @@ label collapseSmallEdges
label collapseHighAspectFaces
(
const polyMesh& mesh,
const PackedList<1>& boundaryPoint,
const PackedBoolList& boundaryPoint,
const scalar areaFac,
const scalar edgeRatio,
edgeCollapser& collapser
......@@ -346,7 +346,7 @@ void set(const labelList& elems, const bool val, boolList& status)
label simplifyFaces
(
const polyMesh& mesh,
const PackedList<1>& boundaryPoint,
const PackedBoolList& boundaryPoint,
const label minSize,
const scalar lenGap,
edgeCollapser& collapser
......@@ -485,7 +485,7 @@ int main(int argc, char *argv[])
const faceList& faces = mesh.faces();
// Get all points on the boundary
PackedList<1> boundaryPoint(mesh.nPoints(), false);
PackedBoolList boundaryPoint(mesh.nPoints());
label nIntFaces = mesh.nInternalFaces();
for (label faceI = nIntFaces; faceI < mesh.nFaces(); faceI++)
......
......@@ -49,7 +49,7 @@ Description
#include "mathematicalConstants.H"
#include "polyTopoChange.H"
#include "mapPolyMesh.H"
#include "PackedList.H"
#include "PackedBoolList.H"
#include "meshTools.H"
#include "OFstream.H"
#include "meshDualiser.H"
......@@ -67,7 +67,7 @@ using namespace Foam;
void simpleMarkFeatures
(
const polyMesh& mesh,
const PackedList<1>& isBoundaryEdge,
const PackedBoolList& isBoundaryEdge,
const scalar featureAngle,
const bool doNotPreserveFaceZones,
......@@ -358,7 +358,7 @@ int main(int argc, char *argv[])
// Mark boundary edges and points.
// (Note: in 1.4.2 we can use the built-in mesh point ordering
// facility instead)
PackedList<1> isBoundaryEdge(mesh.nEdges());
PackedBoolList isBoundaryEdge(mesh.nEdges());
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{
const labelList& fEdges = mesh.faceEdges()[faceI];
......
......@@ -155,7 +155,7 @@ Foam::label Foam::meshDualiser::findDualCell
// from (boundary & feature) point
void Foam::meshDualiser::generateDualBoundaryEdges
(
const PackedList<1>& isBoundaryEdge,
const PackedBoolList& isBoundaryEdge,
const label pointI,
polyTopoChange& meshMod
)
......@@ -388,7 +388,7 @@ Foam::label Foam::meshDualiser::addBoundaryFace
void Foam::meshDualiser::createFacesAroundEdge
(
const bool splitFace,
const PackedList<1>& isBoundaryEdge,
const PackedBoolList& isBoundaryEdge,
const label edgeI,
const label startFaceI,
polyTopoChange& meshMod,
......@@ -907,7 +907,7 @@ void Foam::meshDualiser::setRefinement
// Mark boundary edges and points.
// (Note: in 1.4.2 we can use the built-in mesh point ordering
// facility instead)
PackedList<1> isBoundaryEdge(mesh_.nEdges());
PackedBoolList isBoundaryEdge(mesh_.nEdges());
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
{
const labelList& fEdges = mesh_.faceEdges()[faceI];
......
......@@ -49,7 +49,7 @@ SourceFiles
#define meshDualiser_H
#include "DynamicList.H"
#include "PackedList.H"
#include "PackedBoolList.H"
#include "boolList.H"
#include "typeInfo.H"
......@@ -101,7 +101,7 @@ class meshDualiser
// emanating from (boundary & feature) point
void generateDualBoundaryEdges
(
const PackedList<1>&,
const PackedBoolList&,
const label pointI,
polyTopoChange&
);
......@@ -144,7 +144,7 @@ class meshDualiser
void createFacesAroundEdge
(
const bool splitFace,
const PackedList<1>&,
const PackedBoolList&,
const label edgeI,
const label startFaceI,
polyTopoChange&,
......
......@@ -31,7 +31,7 @@ License
template<int nBits>
Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
:
List<unsigned int>(intSize(size)),
List<unsigned int>(storageSize(size)),
size_(size)
{
operator=(val);
......@@ -56,7 +56,7 @@ Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
template<int nBits>
Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
:
List<unsigned int>(intSize(lst.size()), 0),
List<unsigned int>(storageSize(lst.size()), 0),
size_(lst.size())
{
forAll(lst, i)
......@@ -76,10 +76,36 @@ Foam::autoPtr<Foam::PackedList<nBits> > Foam::PackedList<nBits>::clone() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<int nBits>
void Foam::PackedList<nBits>::setSize(const label size)
void Foam::PackedList<nBits>::setSize(const label newSize)
{
List<unsigned int>::setSize(intSize(size));
size_ = size;
List<unsigned int>::setSize(storageSize(newSize), 0);
size_ = newSize;
}
template<int nBits>
void Foam::PackedList<nBits>::setSize
(
const label newSize,
const unsigned int& val
)
{
# ifdef DEBUGList
checkValue(val);
# endif
List<unsigned int>::setSize(storageSize(newSize), 0);
if (val && newSize > size_)
{
// fill new elements
for (label i = size_; i < newSize; i++)
{
set(i, val);
}
}
size_ = newSize;
}
......
......@@ -27,8 +27,14 @@ Class
Description
List of packed unsigned ints.
Gets given the number of bits per item.
ToDo
Add checks for bad template parameters (ie, nBits=0, nBits too large).
Could make PackedBitRef an iterator and use for traversing as well.
It could be useful to make PackedList behave a bit like DynamicList.
SourceFiles
PackedListI.H
PackedList.C
......@@ -54,45 +60,55 @@ TemplateName(PackedList);
/*---------------------------------------------------------------------------*\
Class PackedList Declaration
Class PackedBitRef Declaration
\*---------------------------------------------------------------------------*/
//- For PackedList
class reference
//- The PackedBitRef is used for PackedList
class PackedBitRef
{
private:
// private data
unsigned int& elem_;
unsigned int mask_;
const label startBit_;
label startBit_;
const unsigned int mask_;
public:
inline reference(unsigned int& elem, unsigned int mask, label startBit)
inline PackedBitRef(unsigned int& elem, label startBit, unsigned int mask)
:
elem_(elem),
mask_(mask),
startBit_(startBit)
startBit_(startBit),
mask_(mask)
{}
inline void operator=(const unsigned int val)
{
unsigned int shiftedMask = mask_ << startBit_;
unsigned int shiftedVal = val << startBit_;
unsigned int shiftedVal = (val & mask_) << startBit_;
elem_ = (elem_ & ~shiftedMask) | shiftedVal;
}
inline operator unsigned int () const
{
return (elem_ >> startBit_) & mask_;
return ((elem_ >> startBit_) & mask_);
}
inline operator bool() const
{
return !!((elem_ >> startBit_) & mask_);
}
};
/*---------------------------------------------------------------------------*\
Class PackedList Declaration
\*---------------------------------------------------------------------------*/
template <int nBits>
class PackedList
:
......@@ -103,23 +119,36 @@ class PackedList
//- Number of nBits entries
label size_;
// Private Member Functions
//- Calculate underlying list size
inline static label intSize(const label sz);
inline static label storageSize(const label);
//- Calculate index into underlying List.
inline static label intIndex(const label i);
//- Calculate element index and offset (start) bit within storage
inline static label location(const label, label& offset);
//- Check index i is within valid range (0 ... size-1).
inline void checkIndex(const label i) const;
//- Check if value is representable in nBits
inline static void checkValue(const unsigned int);
//- Check value is representable in nBits
inline void checkValue(const unsigned int val) const;
//- Check index i is within valid range (0 ... size-1).
inline void checkIndex(const label) const;
public:
// Public data
//- The max. number of bits that can be templated.
// Might someday be useful for a template assert.
inline static unsigned int max_bits();
//- The max. value for an entry, can also be used as the mask
// eg, ((1 << 2) - 1) yields 0b0011
inline static unsigned int max_value();
//- The number of entries per storage entry
inline static unsigned int packing();
// Constructors
//- Null constructor
......@@ -129,7 +158,7 @@ public:
inline PackedList(const label size);
//- Construct with given size and value for all elements.
PackedList(const label size, const unsigned int val);
PackedList(const label size, const unsigned val);
//- Copy constructor.
PackedList(const PackedList<nBits>& PList);
......@@ -145,27 +174,11 @@ public:
// Member Functions
// Edit
//- Reset size of List.
void setSize(const label);
//- Reset size of List.
inline void resize(const label);
//- Clear the list, i.e. set size to zero.
void clear();
//- Transfer the contents of the argument List into this List
// and annull the argument list.
void transfer(PackedList<nBits>&);
//- Transfer contents to the Xfer container
inline Xfer<PackedList<nBits> > xfer();
// Access
//- The number of elements that can be stored before resizing
inline label capacity() const;
//- Number of packed elements
inline label size() const;
......@@ -181,20 +194,51 @@ public:
//- Underlying storage
inline List<unsigned int>& storage();
//- Underlying storage
inline const List<unsigned int>& storage() const;
// Edit
//- Reset size of List, setting zero for any new elements.
void setSize(const label);
//- Reset size of List and value for new elements.
void setSize(const label, const unsigned int& val);
//- Reset size of List, setting zero for any new elements.
inline void resize(const label);
//- Reset size of List and value for new elements.
inline void resize(const label, const unsigned int& val);
//- Construct with given size and value for all elements.
//- Clear the list, i.e. set size to zero.
void clear();
//- Transfer the contents of the argument List into this List
// and annull the argument list.
void transfer(PackedList<nBits>&);
//- Transfer contents to the Xfer container
inline Xfer<PackedList<nBits> > xfer();
// Member operators
//- Get value at index i
inline unsigned int operator[](const label i) const;
//- Set value at index i. Returns proxy which does actual operation
inline ::Foam::reference operator[](const label i);
//- Set value at index i.
// Returns proxy to perform the actual operation
inline ::Foam::PackedBitRef operator[](const label i);
//- Assignment operator. Takes linear time.
void operator=(const PackedList<nBits>&);
//- Assignment of all entries to the given value. Does set on all
// elements.
//- Assignment of all entries to the given value.
// Does set on all elements.
inline void operator=(const unsigned int val);
//- Return as labelList
......@@ -207,7 +251,6 @@ public:
// friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -25,33 +25,67 @@ License
\*---------------------------------------------------------------------------*/
#ifndef PackedList_I
#define PackedList_I
#ifndef PackedListI_H
#define PackedListI_H
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Calculate underlying list size
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::intSize(const label sz)
inline unsigned int Foam::PackedList<nBits>::max_bits()
{
const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
return sizeof(unsigned int)*8 - 1;
}
return (sz+nElemsPerLabel-1)/nElemsPerLabel;
template<int nBits>
inline unsigned int Foam::PackedList<nBits>::max_value()
{
return ((1u << nBits) - 1);
}
// Convert index into index in integer array
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::intIndex(const label i)
inline unsigned int Foam::PackedList<nBits>::packing()
{
const label nElemsPerLabel = sizeof(unsigned int)*8/nBits;
return sizeof(unsigned int)*8 / nBits;
}
// Index in underlying int array
label elemI = i/nElemsPerLabel;
return elemI;
// Calculate underlying list size
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::storageSize(const label sz)
{
return (sz + packing() - 1) / packing();
}
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::location
(
const label i,
label& offset
)
{
// the offset is the start bit within the storage element
offset = nBits * (i % packing());
return i / packing();