Last active
March 27, 2020 21:35
-
-
Save yaneury/3940987ad3a1f70cccd49d796b3af233 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <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