Skip to content
Snippets Groups Projects
Enum.H 12.4 KiB
Newer Older
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  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) 2017-2021 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/>.

Class
    Foam::Enum

Description
    Enum is a wrapper around a list of names/values that represent particular
    enumeration (or int) values.
    All dictionary searches use a literal (not regex).
Mark OLESEN's avatar
Mark OLESEN committed
    EnumI.H

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

#ifndef Enum_H
#define Enum_H

#include "wordList.H"
#include <utility>

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

namespace Foam
{
// Forward Declarations
class dictionary;
template<class EnumType> class Enum;

/*---------------------------------------------------------------------------*\
                            Class Enum Declaration
\*---------------------------------------------------------------------------*/

template<class EnumType>
class Enum
{
    // Private Member Data

        //- The names for the enum
Mark OLESEN's avatar
Mark OLESEN committed
        List<word> keys_;
        //- The values for the enum, stored as int
Mark OLESEN's avatar
Mark OLESEN committed
        List<int> vals_;
    // Allow enums and integrals (should fit within an int)
Mark OLESEN's avatar
Mark OLESEN committed
    static_assert
    (
        std::is_enum<EnumType>::value || std::is_integral<EnumType>::value,
        "Enum must be enum or an integral type"
    );

public:

    // Typedefs

        //- The type of keys used
        typedef word key_type;

        //- The type of enumeration represented by the Enum
        typedef EnumType value_type;

        //- Default construct, an empty list
        Enum() noexcept = default;
        //- Construct from a values/names list.
        //  Duplicate values are permitted (eg, for aliases).
        //  Duplicate names are permitted, but won't make much sense.
Mark OLESEN's avatar
Mark OLESEN committed
        explicit Enum
        (
            std::initializer_list<std::pair<EnumType, const char*>> list
        );
    // Access
        //- True if the enumeration list is empty.
        inline bool empty() const noexcept;

Mark OLESEN's avatar
Mark OLESEN committed
        //- The number of name/value pairs for the enumeration.
        inline label size() const noexcept;
Mark OLESEN's avatar
Mark OLESEN committed
        //- The list of enum names, in construction order. Same as toc()
        inline const List<word>& names() const noexcept;

        //- The list of enum values, in construction order.
        inline const List<int>& values() const noexcept;
Mark OLESEN's avatar
Mark OLESEN committed
        //- The list of enum names, in construction order. Same as names()
        inline const List<word>& toc() const noexcept;
Mark OLESEN's avatar
Mark OLESEN committed
        //- The sorted list of enum names.
        inline List<word> sortedToc() const;
    // Modify

        //- Clear all entries
        inline void clear();

        //- Append value/key pairs to the lists of known enumerations
        //  Does not check for duplicate entries
        void append
        (
            std::initializer_list<std::pair<EnumType, const char*>> list
        );


    // Query
Mark OLESEN's avatar
Mark OLESEN committed
        //- Find the index of the given name.
        //  \return position in list or -1 if not found.
        inline label find(const word& enumName) const;

        //- Find the first index of given enumeration.
        //  \return position in list or -1 if not found.
        inline label find(const EnumType e) const;

        //- True if there is an enumeration corresponding to the given name.
        inline bool found(const word& enumName) const;

        //- True if there is a name corresponding to the given enumeration.
        inline bool found(const EnumType e) const;

Mark OLESEN's avatar
Mark OLESEN committed
        //- The enumeration corresponding to the given name.
        //  FatalError if not found.
        EnumType get(const word& enumName) const;
Mark OLESEN's avatar
Mark OLESEN committed
        //- The name corresponding to the given enumeration.
        //  Return an empty word if there is no corresponding name for it.
Mark OLESEN's avatar
Mark OLESEN committed
        inline const word& get(const EnumType e) const;
        //- The enumeration corresponding to the given name.
        //  \return The enumeration or default if not found.
        //  \note Method name compatibility with HashTable
        EnumType lookup(const word& enumName, const EnumType deflt) const;

        //- Get the key in the dictionary and return the corresponding
        //- enumeration element based on its name.
        //  FatalIOError if anything is incorrect.
Mark OLESEN's avatar
Mark OLESEN committed
        EnumType get
        (
            const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
            const dictionary& dict  //!< dictionary
        ) const;

        //- Find the key in the dictionary and return the corresponding
        //- enumeration element based on its name.
Mark OLESEN's avatar
Mark OLESEN committed
        //
        //  \return The value found or default if not found in dictionary.
        //  FatalIOError if the enumeration is incorrect.
        //  Specifying failsafe downgrades the FatalIOError to an IOWarning.
Mark OLESEN's avatar
Mark OLESEN committed
            const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
            const dictionary& dict, //!< dictionary
            const EnumType deflt,   //!< fallback if not found
Mark OLESEN's avatar
Mark OLESEN committed
            const bool failsafe = false  //!< Warn only on bad enumeration
Mark OLESEN's avatar
Mark OLESEN committed
        //- Find entry and assign to T val.
        //  FatalIOError if the enumeration is incorrect,
        //  or when it is mandatory but was not found.
Mark OLESEN's avatar
Mark OLESEN committed
        //
        //  \return true if the entry was found.
        bool readEntry
        (
            const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
            const dictionary& dict, //!< dictionary
            EnumType& val,          //!< the value to read into
            const bool mandatory = true   //!< the keyword is mandatory
Mark OLESEN's avatar
Mark OLESEN committed
        ) const;
Mark OLESEN's avatar
Mark OLESEN committed
        //- Find an entry if present, and assign to T val.
        //  FatalIOError if the enumeration is incorrect.
Mark OLESEN's avatar
Mark OLESEN committed
        //  Default search: non-recursive with patterns.
        //
        //  \return true if the entry was found.
        inline bool readIfPresent
Mark OLESEN's avatar
Mark OLESEN committed
            const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
            const dictionary& dict, //!< dictionary
            EnumType& val           //!< the value to read into

        //- Read a word from Istream and return the corresponding enumeration
        EnumType read(Istream& is) const;

        //- Read a word from Istream, lookup named enumeration.
        //  \return true on success. Fatal if mandatory and not found.
        bool read
        (
            Istream& is,
            EnumType& val,
            const bool mandatory = true
        ) const;

        //- Write the name representation of the enumeration to an Ostream
        //  A noop if the enumeration wasn't found.
Mark OLESEN's avatar
Mark OLESEN committed
        inline void write(const EnumType e, Ostream& os) const;
        //- Write enumeration names as a list without line-breaks
        //- to an output stream.
        template<class OS>
        inline OS& writeList(OS& os, const label ununsed=0) const;


    // Member Operators

        //- Return the enumeration corresponding to the given name
        //  FatalError if the name is not found.
        //  Identical to get()
        inline EnumType operator[](const word& enumName) const;
        //- Return the first name corresponding to the given enumeration,
        //- or an empty word on failure.
        //  Identical to get()
        inline const word& operator[](const EnumType e) const;

    // Iteration

        //- A const_iterator for iterating an Enum list
        //  \note The iterator dereference returns the \b key
        class const_iterator
        {
            //- The list being iterated
            const Enum* ptr_;

            //- Index in the list
            label idx_;

        public:

            //- Default construct, construct at given position
            inline explicit const_iterator
            (
                const Enum* eptr = nullptr,
                const label idx = 0
            ) noexcept;

            //- The name at the current index
            inline const word& key() const;

            //- Enumeration value at the current index
            inline EnumType val() const;

            //- De-referencing returns the name (key)
            //  This is similar to HashSet (not HashTable!) and allows
            //  convenient output and traversing of the names
            const word& operator*() const { return key(); }

            //- Move to the next index
            inline const_iterator& operator++() noexcept;

            inline bool operator==(const const_iterator& iter) const noexcept;
            inline bool operator!=(const const_iterator& iter) const noexcept;
        };

        inline const_iterator cbegin() const noexcept;
        inline const_iterator cend() const noexcept;
        const_iterator begin() const noexcept { return cbegin(); }
        const_iterator end() const noexcept { return cend(); }
Mark OLESEN's avatar
Mark OLESEN committed
    // Housekeeping
        //- Find the key in the dictionary and return the corresponding
        //- enumeration element based on its name.
        //
        //  \return The value found or default if not found in dictionary.
        //  FatalError (or Warning) if the enumeration was incorrect.
        EnumType lookupOrDefault
        (
            const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
            const dictionary& dict, //!< dictionary
            const EnumType deflt,   //!< fallback if not found
            const bool failsafe = false //!< Warn only on bad enumeration
        ) const
        {
            return getOrDefault(key, dict, deflt, failsafe);
        }


        //- Deprecated(2020-11) use get() method
        //  \deprecated(2020-11) - use get() method
        FOAM_DEPRECATED_FOR(2020-11, "get() method")
        const word& operator()(const EnumType e) const
        {
            return get(e);
        }

        //- Deprecated(2020-11) use two-parameter lookup() method
        //  \deprecated(2020-11) - use two-parameter lookup() method
        FOAM_DEPRECATED_FOR(2020-11, "lookup() method")
        EnumType operator()(const word& key, const EnumType deflt) const
        {
            return lookup(key, deflt);
        }

        //- Deprecated(2020-11) use two-parameter lookup() method
        //  \deprecated(2020-11) - use two-parameter lookup() method
        FOAM_DEPRECATED_FOR(2020-11, "lookup() method")
        EnumType get(const word& key, const EnumType deflt) const
        {
            return lookup(key, deflt);
        }

        //- Deprecated(2018-10) same as two-parameter get() method
        //  \deprecated(2018-10) - use two-parameter get() method
        FOAM_DEPRECATED_FOR(2018-10, "get() method")
        EnumType lookup(const word& key, const dictionary& dict) const
Mark OLESEN's avatar
Mark OLESEN committed
        {
            return get(key, dict);
        }
Mark OLESEN's avatar
Mark OLESEN committed
// Ostream Operator

//- Write enumeration names, without line-breaks (ie, FlatOutput)
template<class EnumType>
inline Ostream& operator<<(Ostream& os, const Enum<EnumType>& list);

//- Write enumeration names, without line-breaks (ie, FlatOutput)
template<class EnumType>
inline std::ostream& operator<<(std::ostream& os, const Enum<EnumType>& list);

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

} // End namespace Foam

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

#include "EnumI.H"

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

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

#endif

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