Last active
August 27, 2018 07:58
-
-
Save LusainKim/001941abe826fea2bdf7efb97556da41 to your computer and use it in GitHub Desktop.
A code that compares multiple cases to a single target.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <tuple> | |
using namespace std; | |
namespace group_compare | |
{ | |
// template meta programming | |
namespace helper | |
{ | |
template <int... Is> | |
struct index {}; | |
template <int N, int... Is> | |
struct gen_seq : gen_seq<N - 1, N - 1, Is...> {}; | |
template <int... Is> | |
struct gen_seq<0, Is...> : index<Is...> {}; | |
} | |
struct tag_group_compare {}; | |
struct tag_equal_compare : tag_group_compare {}; | |
struct tag_unequal_compare : tag_group_compare {}; | |
template<class ...Ts> | |
class group | |
{ | |
template<class ...Args> | |
friend constexpr auto make_group(Args&&...); | |
template<typename rhs_t, class ...Args> | |
friend constexpr bool operator!=(rhs_t&&, const group<Args...>&); | |
template<typename rhs_t, class ...Args> | |
friend constexpr bool operator!=(rhs_t&&, group<Args...>&&); | |
template<typename rhs_t, class ...Args> | |
friend constexpr bool operator==(rhs_t&&, const group<Args...>&); | |
template<typename rhs_t, class ...Args> | |
friend constexpr bool operator==(rhs_t&&, group<Args...>&&); | |
private: | |
tuple<Ts...> groups; | |
private: | |
constexpr explicit group(Ts&&...args) | |
: groups { std::forward<Ts>(args)...} | |
{ | |
} | |
template <typename rhs_t> | |
constexpr bool compare_core(tag_equal_compare, rhs_t&&) const noexcept { return true; } | |
template <typename rhs_t, typename Ty, typename... Args> | |
constexpr bool compare_core(tag_equal_compare, rhs_t&& rhs, Ty&& ty, Args&&... args) const noexcept | |
{ | |
return (rhs == std::forward<Ty>(ty)) && compare_core(tag_equal_compare{}, std::forward<rhs_t>(rhs), std::forward<Args>(args)...); | |
} | |
template <typename rhs_t> | |
constexpr bool compare_core(tag_unequal_compare, rhs_t&&) const noexcept { return true; } | |
template <typename rhs_t, typename Ty, typename... Args> | |
constexpr bool compare_core(tag_unequal_compare, rhs_t&& rhs, Ty&& ty, Args&&... args) const noexcept | |
{ | |
return (rhs != std::forward<Ty>(ty)) && compare_core(tag_unequal_compare{}, std::forward<rhs_t>(rhs), std::forward<Args>(args)...); | |
} | |
template <typename is_equal_comp, typename rhs_t, typename... Args, int... Is> | |
constexpr bool compare(rhs_t&& rhs, const std::tuple<Args...>& tup, helper::index<Is...>) const noexcept | |
{ | |
return compare_core(is_equal_comp{}, std::forward<rhs_t>(rhs), std::get<Is>(tup)...); | |
} | |
template <typename is_equal_comp, typename rhs_t, typename... Args> | |
constexpr bool compare(rhs_t&& rhs, const std::tuple<Args...>& tup) const noexcept | |
{ | |
return compare<is_equal_comp>( | |
std::forward<rhs_t>(rhs) | |
, tup | |
, helper::gen_seq<sizeof...(Args)>{} | |
); | |
} | |
template <typename is_equal_comp, typename rhs_t> | |
constexpr bool compare(rhs_t&& rhs) const noexcept | |
{ | |
return compare<is_equal_comp>(std::forward<rhs_t>(rhs), groups); | |
} | |
}; | |
template<class ...Args> | |
constexpr auto make_group(Args&&...args) | |
{ | |
return group<Args...>(std::forward<Args>(args)...); | |
} | |
template<typename rhs_t, class ...Args> | |
constexpr bool operator!=(rhs_t&& rhs, group<Args...>&& lhs) | |
{ | |
return lhs.compare<tag_unequal_compare>(std::forward<rhs_t>(rhs)); | |
} | |
template<typename rhs_t, class ...Args> | |
constexpr bool operator!=(rhs_t&& rhs, const group<Args...>& lhs) | |
{ | |
return lhs.compare<tag_unequal_compare>(std::forward<rhs_t>(rhs)); | |
} | |
template<typename rhs_t, class ...Args> | |
constexpr bool operator==(rhs_t&& rhs, group<Args...>&& lhs) | |
{ | |
return lhs.compare<tag_equal_compare>(std::forward<rhs_t>(rhs)); | |
} | |
template<typename rhs_t, class ...Args> | |
constexpr bool operator==(rhs_t&& rhs, const group<Args...>& lhs) | |
{ | |
return lhs.compare<tag_equal_compare>(std::forward<rhs_t>(rhs)); | |
} | |
} | |
using namespace group_compare; | |
class Unit | |
{ | |
public: | |
int key; | |
bool operator!=(const Unit& unit) | |
{ | |
return key != unit.key; | |
} | |
bool operator!=(int Key) | |
{ | |
return key != Key; | |
} | |
bool operator==(const Unit& unit) | |
{ | |
return key == unit.key; | |
} | |
bool operator==(int Key) | |
{ | |
return key == Key; | |
} | |
}; | |
int main() | |
{ | |
Unit unit{ 5 }; | |
cout << boolalpha << (unit != make_group(Unit{ 2 }, 3)) << endl; | |
cout << endl; | |
cout << boolalpha << (unit != make_group(Unit{ 5 }, 3)) << endl; | |
cout << boolalpha << (unit != make_group(Unit{ 2 }, 5)) << endl; | |
cout << endl; | |
cout << boolalpha << (unit != make_group(Unit{ 5 }, 5)) << endl; | |
cout << endl << "==" << endl; | |
cout << boolalpha << (unit == make_group(Unit{ 2 }, 3)) << endl; | |
cout << endl; | |
cout << boolalpha << (unit == make_group(Unit{ 5 }, 3)) << endl; | |
cout << boolalpha << (unit == make_group(Unit{ 2 }, 5)) << endl; | |
cout << endl; | |
cout << boolalpha << (unit == make_group(Unit{ 5 }, 5)) << endl; | |
cout << endl << "==" << endl; | |
bool bDead = false, bMove = false , bJump = false, bAtt = false; | |
cout << boolalpha << (false == make_group(bDead, !bMove, bJump, bAtt)) << endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment