Skip to content

Instantly share code, notes, and snippets.

@LusainKim
Last active August 27, 2018 07:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LusainKim/001941abe826fea2bdf7efb97556da41 to your computer and use it in GitHub Desktop.
Save LusainKim/001941abe826fea2bdf7efb97556da41 to your computer and use it in GitHub Desktop.
A code that compares multiple cases to a single target.
#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