You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
6.4 KiB
C
218 lines
6.4 KiB
C
1 year ago
|
/***************************************************************************
|
||
|
* Copyright (C) gempa GmbH *
|
||
|
* All rights reserved. *
|
||
|
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||
|
* *
|
||
|
* GNU Affero General Public License Usage *
|
||
|
* This file may be used under the terms of the GNU Affero *
|
||
|
* Public License version 3.0 as published by the Free Software Foundation *
|
||
|
* and appearing in the file LICENSE included in the packaging of this *
|
||
|
* file. Please review the following information to ensure the GNU Affero *
|
||
|
* Public License version 3.0 requirements will be met: *
|
||
|
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||
|
* *
|
||
|
* Other Usage *
|
||
|
* Alternatively, this file may be used in accordance with the terms and *
|
||
|
* conditions contained in a signed written agreement between you and *
|
||
|
* gempa GmbH. *
|
||
|
***************************************************************************/
|
||
|
|
||
|
|
||
|
#ifndef SEISCOMP_CORE_ENUMERATION_H
|
||
|
#define SEISCOMP_CORE_ENUMERATION_H
|
||
|
|
||
|
|
||
|
#include <seiscomp/core/io.h>
|
||
|
|
||
|
|
||
|
namespace Seiscomp {
|
||
|
namespace Core {
|
||
|
|
||
|
|
||
|
class SC_SYSTEM_CORE_API Enumeration {
|
||
|
public:
|
||
|
virtual ~Enumeration();
|
||
|
|
||
|
/**
|
||
|
* Converts an enumeration to its string representation
|
||
|
* @return The enumeration value string
|
||
|
*/
|
||
|
virtual const char *toString() const = 0;
|
||
|
|
||
|
/**
|
||
|
* Converts a string to an enumeration value.
|
||
|
* @param str The name of the enumeration value. This name is
|
||
|
* case sensitive.
|
||
|
* @return The result of the conversion
|
||
|
*/
|
||
|
virtual bool fromString(const std::string &str) = 0;
|
||
|
|
||
|
/**
|
||
|
* Converts an enumeration value to an integer
|
||
|
* @return The integer value
|
||
|
*/
|
||
|
virtual int toInt() const = 0;
|
||
|
|
||
|
/**
|
||
|
* Converts an integer to an enumeration value
|
||
|
* @param value The integer value to be converted
|
||
|
* @return The result of the conversion
|
||
|
*/
|
||
|
virtual bool fromInt(int value) = 0;
|
||
|
};
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
/** \brief An enumeration class that supports string conversion and
|
||
|
* \brief serialization
|
||
|
*
|
||
|
* Native enumerations are difficult to serialize in string based
|
||
|
* archives like XML. This class implements automatic string
|
||
|
* conversion based on a name table created while compile time.
|
||
|
* To create an enumeration the preprocessor macros MAKEENUM should
|
||
|
* be used.
|
||
|
* MAKEENUM(Name, ValueList, NameList)
|
||
|
* \param Name The name of the enumeration
|
||
|
* \param ValueList The list of values created with EVALUES
|
||
|
* \param NameList The list of names created with ENAMES
|
||
|
* \code
|
||
|
* MAKEENUM(Type,
|
||
|
* EVALUES(
|
||
|
* AUTOMATIC,
|
||
|
* MANUAL
|
||
|
* ),
|
||
|
* ENAMES(
|
||
|
* "automatic",
|
||
|
* "manual"
|
||
|
* )
|
||
|
* );
|
||
|
* \endcode
|
||
|
*
|
||
|
* The above example expands to:
|
||
|
* \code
|
||
|
* enum EType { AUTOMATIC = 0x00, MANUAL, ETypeQuantity };
|
||
|
* class ETypeNames {
|
||
|
* public:
|
||
|
* static const char* name(int i) {
|
||
|
* static const char* names[] = { "automatic", "manual" };
|
||
|
* return names[i];
|
||
|
* }
|
||
|
* };
|
||
|
* typedef Enum<EType, AUTOMATIC, ETypeQuantity, ETypeNames> Type;
|
||
|
* \endcode
|
||
|
*
|
||
|
* The class Type can be used like native enumerations.
|
||
|
* \code
|
||
|
* Type value = AUTOMATIC;
|
||
|
* assert(value == AUTOMATIC);
|
||
|
*
|
||
|
* printf("value = %s", value.toString());
|
||
|
* value.fromString("manual"); // enumeration names are case sensitive
|
||
|
* assert(value == MANUAL);
|
||
|
* \endcode
|
||
|
*
|
||
|
* NOTE: Because SWIG does not support nested classes (version 1.3.27)
|
||
|
* the MAKENUM macro should no be used inside of class definitions.
|
||
|
* However, in C++ it can be placed nearly anywhere.
|
||
|
*/
|
||
|
template <typename ENUMTYPE, ENUMTYPE END, typename NAMES>
|
||
|
class Enum : public Enumeration {
|
||
|
// ------------------------------------------------------------------
|
||
|
// Typetraits
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
typedef ENUMTYPE Type;
|
||
|
typedef NAMES NameDispatcher;
|
||
|
static const ENUMTYPE First = ENUMTYPE(0);
|
||
|
static const ENUMTYPE End = ENUMTYPE(END - 1);
|
||
|
static const ENUMTYPE Quantity = ENUMTYPE(END - 0);
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Xstruction
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
//! C'tor
|
||
|
Enum(ENUMTYPE value = ENUMTYPE(0));
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Operators
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
operator ENUMTYPE() const;
|
||
|
|
||
|
bool operator==(ENUMTYPE value) const;
|
||
|
bool operator!=(ENUMTYPE value) const;
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Serialization
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
void serialize(Archive &ar);
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Conversion
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
const char *toString() const override;
|
||
|
bool fromString(const std::string &str) override;
|
||
|
|
||
|
int toInt() const override;
|
||
|
bool fromInt(int value) override;
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Implementation
|
||
|
// ------------------------------------------------------------------
|
||
|
protected:
|
||
|
ENUMTYPE _value;
|
||
|
};
|
||
|
|
||
|
|
||
|
#define ENUMNAME(Name, ...) \
|
||
|
class E##Name##Names { \
|
||
|
public: \
|
||
|
E##Name##Names() {} \
|
||
|
static const char* name(int i) { \
|
||
|
static const char* names[] = { __VA_ARGS__ }; \
|
||
|
return names[i]; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define ENUMWRAPPERCLASS(Name) Seiscomp::Core::Enum<E##Name, E##Name##Quantity, E##Name##Names>
|
||
|
|
||
|
#define ENUMX(Name, ...) \
|
||
|
enum E##Name { \
|
||
|
__VA_ARGS__, \
|
||
|
E##Name##Quantity \
|
||
|
}; \
|
||
|
class E##Name##Names
|
||
|
|
||
|
#define ENUMXNAMES(Name, ...) \
|
||
|
ENUMNAME(Name, __VA_ARGS__)
|
||
|
|
||
|
|
||
|
#define EVALUES(...) __VA_ARGS__
|
||
|
#define ENAMES(...) __VA_ARGS__
|
||
|
|
||
|
#define PREPAREENUM(Name, DEFS, NAMES) \
|
||
|
ENUMX(Name, DEFS); \
|
||
|
ENUMXNAMES(Name, NAMES)
|
||
|
|
||
|
#define MAKEENUM(Name, DEFS, NAMES) \
|
||
|
ENUMX(Name, DEFS); \
|
||
|
ENUMXNAMES(Name, NAMES); \
|
||
|
typedef ENUMWRAPPERCLASS(Name) Name
|
||
|
|
||
|
|
||
|
#include <seiscomp/core/enumeration.inl>
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|