Commit 1d79c045 authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

ENH: additional contiguous traits (#1378)

- change contiguous from a series of global functions to separate
  templated traits classes:

    - is_contiguous
    - is_contiguous_label
    - is_contiguous_scalar

  The static constexpr 'value' and a constexpr conversion operator
  allow use in template expressions.  The change also makes it much
  easier to define general traits and to inherit from them.

  The is_contiguous_label and is_contiguous_scalar are special traits
  for handling data of homogeneous components of the respective types.
parent 3c07a1bb
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -78,7 +78,7 @@ void infoHashString
void reportHashList(const UList<string>& list)
{
Info<< "contiguous = " << contiguous<string>() << nl << nl;
Info<< "contiguous = " << is_contiguous<string>::value << nl << nl;
for (const string& val : list)
{
......@@ -91,7 +91,7 @@ void reportHashList(const UList<string>& list)
void reportHashList(const UList<label>& list)
{
Info<<"contiguous = " << contiguous<label>() << nl << nl;
Info<<"contiguous = " << is_contiguous<label>::value << nl << nl;
for (const label val : list)
{
......@@ -110,7 +110,7 @@ void reportHashList(const UList<label>& list)
void reportHashList(const UList<face>& list)
{
Info<<"contiguous = " << contiguous<label>() << nl << nl;
Info<<"contiguous = " << is_contiguous<label>::value << nl << nl;
for (const face& f : list)
{
......@@ -157,7 +157,7 @@ typedef Pair<word> wordPair;
void reportHashList(const UList<wordPair>& list)
{
Info<<"contiguous = " << contiguous<wordPair>() << nl << nl;
Info<<"contiguous = " << is_contiguous<wordPair>::value << nl << nl;
for (const wordPair& pr : list)
{
......@@ -182,7 +182,7 @@ void reportHashList(const UList<wordPair>& list)
void reportHashList(const UList<labelPair>& list)
{
Info<<"contiguous = " << contiguous<labelPair>() << nl << nl;
Info<<"contiguous = " << is_contiguous<labelPair>::value << nl << nl;
for (const labelPair& pr : list)
{
......@@ -203,7 +203,7 @@ void reportHashList(const UList<labelPair>& list)
void reportHashList(const UList<labelPairPair>& list)
{
Info<<"contiguous = " << contiguous<labelPairPair>() << nl << nl;
Info<<"contiguous = " << is_contiguous<labelPairPair>::value << nl << nl;
for (const labelPairPair& pr : list)
{
......@@ -224,7 +224,7 @@ void reportHashList(const UList<labelPairPair>& list)
void reportHashList(const UList<edge>& list)
{
Info<<"contiguous = " << contiguous<edge>() << nl << nl;
Info<<"contiguous = " << is_contiguous<edge>::value << nl << nl;
for (const edge& e : list)
{
......@@ -245,7 +245,7 @@ void reportHashList(const UList<edge>& list)
void reportHashList(const UList<triFace>& list)
{
Info<<"contiguous = " << contiguous<triFace>() << nl << nl;
Info<<"contiguous = " << is_contiguous<triFace>::value << nl << nl;
for (const triFace& f : list)
{
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -112,7 +112,7 @@ Ostream& printListOutputType(const char* what)
{
Info<< what
<< " (contiguous="
<< contiguous<T>() << " no_linebreak="
<< is_contiguous<T>::value << " no_linebreak="
<< Detail::ListPolicy::no_linebreak<T>::value
<< " short_length="
<< Detail::ListPolicy::short_length<T>::value << ')';
......
/* EXE_INC = */
EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/parallel/distributed/lnInclude
/* EXE_LIBS = */
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -37,6 +37,7 @@ Description
#include "IOstreams.H"
#include "scalar.H"
#include "vector.H"
#include "Switch.H"
#include "labelRange.H"
#include "scalarList.H"
......@@ -44,24 +45,43 @@ Description
#include "FixedList.H"
#include "Pair.H"
#include "distributedTriSurfaceMesh.H"
namespace Foam
{
// Wrong, but interesting to test
// template<> struct contiguous<Pair<word>> : std::true_type {};
template<> struct is_contiguous<Pair<word>> : std::true_type {};
} // End namespace Foam
} // end namespace Foam
using namespace Foam;
template<class T>
void printContiguous()
void printInfo(const char* const name = nullptr)
{
Info<<"contiguous " << typeid(T).name() << " () = "
<< contiguous<T>()
// << " value = " << contiguous<T>::value
<< nl;
if (name == nullptr)
{
Info<< typeid(T).name();
}
else
{
Info<< name;
}
Info<< " contiguous=" << Switch(is_contiguous<T>::value);
if (is_contiguous_label<T>::value)
{
Info<< " label";
}
if (is_contiguous_scalar<T>::value)
{
Info<< " scalar";
}
Info<< nl;
}
......@@ -74,18 +94,16 @@ int main(int argc, char *argv[])
argList::noParallel();
argList::noFunctionObjects();
#include "setRootCase.H"
printContiguous<label>();
printContiguous<double>();
printContiguous<FixedList<int, 2>>();
printContiguous<FixedList<int, 3>>();
printContiguous<Pair<long>>();
printInfo<label>();
printInfo<double>();
printInfo<FixedList<double, 4>>();
printInfo<Pair<long>>();
printContiguous<FixedList<word, 2>>();
printContiguous<Pair<word>>();
printInfo<FixedList<word, 2>>();
printInfo<Pair<word>>();
printContiguous<FixedList<FixedList<int, 2>, 2>>();
printInfo<FixedList<FixedList<int, 2>, 2>>();
printInfo<segment>();
return 0;
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2015 OpenFOAM Foundation
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2015 OpenFOAM Foundation
......@@ -36,6 +36,7 @@ SourceFiles
#ifndef indexedCellEnum_H
#define indexedCellEnum_H
#include "contiguous.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -63,11 +64,10 @@ public:
};
template<>
inline bool contiguous<indexedCellEnum>()
{
return true;
}
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Contiguous data for indexedCellEnum
template<> struct is_contiguous<indexedCellEnum> : std::true_type {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
......@@ -323,32 +323,26 @@ public:
} // End namespace CGAL
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
#ifdef CGAL_INEXACT
namespace Foam
{
// For inexact representations where the storage type is a double, the data
// is contiguous. This may not be true for exact number types.
template<>
inline bool contiguous
struct is_contiguous
<
CGAL::indexedVertex
<
K,
CGAL::Triangulation_vertex_base_3<K>
>
>()
{
return true;
}
CGAL::indexedVertex<K, CGAL::Triangulation_vertex_base_3<K>>
> : std::true_type {};
template<>
inline bool contiguous<CGAL::Triangulation_vertex_base_3<K>::Point>()
{
return true;
}
struct is_contiguous
<
CGAL::Triangulation_vertex_base_3<K>::Point
> : std::true_type {};
} // End namespace Foam
#endif
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
......@@ -84,15 +84,17 @@ public:
};
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Contiguous data for indexedVertexEnum
template<> struct is_contiguous<indexedVertexEnum> : std::true_type {};
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
Istream& operator>>(Istream&, indexedVertexEnum::vertexType&);
Ostream& operator<<(Ostream&, const indexedVertexEnum::vertexType&);
template<>
inline bool contiguous<indexedVertexEnum>()
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
......@@ -38,6 +38,7 @@ SourceFiles
#ifndef volumeType_H
#define volumeType_H
#include "contiguous.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -45,7 +46,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class dictionary;
class volumeType;
Istream& operator>>(Istream& is, volumeType& vt);
......@@ -128,9 +129,10 @@ public:
};
//- Data associated with volumeType type are contiguous
template<>
inline bool contiguous<volumeType>() {return true;}
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Contiguous data for volumeType
template<> struct is_contiguous<volumeType> : std::true_type {};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -44,9 +44,9 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
const label len = list.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>())
if (os.format() == IOstream::ASCII || !is_contiguous<T>::value)
{
if (len > 1 && contiguous<T>() && list.uniform())
if (len > 1 && is_contiguous<T>::value && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
......@@ -60,7 +60,7 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
&&
(
Detail::ListPolicy::no_linebreak<T>::value
|| contiguous<T>()
|| is_contiguous<T>::value
)
)
)
......
......@@ -431,7 +431,7 @@ public:
unsigned seed=0
) const
{
if (contiguous<T>())
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), N*sizeof(T), seed);
}
......@@ -445,6 +445,20 @@ public:
};
};
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- FixedList is contiguous if the type is contiguous
template<class T, unsigned N>
struct is_contiguous<FixedList<T, N>> : is_contiguous<T> {};
//- Check for FixedList of labels
template<class T, unsigned N>
struct is_contiguous_label<FixedList<T, N>> : is_contiguous_label<T> {};
//- Check for FixedList of scalars
template<class T, unsigned N>
struct is_contiguous_scalar<FixedList<T, N>> : is_contiguous_scalar<T> {};
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
......@@ -465,7 +479,7 @@ struct Hash<FixedList<T, N>>
unsigned seed=0
) const
{
if (contiguous<T>())
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), N*sizeof(T), seed);
}
......
......@@ -29,7 +29,6 @@ License
#include "Istream.H"
#include "Ostream.H"
#include "token.H"
#include "contiguous.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
......@@ -75,7 +74,7 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
// small and we desire a consistent appearance.
// Eg, FixedList<T,2> or Pair<T> as "(-1 -1)", not as "2{-1}"
if (os.format() == IOstream::ASCII || !contiguous<T>())
if (os.format() == IOstream::ASCII || !is_contiguous<T>::value)
{
if
(
......@@ -86,7 +85,7 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
&&
(
Detail::ListPolicy::no_linebreak<T>::value
|| contiguous<T>()
|| is_contiguous<T>::value
)
)
)
......@@ -146,7 +145,7 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, N>& list)
{
is.fatalCheck(FUNCTION_NAME);
if (is.format() == IOstream::ASCII || !contiguous<T>())
if (is.format() == IOstream::ASCII || !is_contiguous<T>::value)
{
token firstToken(is);
......
......@@ -56,7 +56,7 @@ void Foam::List<T>::doResize(const label newSize)
if (overlap)
{
#ifdef USEMEMCPY
if (contiguous<T>())
if (is_contiguous<T>::value)
{
memcpy(nv, this->v_, overlap*sizeof(T));
}
......@@ -189,7 +189,7 @@ Foam::List<T>::List(const UList<T>& a)
doAlloc();
#ifdef USEMEMCPY
if (contiguous<T>())
if (is_contiguous<T>::value)
{
memcpy(this->v_, a.v_, this->byteSize());
}
......@@ -217,7 +217,7 @@ Foam::List<T>::List(const List<T>& a)
doAlloc();
#ifdef USEMEMCPY
if (contiguous<T>())
if (is_contiguous<T>::value)
{
memcpy(this->v_, a.v_, this->byteSize());
}
......@@ -252,7 +252,7 @@ Foam::List<T>::List(List<T>& a, bool reuse)
doAlloc();
#ifdef USEMEMCPY
if (contiguous<T>())
if (is_contiguous<T>::value)
{
memcpy(this->v_, a.v_, this->byteSize());
}
......@@ -456,7 +456,7 @@ void Foam::List<T>::operator=(const UList<T>& a)
if (this->size_)
{
#ifdef USEMEMCPY
if (contiguous<T>())
if (is_contiguous<T>::value)
{
memcpy(this->v_, a.v_, this->byteSize());
}
......
......@@ -353,7 +353,7 @@ struct Hash<List<T>>
{
inline unsigned operator()(const UList<T>& obj, unsigned seed=0) const
{
if (contiguous<T>())
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), obj.size()*sizeof(T), seed);
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -79,7 +79,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !contiguous<T>())
if (is.format() == IOstream::ASCII || !is_contiguous<T>::value)
{
// Read beginning of contents
const char delimiter = is.readBeginList("List");
......
......@@ -115,7 +115,7 @@ void Foam::UList<T>::deepCopy(const UList<T>& list)
else if (len)
{
#ifdef USEMEMCPY
if (contiguous<T>())
if (is_contiguous<T>::value)
{
memcpy(this->v_, list.v_, this->byteSize());
}
......@@ -180,7 +180,7 @@ void Foam::UList<T>::operator=(const zero)
template<class T>
std::streamsize Foam::UList<T>::byteSize() const
{
if (!contiguous<T>())
if (!is_contiguous<T>::value)
{
FatalErrorInFunction
<< "Cannot return binary size of a list with non-primitive elements"
......
......@@ -247,7 +247,7 @@ public:
//- Return the binary size in number of characters of the UList
//- if the element is a primitive type
// i.e. contiguous<T>() == true.
// i.e. is_contiguous<T>::value == true.
// Note that is of type streamsize since used in stream ops
std::streamsize byteSize() const;
......@@ -524,7 +524,7 @@ public:
unsigned seed=0
) const
{
if (contiguous<T>())
if (is_contiguous<T>::value)
{
return Hasher(obj.cdata(), obj.size()*sizeof(T), seed);
}
......@@ -591,7 +591,7 @@ struct Hash<UList<T>>
{
inline unsigned operator()(const UList<T>& obj, unsigned seed=0) const
{