Skip to content

Instantly share code, notes, and snippets.

@yaneury
Last active March 27, 2020 21:35
Show Gist options
  • Select an option

  • Save yaneury/3940987ad3a1f70cccd49d796b3af233 to your computer and use it in GitHub Desktop.

Select an option

Save yaneury/3940987ad3a1f70cccd49d796b3af233 to your computer and use it in GitHub Desktop.
#include <type_traits>
#include <iostream>
template <typename Id>
struct BoolTemplateType
{
using TypeId = Id;
};
template <typename T, typename... Args>
struct _IsPresent {
};
template <typename T0, typename T1, typename... Args>
struct _IsPresent<T0, T1, Args...> : std::integral_constant<bool, std::is_same<T0, T1>::value || _IsPresent<T1, Args...>::value>
{
};
template <typename T>
struct _IsPresent<T> : std::false_type
{
};
template <typename Id, typename T, T value>
struct IntegralTemplateType : std::integral_constant<T, value>
{
using TypeId = Id;
};
template <typename D, typename... Args>
struct _GetValue;
template <typename D, typename T2, typename... Args>
struct _GetValue<D, T2, Args...>
{
template <typename D2, typename T22, typename Enable = void>
struct impl
: std::integral_constant<decltype(D::value), _GetValue<D, Args...>::value>
{
};
template <typename D2, typename T22>
struct impl<D2, T22, std::enable_if_t<std::is_same<typename D2::type_id, typename T22::type_id>::value>>
: std::integral_constant<decltype(D::value), T22::value>
{
};
static constexpr const auto value = impl<D, T2>::value;
};
template <typename D>
struct _GetValue<D> : std::integral_constant<decltype(D::value), D::value>
{
};
enum class By
{
Word = 0,
DoubleWord = 1,
BestFit = 10,
NextFit = 11,
FirstFit = 12
};
enum class Type
{
Implicit,
Explicit
};
enum class After
{
Free,
Exhaustion
};
struct _FreelistId;
template <Type type>
struct Freelist : IntegralTemplateType<_FreelistId, Type, type>
{
};
struct _PlacementId;
template <By by>
struct Place : IntegralTemplateType<_PlacementId, By, by>
{
};
struct _CoalesceId;
template <After after>
struct Coalesce : IntegralTemplateType<_CoalesceId, After, after>
{
};
struct _AlignmentId;
template <By by>
struct Align : IntegralTemplateType<_AlignmentId, By, by>
{
};
struct _UseFooterId;
struct UseFooter : BoolTemplateType<_UseFooterId>
{
};
struct _MultiThreadedId;
struct MultiThreaded : BoolTemplateType<_MultiThreadedId>
{
};
template <typename... Args>
struct Allocator
{
static constexpr Type _FreelistType = _GetValue<Freelist<Type::Explicit>, Args...>::value;
static constexpr By _PlaceBy = _GetValue<Place<By::BestFit>, Args...>::value;
static constexpr After _CoalesceAfter = _GetValue<Coalesce<After::Free>, Args...>::value;
static constexpr By _AlignBy = _GetValue<Align<By::Word>, Args...>::value;
static constexpr bool _UseFooter = _IsPresent<UseFooter, Args...>::value;
static constexpr bool _MultiThreaded = _IsPresent<MultiThreaded, Args...>::value;
};
// UseFooter should output 1 (true) below. However, it only does so when it's the 1st arg passed as the template type.
int main()
{
/*
UseFooter as first argument
using AllocType = Allocator<
UseFooter,
Freelist<Type::Implicit>,
Place<By::BestFit>,
Coalesce<After::Free>,
Align<By::Word>
>;
*/
using AllocType = Allocator<
Freelist<Type::Implicit>,
Place<By::BestFit>,
Coalesce<After::Free>,
Align<By::Word>,
UseFooter
>;
std::cout
<< "Freelist Type: " << static_cast<int>(AllocType::_FreelistType) << std::endl
<< "PlaceBy: " << static_cast<int>(AllocType::_PlaceBy) << std::endl
<< "Coalesce: " << static_cast<int>(AllocType::_CoalesceAfter) << std::endl
<< "AlignBy: " << static_cast<int>(AllocType::_AlignBy) << std::endl
<< "UseFooter: " << static_cast<bool>(AllocType::_UseFooter) << std::endl
<< "MultiThreaded: " << static_cast<bool>(AllocType::_MultiThreaded) << std::endl;
std::cout << "IsSame: " << std::is_same<UseFooter, UseFooter>::value << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment