Commit a0a7da2e authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: Pair, Tuple2 improvements (#1160)

- move constructors, construct from std::pair
- input/output of std::pair

Makes it easier when using data structures for other codes.
parent 08dc8d0e
......@@ -25,10 +25,11 @@ Application
Test-Tuple2
Description
Test construction, comparision etc for Tuple2 and Pair.
\*---------------------------------------------------------------------------*/
#include "Pair.H"
#include "labelPair.H"
#include "Tuple2.H"
#include "label.H"
#include "scalar.H"
......@@ -67,6 +68,26 @@ struct special2
};
// Print info
void printTuple2(const Tuple2<word, word>& t)
{
Info<< "tuple: " << t << nl;
Info<< "first @: " << long(t.first().data()) << nl;
Info<< "second @: " << long(t.second().data()) << nl;
}
// Print info
void printTuple2(const Pair<word>& t)
{
Info<< "tuple: " << t << nl;
Info<< "first @: " << long(t.first().data()) << nl;
Info<< "second @: " << long(t.second().data()) << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
......@@ -74,11 +95,14 @@ int main()
{
typedef Tuple2<label, scalar> indexedScalar;
Info<< "null constructed Tuple: " << indexedScalar() << nl;
Info<< "null constructed Pair: " << Pair<scalar>() << nl;
indexedScalar t2(1, 3.2);
Info<< "tuple: "
Info<< "Foam::Tuple2: "
<< t2 << " => "
<< t2.first() << " " << t2.second() << nl;
<< t2.first() << ' ' << t2.second() << nl;
// As list. Generated so that we have duplicate indices
List<indexedScalar> list1(3*4);
......@@ -113,25 +137,83 @@ int main()
<< nl << list1 << nl;
Info<< nl << nl << "Pairs" << nl;
{
Info<< nl << nl << "Foam::Pair" << nl;
typedef Pair<label> indexedLabel;
indexedLabel pr(1, 3);
Info<< "pair: "
<< pr << " => "
<< pr.first() << ' ' << pr.second() << nl;
typedef Pair<label> indexedLabel;
List<indexedLabel> list2 = ListOps::create<indexedLabel>
(
list1,
[](const indexedScalar& t2)
{
return indexedLabel(t2.first(), t2.second());
}
);
indexedLabel pr(1, 3);
Info<< "Unsorted pairs:" << nl << list2 << nl;
}
{
Info<< nl << nl << "std::pair" << nl;
Info<< "pair: "
<< pr << " => "
<< pr.first() << " " << pr.second() << nl;
typedef std::pair<label, label> indexedLabel;
List<indexedLabel> list2 = ListOps::create<indexedLabel>
(
list1,
[](const indexedScalar& t2) {
return indexedLabel(t2.first(), t2.second());
}
);
indexedLabel pr(1, 3);
Info<< "Unsorted pairs:" << nl << list2 << nl;
Info<< "pair: "
<< pr << " => "
<< pr.first << ' ' << pr.second << nl;
List<indexedLabel> list2 = ListOps::create<indexedLabel>
(
list1,
[](const indexedScalar& t2)
{
return indexedLabel(t2.first(), t2.second());
}
);
Info<< "Unsorted pairs:" << nl << list2 << nl;
}
{
word word1("hello");
word word2("word");
Info<< "create with " << word1 << " @ " << long(word1.data())
<< " " << word2 << " @ " << long(word2.data()) << nl;
Tuple2<word, word> tup(std::move(word2), std::move(word1));
printTuple2(tup);
Info<< "input is now " << word1 << " @ " << long(word1.data())
<< " " << word2 << " @ " << long(word2.data()) << nl;
}
{
word word1("hello");
word word2("word");
Info<< "create with " << word1 << " @ " << long(word1.data())
<< " " << word2 << " @ " << long(word2.data()) << nl;
Pair<word> tup(std::move(word2), std::move(word1));
printTuple2(tup);
Info<< "input is now " << word1 << " @ " << long(word1.data())
<< " " << word2 << " @ " << long(word2.data()) << nl;
}
Info<< "\nEnd\n" << endl;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2017-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -41,6 +41,7 @@ See also
#include "FixedList.H"
#include "Istream.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -64,17 +65,26 @@ public:
//- Construct null
Pair() = default;
//- Construct from components
//- Copy construct from components
inline Pair(const T& f, const T& s);
//- Construct from FixedList
inline Pair(const FixedList<T, 2>& lst);
//- Move construct from components
inline Pair(T&& f, T&& s);
//- Construct, optionally sorted with first less-than second
//- Copy construct from std::pair
inline Pair(const std::pair<T,T>& vals);
//- Move construct from std::pair
inline Pair(std::pair<T,T>&& vals);
//- Copy construct FixedList of two items
inline Pair(const FixedList<T, 2>& list);
//- Copy construct, optionally sorted with first less-than second
inline Pair(const T& f, const T& s, const bool doSort);
//- Construct, optionally sorted with first less-than second
inline Pair(const FixedList<T, 2>& lst, const bool doSort);
//- Copy construct, optionally sorted with first less-than second
inline Pair(const FixedList<T, 2>& list, const bool doSort);
//- Construct from Istream
inline explicit Pair(Istream& is);
......@@ -151,6 +161,7 @@ public:
return seed;
}
};
};
......@@ -206,11 +217,7 @@ bool operator<(const Pair<T>& a, const Pair<T>& b)
return
(
a.first() < b.first()
||
(
!(b.first() < a.first())
&& a.second() < b.second()
)
|| (!(b.first() < a.first()) && a.second() < b.second())
);
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -54,9 +54,33 @@ inline Foam::Pair<T>::Pair(const T& f, const T& s)
template<class T>
inline Foam::Pair<T>::Pair(const FixedList<T, 2>& lst)
inline Foam::Pair<T>::Pair(T&& f, T&& s)
{
first() = std::move(f);
second() = std::move(s);
}
template<class T>
inline Foam::Pair<T>::Pair(const std::pair<T,T>& vals)
{
first() = vals.first;
second() = vals.second;
}
template<class T>
inline Foam::Pair<T>::Pair(std::pair<T,T>&& vals)
{
first() = std::move(vals.first);
second() = std::move(vals.second);
}
template<class T>
inline Foam::Pair<T>::Pair(const FixedList<T, 2>& list)
:
FixedList<T, 2>(lst)
FixedList<T, 2>(list)
{}
......@@ -77,13 +101,12 @@ inline Foam::Pair<T>::Pair(const T& f, const T& s, const bool doSort)
template<class T>
inline Foam::Pair<T>::Pair(const FixedList<T, 2>& lst, const bool doSort)
inline Foam::Pair<T>::Pair(const FixedList<T, 2>& list, const bool doSort)
:
Pair<T>(lst.first(), lst.last(), doSort)
Pair<T>(list.first(), list.last(), doSort)
{}
template<class T>
inline Foam::Pair<T>::Pair(Istream& is)
:
......@@ -132,16 +155,16 @@ inline const T& Foam::Pair<T>::other(const T& a) const
template<class T>
inline bool Foam::Pair<T>::sorted() const
inline void Foam::Pair<T>::flip()
{
return (first() < second());
Foam::Swap(first(), second());
}
template<class T>
inline void Foam::Pair<T>::flip()
inline bool Foam::Pair<T>::sorted() const
{
Foam::Swap(first(), second());
return !(second() < first());
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -38,45 +38,35 @@ See also
#define Tuple2_H
#include "Istream.H"
#include "Ostream.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
template<class Type1, class Type2>
class Tuple2;
template<class Type1, class Type2>
inline Istream& operator>>(Istream& is, Tuple2<Type1, Type2>& t2);
template<class Type1, class Type2>
inline Ostream& operator<<(Ostream& os, const Tuple2<Type1, Type2>& t2);
/*---------------------------------------------------------------------------*\
Class Tuple2 Declaration
\*---------------------------------------------------------------------------*/
template<class Type1, class Type2>
template<class T1, class T2>
class Tuple2
{
// Private data
// Private Data
Type1 f_;
Type2 s_;
T1 f_;
T2 s_;
public:
// Typedefs (cf. std::pair)
//- Type of member first, the first template parameter (Type1)
typedef Type1 first_type;
//- Type of member first, the first template parameter (T1)
typedef T1 first_type;
//- Type of member second, the second template parameter (Type2)
typedef Type2 second_type;
//- Type of member second, the second template parameter (T2)
typedef T2 second_type;
// Constructors
......@@ -84,13 +74,34 @@ public:
//- Construct null
inline Tuple2() = default;
//- Construct from components
inline Tuple2(const Type1& f, const Type2& s)
//- Copy construct from components
inline Tuple2(const T1& f, const T2& s)
:
f_(f),
s_(s)
{}
//- Move construct from components
inline Tuple2(T1&& f, T2&& s)
:
f_(std::move(f)),
s_(std::move(s))
{}
//- Copy construct from std::pair
inline Tuple2(const std::pair<T1,T2>& vals)
:
f_(vals.first),
s_(vals.second)
{}
//- Move construct from std::pair
inline Tuple2(std::pair<T1,T2>&& vals)
:
f_(std::move(vals.first)),
s_(std::move(vals.second))
{}
//- Construct from Istream
inline explicit Tuple2(Istream& is)
{
......@@ -101,136 +112,94 @@ public:
// Member Functions
//- Return first
inline const Type1& first() const
inline const T1& first() const
{
return f_;
}
//- Return first
inline Type1& first()
inline T1& first()
{
return f_;
}
//- Return second
inline const Type2& second() const
inline const T2& second() const
{
return s_;
}
//- Return second
inline Type2& second()
inline T2& second()
{
return s_;
}
// IOstream operators
//- Read Tuple2 from Istream, discarding contents of existing Tuple2.
friend Istream& operator>> <Type1, Type2>
(
Istream& is,
Tuple2<Type1, Type2>& t2
);
// Write Tuple2 to Ostream.
friend Ostream& operator<< <Type1, Type2>
(
Ostream& os,
const Tuple2<Type1, Type2>& t2
);
};
//- Return reverse of a Tuple2
template<class Type1, class Type2>
inline Tuple2<Type2, Type1> reverse(const Tuple2<Type1, Type2>& t)
template<class T1, class T2>
inline Tuple2<T2, T1> reverse(const Tuple2<T1,T2>& t)
{
return Tuple2<Type2, Type1>(t.second(), t.first());
return Tuple2<T2, T1>(t.second(), t.first());
}
template<class Type1, class Type2>
inline bool operator==
(
const Tuple2<Type1, Type2>& a,
const Tuple2<Type1, Type2>& b
)
template<class T1, class T2>
inline bool operator==(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
{
return (a.first() == b.first() && a.second() == b.second());
}
template<class Type1, class Type2>
inline bool operator!=
(
const Tuple2<Type1, Type2>& a,
const Tuple2<Type1, Type2>& b
)
template<class T1, class T2>
inline bool operator!=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
{
return !(a == b);
}
template<class Type1, class Type2>
inline bool operator<
(
const Tuple2<Type1, Type2>& a,
const Tuple2<Type1, Type2>& b
)
template<class T1, class T2>
inline bool operator<(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
{
return
(
a.first() < b.first()
||
(
!(b.first() < a.first())
&& a.second() < b.second()
)
|| (!(b.first() < a.first()) && a.second() < b.second())
);
}
template<class Type1, class Type2>
inline bool operator<=
(
const Tuple2<Type1, Type2>& a,
const Tuple2<Type1, Type2>& b
)
template<class T1, class T2>
inline bool operator<=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
{
return !(b < a);
}
template<class Type1, class Type2>
inline bool operator>
(
const Tuple2<Type1, Type2>& a,
const Tuple2<Type1, Type2>& b
)
template<class T1, class T2>
inline bool operator>(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
{
return (b < a);
}
template<class Type1, class Type2>
inline bool operator>=
(
const Tuple2<Type1, Type2>& a,
const Tuple2<Type1, Type2>& b
)
template<class T1, class T2>
inline bool operator>=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
{
return !(a < b);
}
template<class Type1, class Type2>
inline Istream& operator>>(Istream& is, Tuple2<Type1, Type2>& t2)
// IOstream Operators
//- Read Tuple2 from Istream, discarding contents of existing Tuple2.
template<class T1, class T2>
inline Istream& operator>>(Istream& is, Tuple2<T1,T2>& t)
{
is.readBegin("Tuple2");
is >> t2.f_ >> t2.s_;
is >> t.first() >> t.second();
is.readEnd("Tuple2");
is.check(FUNCTION_NAME);
......@@ -238,11 +207,37 @@ inline Istream& operator>>(Istream& is, Tuple2<Type1, Type2>& t2)
}
template<class Type1, class Type2>
inline Ostream& operator<<(Ostream& os, const Tuple2<Type1, Type2>& t2)
//- Read std::pair from Istream
template<class T1, class T2>
inline Istream& operator>>(Istream& is, std::pair<T1,T2>& t)
{
is.readBegin("std::pair");
is >> t.first >> t.second;
is.readEnd("std::pair");
is.check(FUNCTION_NAME);
return is;
}
//- Write Tuple2 to Ostream.
template<class T1, class T2>
inline Ostream& operator<<(Ostream& os, const Tuple2<T1,T2>& t)
{
os << token::BEGIN_LIST
<< t.first() << token::SPACE << t.second()
<< token::END_LIST;
return os;
}
//- Write std::pair to Ostream.
template<class T1, class T2>
inline Ostream& operator<<(Ostream& os, const std::pair<T1,T2>& t)
{
os << token::BEGIN_LIST
<< t2.f_ << token::SPACE << t2.s_
<< t.first << token::SPACE << t.second
<< token::END_LIST;
return os;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment