/*---------------------------------------------------------------------------*\

    geophase: A C++ template library for geometrical operations on non-convex
    polyhedra with non-planar faces
     
    Copyright (C) 2019 Tomislav Maric, TU Darmstadt 

    This program 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.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.


Description
    A sequence of halfspaces.

Author
    Tomislav Maric maric@mma.tu-darmstadt.de

\*---------------------------------------------------------------------------*/

#ifndef HalfspaceSequence_H
#define HalfspaceSequence_H

#include <list>
#include <deque>
#include <vector>

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam { namespace GeometricalTransport { 

/*---------------------------------------------------------------------------*\
                         Class HalfspaceSequence Declaration
\*---------------------------------------------------------------------------*/

template
<
    typename Halfspace,    
    template<typename, typename> class SequenceContainer,
    template <typename T> class Allocator = std::allocator
>
class HalfspaceSequence 
:
    public SequenceContainer
    <
        typename std::enable_if
        <
            Traits::tag_enabled<Halfspace, halfspace_tag>::value, 
            Halfspace
        >::type,
        Allocator<Halfspace>
    >
{
    typedef SequenceContainer<Halfspace, Allocator<Halfspace>> base;

    public: 

        using base::base; 

        void flip() 
        {
            for (auto & hspace : *this)
                hspace.flip();
        }
};

namespace Traits {

    template
    <
        typename Halfspace,    
        template<typename, typename> class Sequence,
        template <typename T> class Allocator 
    >
    struct tag 
    <
        HalfspaceSequence<Halfspace, Sequence, Allocator>
    >
    {
        typedef halfspace_sequence_tag type;
    };

    template<typename Halfspace>
    struct tag 
    <
        HalfspaceSequence<Halfspace, std::vector>
    >
    {
        typedef halfspace_sequence_direct_tag type;
    };

    template<typename Halfspace>
    struct tag 
    <
        HalfspaceSequence<Halfspace, std::deque>
    >
    {
        typedef halfspace_sequence_direct_tag type;
    };

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // end namespace Geometry::Traits 

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

}} // end namespace Foam::GeometricalTransport

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //
