Skip to content

Instantly share code, notes, and snippets.

@remysalim
Created April 15, 2020 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remysalim/576955976e4ffe2e0ec64d3abe23b562 to your computer and use it in GitHub Desktop.
Save remysalim/576955976e4ffe2e0ec64d3abe23b562 to your computer and use it in GitHub Desktop.
#include <cstdint>
#include <type_traits>
#include <utility>
/// Specialize the T<true, n> base classes to deduce inheritance based on value, where n is a bit position.
/// i.e:
/// class Base : FeatureHelper<T, 5u>{};
/// ==
/// class Base : T<true, 0>, T<true, 2>{};
///
/// Example:
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
/// struct X1 {};
/// struct X2 {};
/// struct X5 {};
///
/// template<bool, std::size_t> struct Feature {};
/// template<> struct Feature<true, 0> : X1 {};
/// template<> struct Feature<true, 1> : X2 {};
/// template<> struct Feature<true, 4> : X5 {};
///
/// template<uint8_t v>
/// class Base : FeatureHelper<Feature, v> {};
///
/// int main() {
/// static_assert(std::is_base_of_v<X1, Base<19u>>);
/// static_assert(std::is_base_of_v<X2, Base<19u>>);
/// static_assert(std::is_base_of_v<X5, Base<19u>>);
/// }
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template<template<bool, std::size_t> typename T, auto v, typename = std::make_index_sequence<sizeof(v) * 8u>>
struct FeatureHelper;
template<template<bool, std::size_t> typename T, auto v, std::size_t... Is>
struct FeatureHelper<T, v, std::index_sequence<Is...>> : public T<(v & (1 << Is)) != 0u, Is>... {};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment