Skip to content
Snippets Groups Projects
Tuple2.H 8.52 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        \\  /    A nd           | www.openfoam.com
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        Copyright (C) 2011-2016 OpenFOAM Foundation
    
        Copyright (C) 2019-2020 OpenCFD Ltd.
    
    -------------------------------------------------------------------------------
    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 3 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, see <http://www.gnu.org/licenses/>.
    
        A 2-tuple for storing two objects of dissimilar types.
        The container is similar in purpose to std::pair, but does not expose
        its members directly.
    
    Mark Olesen's avatar
    Mark Olesen committed
        Foam::Pair for storing two objects of identical types.
    
    
    \*---------------------------------------------------------------------------*/
    
    #ifndef Tuple2_H
    #define Tuple2_H
    
    #include "Istream.H"
    
    #include "Ostream.H"
    
    #include <utility>
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    /*---------------------------------------------------------------------------*\
    
                               Class Tuple2 Declaration
    
    \*---------------------------------------------------------------------------*/
    
    
    template<class T1, class T2 = T1>
    
        // Private Data
    
        // Typedefs (cf. std::pair)
    
    
            //- Type of member first, the first template parameter (T1)
            typedef T1 first_type;
    
            //- Type of member second, the second template parameter (T2)
            typedef T2 second_type;
    
            //- Default construct
            Tuple2() = default;
    
            //- Copy construct from components
            inline Tuple2(const T1& f, const T2& 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)
    
    Mark Olesen's avatar
    Mark Olesen committed
                is >> *this;
    
            inline const T1& first() const noexcept
    
            inline T1& first() noexcept
    
            inline const T2& second() const noexcept
    
            inline T2& second() noexcept
    
    // * * * * * * * * * * * * * * * * * Traits  * * * * * * * * * * * * * * * * //
    
    //- Hashing for Tuple2 data
    template<class T1, class T2>
    struct Hash<Tuple2<T1, T2>>
    {
        unsigned operator()(const Tuple2<T1, T2>& obj, unsigned seed=0) const
        {
            return Hash<T2>()(obj.second(), Hash<T1>()(obj.first(), seed));
        }
    };
    
    //- Hashing for std::pair data
    template<class T1, class T2>
    struct Hash<std::pair<T1, T2>>
    {
        unsigned operator()(const std::pair<T1, T2>& obj, unsigned seed=0) const
        {
            return Hash<T2>()(obj.second, Hash<T1>()(obj.first, seed));
        }
    };
    
    
    
    // * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * * //
    
    
    //- Return reverse of a Tuple2
    
    template<class T1, class T2>
    inline Tuple2<T2, T1> reverse(const Tuple2<T1,T2>& t)
    
        return Tuple2<T2, T1>(t.second(), t.first());
    
    // * * * * * * * * * * * * * * Global Operators  * * * * * * * * * * * * * * //
    
    
    template<class T1, class T2>
    inline bool operator==(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
    
    Mark Olesen's avatar
    Mark Olesen committed
        return (a.first() == b.first() && a.second() == b.second());
    
    template<class T1, class T2>
    inline bool operator!=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
    
    Mark Olesen's avatar
    Mark Olesen committed
        return !(a == 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())
    
    template<class T1, class T2>
    inline bool operator<=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
    
    template<class T1, class T2>
    inline bool operator>(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
    
    template<class T1, class T2>
    inline bool operator>=(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b)
    
    // * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * * //
    
    // Comparing first only
    
    //- Compare tuple-like containers
    //  \return reference to the container with the smaller value of first
    template<class T1>
    struct minFirstOp
    {
        const Pair<T1>& operator()(const Pair<T1>& a, const Pair<T1>& b) const
        {
            return (b.first() < a.first()) ? b : a;
        }
    
        template<class T2>
        const Tuple2<T1,T2>&
        operator()(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) const
        {
            return (b.first() < a.first()) ? b : a;
        }
    };
    
    
    //- Assign tuple-like container to use the one with the smaller value of first
    template<class T1>
    struct minFirstEqOp
    {
        void operator()(Pair<T1>& x, const Pair<T1>& y) const
        {
            if (y.first() < x.first()) x = y;
        }
    
        template<class T2>
        void operator()(Tuple2<T1,T2>& x, const Tuple2<T1,T2>& y) const
        {
            if (y.first() < x.first()) x = y;
        }
    };
    
    
    //- Compare tuple-like containers
    //  \return reference to the container with the larger value of first
    template<class T1>
    struct maxFirstOp
    {
        const Pair<T1>& operator()(const Pair<T1>& a, const Pair<T1>& b) const
        {
            return (a.first() < b.first()) ? b : a;
        }
    
        template<class T2>
        const Tuple2<T1,T2>&
        operator()(const Tuple2<T1,T2>& a, const Tuple2<T1,T2>& b) const
        {
            return (a.first() < b.first()) ? b : a;
        }
    };
    
    
    //- Assign tuple-like container to use the one with the larger value of first
    template<class T1>
    struct maxFirstEqOp
    {
        void operator()(Pair<T1>& x, const Pair<T1>& y) const
        {
            if (x.first() < y.first()) x = y;
        }
    
        template<class T2>
        void operator()(Tuple2<T1,T2>& x, const Tuple2<T1,T2>& y) const
        {
            if (x.first() < y.first()) x = y;
        }
    };
    
    
    // * * * * * * * * * * * * * * * 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 >> t.first() >> t.second();
    
    //- 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
    
            << t.first << token::SPACE << t.second
    
            << token::END_LIST;
    
    Mark Olesen's avatar
    Mark Olesen committed
    
    
        return os;
    }
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    #endif
    
    // ************************************************************************* //