Skip to content

Instantly share code, notes, and snippets.

@LusainKim
Last active July 13, 2016 07:33
Show Gist options
  • Save LusainKim/ff7ec985cb90e0d322ff0a50381441d8 to your computer and use it in GitHub Desktop.
Save LusainKim/ff7ec985cb90e0d322ff0a50381441d8 to your computer and use it in GitHub Desktop.
enum class example
#include <iostream>
namespace EnumFunc {
template<typename Enum> // Enum class의 선언형을 알려주어 인자와 대응하는 값을 반환하는 함수입니다.
inline constexpr auto GetEnumValueByType(Enum enumerator) noexcept // enum class E : int { a,b,c }; 일 때,
{ // auto data = GetEnumValueByType(E::a);
return static_cast<std::underlying_type_t<Enum>>(enumerator); // data의 형식은 int 이고, 값은 0 입니다.
}
// 다음 함수부터의 전제 조건 : 함수에서 사용 가능한 모든 열거형은
// none = 0 으로 시작하여 count 로 끝나야 한다.
template<typename Enum>
inline Enum SetRandomEnum() noexcept
{
using Ty = decltype(GetEnumValueByType(Enum::none));
Ty randomInt{ (rand() % (GetCharType(Enum::count) - 1) + 1) };
// 잠재적 버그구간
return static_cast<Enum>(randomInt);
}
template<typename Enum>
inline Enum& operator++(Enum& c)
{
auto ty = (GetEnumValueByType(c) + 1) % GetEnumValueByType(Enum::count);
c = static_cast<Enum>(ty
+ (ty == GetEnumValueByType(Enum::none) ? 1 : 0));
return c;
}
template<typename Enum>
inline Enum operator++(Enum& c, int)
{
Enum ret = c;
++c;
return ret;
}
template<typename Enum>
inline Enum operator+(Enum c, Enum o)
{
auto lv = GetEnumValueByType(c);
auto rv = GetEnumValueByType(o);
auto ty = (lv + rv) % GetEnumValueByType(Enum::count);
return static_cast<Enum>(ty
+ (ty == GetEnumValueByType(Enum::none) ? 1 : 0) );
}
};
// -----------------------------------------------------------------------------------
// 예제
// -----------------------------------------------------------------------------------
#include <string>
using namespace std;
enum class Character : char {
none
, 전사
, 마법사
, 성직자
, 궁수
, count
};
inline constexpr auto GetCharType(Character e) noexcept { return EnumFunc::GetEnumValueByType(e); }
inline ostream& operator<<(ostream& Ostr, const Character f) noexcept
{
string output;
switch (f)
{
case Character::전사: output = string("전사"); break;
case Character::마법사: output = string("마법사"); break;
case Character::성직자: output = string("성직자"); break;
case Character::궁수: output = string("궁수"); break;
}
Ostr << output;
return Ostr;
}
int main()
{
using namespace EnumFunc;
for (int i = 0; i < GetCharType(Character::count) * 2; ++i)
{
Character lunit{ EnumFunc::SetRandomEnum<Character>() };
Character runit{ EnumFunc::SetRandomEnum<Character>() };
++lunit;
runit++;
cout << lunit << "(" << GetCharType(lunit) << ")";
cout << " + ";
cout << runit << "(" << GetCharType(runit) << ")";
cout << " = ";
Character retunit = lunit + runit;
cout << retunit << "(" << GetCharType(retunit) << ")" << endl;
}
}
@LusainKim
Copy link
Author

LusainKim commented Jul 11, 2016

scoped enum 을 사용하는 예제입니다.

  1. enum의 산술연산이 가능합니다.
  2. enum → type의 형변환 가능 함수가 있습니다.
  3. type → enum은 강제 형변환으로만 가능하며, 버그의 여지가 있습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment