| #include <iostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <map>
using namespace std;
namespace umba {
namespace enum_helpers {
// template<typename Integer, std::enable_if_t<std::is_integral<Integer>::value, bool> = true>
// T(Integer) : type(int_t) {}
//----------------------------------------------------------------------------
//! Конвертирует enum в подлежащий тип. Версия для 'честных' enum'ов.
template< typename EnumType, typename std::enable_if< std::is_enum<EnumType>::value, bool>::type = true > inline
typename std::underlying_type< EnumType >::type toUnderlyingType( EnumType flagsVal )
{
typedef typename std::underlying_type< EnumType >::type EnumUnderlyingType;
return (EnumUnderlyingType)flagsVal;
}
//----------------------------------------------------------------------------
//! Конвертирует enum в подлежащий тип. Версия для интегральных типов.
/*! Часто неохота разбираться, является ли значение int'ом, unsigned'ом, или другим интегральным типом,
или же является enum'ом.
*/
template< typename EnumType, typename std::enable_if< (!std::is_enum<EnumType>::value
&& std::is_integral<EnumType>::value
)
, bool>::type = true
> inline
EnumType toUnderlyingType( EnumType flagsVal )
{
return flagsVal;
}
//----------------------------------------------------------------------------
//! Конвертирует в enum из подлежащего типа. Версия для 'честных' enum'ов.
template< typename EnumType, typename std::enable_if< std::is_enum<EnumType>::value, bool
>::type = true > inline
EnumType fromUnderlyingType( typename std::underlying_type< EnumType >::type flagsVal )
{
return (EnumType)flagsVal;
}
//----------------------------------------------------------------------------
//! Конвертирует в enum из подлежащего типа. Версия для интегральных типов.
/*! Часто неохота разбираться, является ли значение int'ом, unsigned'ом, или другим интегральным типом,
или же является enum'ом.
*/
template< typename EnumType, typename std::enable_if< (!std::is_enum<EnumType>::value
&& std::is_integral< EnumType >::value
)
, bool>::type = true
> inline
EnumType fromUnderlyingType( EnumType flagsVal )
{
return flagsVal;
}
//----------------------------------------------------------------------------
template< typename EnumType > inline
bool enumLessImpl(EnumType e1, EnumType e2)
{
typedef typename std::underlying_type< EnumType >::type EnumUnderlyingType;
return (EnumUnderlyingType)e1 < (EnumUnderlyingType)e2;
}
//----------------------------------------------------------------------------
template< typename EnumType > inline
bool enumLessEqualImpl(EnumType e1, EnumType e2)
{
typedef typename std::underlying_type< EnumType >::type EnumUnderlyingType;
return (EnumUnderlyingType)e1 <= (EnumUnderlyingType)e2;
}
//----------------------------------------------------------------------------
template< typename EnumType > inline
bool enumGreaterImpl(EnumType e1, EnumType e2)
{
typedef typename std::underlying_type< EnumType >::type EnumUnderlyingType;
return (EnumUnderlyingType)e1 > (EnumUnderlyingType)e2;
}
//----------------------------------------------------------------------------
template< typename EnumType > inline
bool enumGreaterEqualImpl(EnumType e1, EnumType e2)
{
typedef typename std::underlying_type< EnumType >::type EnumUnderlyingType;
return (EnumUnderlyingType)e1 >= (EnumUnderlyingType)e2;
}
} // namespace enum_helpers
} // namespace umba
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#define UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNARY_OPERATOR_IMPL(EnumType, operatorSign) \
inline \
EnumType operator operatorSign( EnumType e ) \
{ \
return umba::enum_helpers::fromUnderlyingType<EnumType>( \
operatorSign \
umba::enum_helpers::toUnderlyingType<EnumType>(e) \
); \
}
//------------------------------
#define UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType, operatorSign) \
inline \
EnumType operator operatorSign( EnumType e1, EnumType e2) \
{ \
return umba::enum_helpers::fromUnderlyingType<EnumType>( \
umba::enum_helpers::toUnderlyingType<EnumType>(e1) \
operatorSign \
umba::enum_helpers::toUnderlyingType<EnumType>(e2) \
); \
} \
inline \
EnumType& operator operatorSign##=( EnumType &e1, EnumType e2) \
{ \
e1 = e1 operatorSign e2; \
return e1; \
}
//------------------------------
#define UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType, operatorSign) \
inline \
EnumType operator operatorSign( EnumType e1, typename std::underlying_type< EnumType >::type e2) \
{ \
return umba::enum_helpers::fromUnderlyingType<EnumType>( \
umba::enum_helpers::toUnderlyingType<EnumType>(e1) \
operatorSign \
e2 \
); \
} \
inline \
EnumType operator operatorSign( typename std::underlying_type< EnumType >::type e1, EnumType e2) \
{ \
return umba::enum_helpers::fromUnderlyingType<EnumType>( \
e1 \
operatorSign \
umba::enum_helpers::toUnderlyingType<EnumType>(e2) \
); \
} \
inline \
EnumType& operator operatorSign##=( EnumType &e1, typename std::underlying_type< EnumType >::type e2) \
{ \
e1 = e1 operatorSign e2; \
return e1; \
}
//------------------------------
#define UMBA_ENUM_CLASS_IMPLEMENT_ENUM_SHIFT_OPERATOR_IMPL(EnumType, operatorSign) \
inline \
EnumType operator operatorSign( EnumType e, unsigned sh ) \
{ \
return umba::enum_helpers::fromUnderlyingType<EnumType>( \
umba::enum_helpers::toUnderlyingType<EnumType>(e) \
operatorSign \
sh \
); \
} \
inline \
EnumType& operator operatorSign##=( EnumType &e, unsigned sh ) \
{ \
e = e operatorSign sh; \
return e; \
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//! Реализует битовые операции для enum-типа
#define UMBA_ENUM_CLASS_IMPLEMENT_BIT_OPERATORS( EnumType ) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNARY_OPERATOR_IMPL (EnumType,~) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,|) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,&) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,^) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_SHIFT_OPERATOR_IMPL (EnumType,<<) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_SHIFT_OPERATOR_IMPL (EnumType,>>)
//----------------------------------------------------------------------------
//! Реализует битовые операции для enum-типа и подлежащего типа
#define UMBA_ENUM_CLASS_IMPLEMENT_UNDERLYING_TYPE_BIT_OPERATORS( EnumType ) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,|) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,&) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,^)
//----------------------------------------------------------------------------
//! Реализует арифметические операции для enum-типа
#define UMBA_ENUM_CLASS_IMPLEMENT_ARITHMETIC_OPERATORS( EnumType ) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNARY_OPERATOR_IMPL (EnumType,+) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNARY_OPERATOR_IMPL (EnumType,-) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,+) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,-) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,*) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,%) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_BINARY_OPERATOR_IMPL(EnumType,/)
//----------------------------------------------------------------------------
//! Реализует арифметические операции для enum-типа и подлежащего типа
#define UMBA_ENUM_CLASS_IMPLEMENT_UNDERLYING_TYPE_ARITHMETIC_OPERATORS( EnumType ) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,+) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,-) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,*) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,/) \
UMBA_ENUM_CLASS_IMPLEMENT_ENUM_UNDERLYING_TYPE_BINARY_OPERATOR_IMPL(EnumType,%)
//----------------------------------------------------------------------------
//! Реализует операции сравнения больше/меньше для enum-типа
#define UMBA_ENUM_CLASS_IMPLEMENT_RELATION_OPERATORS( EnumType ) \
\
inline bool operator< (EnumType e1, EnumType e2) { return umba::enum_helpers::enumLessImpl (e1, e2); } \
inline bool operator<=(EnumType e1, EnumType e2) { return umba::enum_helpers::enumLessEqualImpl (e1, e2); } \
inline bool operator> (EnumType e1, EnumType e2) { return umba::enum_helpers::enumGreaterImpl (e1, e2); } \
inline bool operator>=(EnumType e1, EnumType e2) { return umba::enum_helpers::enumGreaterEqualImpl(e1, e2); }
//----------------------------------------------------------------------------
//! Реализует операции сравнения больше/меньше для enum-типа и подлежащего типа
#define UMBA_ENUM_CLASS_IMPLEMENT_UNDERLYING_TYPE_RELATION_OPERATORS( EnumType ) \
\
inline bool operator< (EnumType e1, typename std::underlying_type< EnumType >::type e2) { return umba::enum_helpers::enumLessImpl (e1, (EnumType)e2); } \
inline bool operator<=(EnumType e1, typename std::underlying_type< EnumType >::type e2) { return umba::enum_helpers::enumLessEqualImpl (e1, (EnumType)e2); } \
inline bool operator> (EnumType e1, typename std::underlying_type< EnumType >::type e2) { return umba::enum_helpers::enumGreaterImpl (e1, (EnumType)e2); } \
inline bool operator>=(EnumType e1, typename std::underlying_type< EnumType >::type e2) { return umba::enum_helpers::enumGreaterEqualImpl(e1, (EnumType)e2); } \
\
inline bool operator< (typename std::underlying_type< EnumType >::type e1, EnumType e2) { return umba::enum_helpers::enumLessImpl ((EnumType)e1, e2); } \
inline bool operator<=(typename std::underlying_type< EnumType >::type e1, EnumType e2) { return umba::enum_helpers::enumLessEqualImpl ((EnumType)e1, e2); } \
inline bool operator> (typename std::underlying_type< EnumType >::type e1, EnumType e2) { return umba::enum_helpers::enumGreaterImpl ((EnumType)e1, e2); } \
inline bool operator>=(typename std::underlying_type< EnumType >::type e1, EnumType e2) { return umba::enum_helpers::enumGreaterEqualImpl((EnumType)e1, e2); }
//----------------------------------------------------------------------------
#define UMBA_ENUM_CLASS_IMPLEMENT_UNDERLYING_TYPE_EQUAL_OPERATORS( EnumType ) \
\
template<typename EnumType, typename IntType> inline \
bool operator==(EnumType e, IntType i) \
{ \
return umba::enum_helpers::toUnderlyingType(e)==umba::enum_helpers::toUnderlyingType(i); \
} \
\
template<typename EnumType, typename IntType> inline \
bool operator!=(EnumType e, IntType i) \
{ \
return umba::enum_helpers::toUnderlyingType(e)!=umba::enum_helpers::toUnderlyingType(i); \
} \
\
inline \
bool operator!(EnumType e) \
{ \
return e==0; \
}
/*
template<typename EnumType, typename IntType> inline \
bool operator==(IntType i, EnumType e) \
{ \
return umba::enum_helpers::toUnderlyingType(e)==umba::enum_helpers::toUnderlyingType(i); \
} \
\
template<typename EnumType, typename IntType> inline \
bool operator!=(IntType i, EnumType e) \
{ \
return umba::enum_helpers::toUnderlyingType(e)!=umba::enum_helpers::toUnderlyingType(i); \
} \
*/
enum EEE
{
zero,
one,
two
};
enum class CEEE
{
zero,
one,
two
};
enum class MoveFileFlags
{
copyAllowed = 1, //!< If the file is to be moved to a different volume, the function simulates the move by using the CopyFile and DeleteFile functions.
replaceExisting = 2, //!< If a file named lpNewFileName exists, the function replaces its contents with the contents of the lpExistingFileName file
overwrite = 2, //!< Same as replaceExisting
writeThrough = 4 //!< The function does not return until the file is actually moved on the disk. Setting this value guarantees that a move performed as a copy and delete operation is flushed to disk before the function returns. The flush occurs at the end of the copy operation.
};
UMBA_ENUM_CLASS_IMPLEMENT_BIT_OPERATORS(MoveFileFlags)
UMBA_ENUM_CLASS_IMPLEMENT_UNDERLYING_TYPE_BIT_OPERATORS(MoveFileFlags)
UMBA_ENUM_CLASS_IMPLEMENT_UNDERLYING_TYPE_EQUAL_OPERATORS(MoveFileFlags)
inline
bool isKindOfName(const std::unordered_set<std::string>& s, const std::string &name)
{
// строка 321 //return s.find(name)!=s.end();
return true;
}
int main()
{
using namespace umba::enum_helpers;
cout << "val of EEE::one: " << toUnderlyingType(one) << "\n";
cout << "val of EEE::two: " << toUnderlyingType(two) << "\n";
cout << "val of CEEE::one: " << toUnderlyingType(CEEE::one) << "\n";
cout << "val of CEEE::two: " << toUnderlyingType(CEEE::two) << "\n";
cout << "val of 1: " << toUnderlyingType(1) << "\n";
cout << "val of 2: " << toUnderlyingType(2) << "\n";
cout << "val of copyAllowed : " << toUnderlyingType(MoveFileFlags::copyAllowed) << "\n";
cout << "val of replaceExisting: " << toUnderlyingType(MoveFileFlags::replaceExisting) << "\n";
cout << "MoveFileFlags::replaceExisting==1: " << (MoveFileFlags::replaceExisting==1 ? "true" : "false") << "\n";
MoveFileFlags flags = MoveFileFlags::replaceExisting;
}
|