/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | www.openfoam.com
     \\/     M anipulation  |
-------------------------------------------------------------------------------
    Copyright (C) 2019-2022 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/>.

InNamespace
    Foam

Description
    Functions to operate on Pointer Lists.

Namespace
    Foam::PtrListOps

Description
    Various utility functions to operate on Pointer Lists.

SourceFiles
    PtrListOpsTemplates.C

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

#ifndef Foam_PtrListOps_H
#define Foam_PtrListOps_H

#include "predicates.H"
#include "PtrList.H"
#include "ListOps.H"

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

namespace Foam
{

//- Return (stable) sort order for the list
template<class T>
labelList sortedOrder(const UPtrList<T>& list);

//- Generate (stable) sort order for the list
template<class T>
void sortedOrder(const UPtrList<T>& list, labelList& order);

//- Generate (stable) sort order for the list,
//- using the specified list compare predicate
template<class T, class ListComparePredicate>
void sortedOrder
(
    const UPtrList<T>& list,
    labelList& order,
    const ListComparePredicate& comp
);


//- Inplace shuffle of pointer list.
template<class T>
void shuffle(UPtrList<T>& list);


/*---------------------------------------------------------------------------*\
                       Namespace PtrListOps Declaration
\*---------------------------------------------------------------------------*/

namespace PtrListOps
{

//- List of values generated by applying the access operation
//- to each list item.
//
//  For example,
//  \code
//  PtrListOps::get(mesh.boundaryMesh(), nameOp<polyPatch>());
//  \endcode
template<class ReturnType, class T, class AccessOp>
List<ReturnType> get
(
    const UPtrList<T>& list,
    const AccessOp& aop
);


//- List of names generated by calling \c name() for each list item
//- and filtered for matches
//
//  For example,
//  \code
//  wordRes matches(...);
//  PtrListOps::names(mesh.boundaryMesh(), matches);
//
//  PtrListOps::names(mesh.boundaryMesh(), predicates::always());
//  \endcode
template<class T, class UnaryMatchPredicate>
List<word> names
(
    const UPtrList<T>& list,
    const UnaryMatchPredicate& matcher
);


//- List of names generated by calling \c name() for each list item
//- no filtering (ie, predicates::always)
template<class T>
List<word> names(const UPtrList<T>& list);


//- Find first list item with 'name()' that matches, -1 on failure
template<class T, class UnaryMatchPredicate>
label firstMatching
(
    const UPtrList<T>& list,
    const UnaryMatchPredicate& matcher
);


//- Extract list indices for all items with 'name()' that matches
template<class T, class UnaryMatchPredicate>
labelList findMatching
(
    const UPtrList<T>& list,
    const UnaryMatchPredicate& matcher
);

} // End namespace ListOps


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

} // End namespace Foam

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

#ifdef NoRepository
    #include "PtrListOpsTemplates.C"
#endif

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

#endif

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