#include <iostream>
#include <type_traits>
// =====================================================================
// 1. Boost.MPL Core Components
// =====================================================================
// An MPL vector is just a type holding a list of other types.
template < typename ... Ts >
struct vector { } ;
// An MPL int_ represents an integer as a TYPE.
template < int N>
struct int_ : std:: integral_constant < int , N> { } ;
// A generic less-than predicate for types.
template < typename T1, typename T2>
struct less : std:: integral_constant < bool , ( T1:: value < T2:: value ) > { } ;
// =====================================================================
// 2. Type-Level Concatenation (Joining lists)
// =====================================================================
template < typename L1, typename L2, typename L3>
struct concat;
// Specialization to extract the types from three vectors and merge them
template < typename ... T1 , typename ... T2 , typename ... T3 >
struct concat< vector< T1...> , vector< T2...> , vector< T3...>> {
using type = vector< T1..., T2..., T3...> ;
} ;
// =====================================================================
// 3. Type-Level Partitioning (Splitting list around a pivot)
// =====================================================================
template < bool Cond, typename T, typename Less, typename GreaterEq>
struct push_impl;
// If true: push to Less vector
template < typename T, typename ... L , typename ... G >
struct push_impl< true , T, vector< L...> , vector< G...>> {
using less = vector< L..., T> ;
using greater_eq = vector< G...> ;
} ;
// If false: push to GreaterEq vector
template < typename T, typename ... L , typename ... G >
struct push_impl< false , T, vector< L...> , vector< G...>> {
using less = vector< L...> ;
using greater_eq = vector< G..., T> ;
} ;
template < typename Pivot, typename List, template < typename , typename > class Pred, typename LessList = vector<> , typename GreaterEqList = vector<>>
struct partition;
// Base Case: Empty List
template < typename Pivot, template < typename , typename > class Pred, typename LessList, typename GreaterEqList>
struct partition< Pivot, vector<> , Pred, LessList, GreaterEqList> {
using less = LessList;
using greater_eq = GreaterEqList;
} ;
// Recursive Case: Evaluate Head against Pivot, push to correct list, recurse on Tail
template < typename Pivot, typename Head, typename ... Tail , template < typename , typename > class Pred, typename LessList, typename GreaterEqList>
struct partition< Pivot, vector< Head, Tail...> , Pred, LessList, GreaterEqList> {
// 1. Check if Head < Pivot
static constexpr bool is_less = Pred< Head, Pivot> :: value ;
// 2. Route the Head into the temporary less/greater lists
using step = push_impl< is_less, Head, LessList, GreaterEqList> ;
// 3. Recurse down the Tail
using recurse = partition< Pivot, vector< Tail...> , Pred, typename step:: less , typename step:: greater_eq > ;
using less = typename recurse:: less ;
using greater_eq = typename recurse:: greater_eq ;
} ;
// =====================================================================
// 4. THE SORT ALGORITHM (Type-Level Quicksort)
// =====================================================================
template < typename List, template < typename , typename > class Pred = less>
struct sort;
// Base Case: Empty list is already sorted
template < template < typename , typename > class Pred>
struct sort< vector<> , Pred> {
using type = vector<> ;
} ;
// Recursive Quicksort
template < typename Pivot, typename ... Tail , template < typename , typename > class Pred>
struct sort< vector< Pivot, Tail...> , Pred> {
// 1. Partition the Tail around the Pivot
using parts = partition< Pivot, vector< Tail...> , Pred> ;
// 2. Sort the Less list
using sorted_less = typename sort< typename parts:: less , Pred> :: type ;
// 3. Sort the Greater list
using sorted_greater = typename sort< typename parts:: greater_eq , Pred> :: type ;
// 4. Concat: [Sorted Less] + [Pivot] + [Sorted Greater]
using type = typename concat< sorted_less, vector< Pivot> , sorted_greater> :: type ;
} ;
// =====================================================================
// PROOF IT WORKS (Strictly Compile-Time Verification)
// =====================================================================
using UnsortedData = vector< int_< 8 > , int_< 3 > , int_< 9 > , int_< 1 > , int_< 4 >> ;
// 💥 THE COMPILER SORTS THE TYPES HERE 💥
using SortedData = sort< UnsortedData> :: type ;
// We use std::is_same to prove to the compiler that SortedData is exactly
// equivalent to a manually sorted vector. If this fails, compilation stops.
static_assert( std:: is_same <
SortedData,
vector< int_< 1 > , int_< 3 > , int_< 4 > , int_< 8 > , int_< 9 >>
> :: value , "Boost.MPL Sort Failed!" ) ;
int main( ) {
std:: cout << "Type-Level Metaprogramming Sort successful!\n " ;
std:: cout << "The sorting didn't happen in 0ms... it never 'happened' at all.\n " ;
std:: cout << "The types themselves dictate the sorted order.\n " ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gMS4gQm9vc3QuTVBMIENvcmUgQ29tcG9uZW50cwovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8vIEFuIE1QTCB2ZWN0b3IgaXMganVzdCBhIHR5cGUgaG9sZGluZyBhIGxpc3Qgb2Ygb3RoZXIgdHlwZXMuCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUcz4Kc3RydWN0IHZlY3RvciB7fTsKCi8vIEFuIE1QTCBpbnRfIHJlcHJlc2VudHMgYW4gaW50ZWdlciBhcyBhIFRZUEUuCnRlbXBsYXRlIDxpbnQgTj4Kc3RydWN0IGludF8gOiBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCwgTj4ge307CgovLyBBIGdlbmVyaWMgbGVzcy10aGFuIHByZWRpY2F0ZSBmb3IgdHlwZXMuCnRlbXBsYXRlIDx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+CnN0cnVjdCBsZXNzIDogc3RkOjppbnRlZ3JhbF9jb25zdGFudDxib29sLCAoVDE6OnZhbHVlIDwgVDI6OnZhbHVlKT4ge307CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gMi4gVHlwZS1MZXZlbCBDb25jYXRlbmF0aW9uIChKb2luaW5nIGxpc3RzKQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KdGVtcGxhdGUgPHR5cGVuYW1lIEwxLCB0eXBlbmFtZSBMMiwgdHlwZW5hbWUgTDM+CnN0cnVjdCBjb25jYXQ7CgovLyBTcGVjaWFsaXphdGlvbiB0byBleHRyYWN0IHRoZSB0eXBlcyBmcm9tIHRocmVlIHZlY3RvcnMgYW5kIG1lcmdlIHRoZW0KdGVtcGxhdGUgPHR5cGVuYW1lLi4uIFQxLCB0eXBlbmFtZS4uLiBUMiwgdHlwZW5hbWUuLi4gVDM+CnN0cnVjdCBjb25jYXQ8dmVjdG9yPFQxLi4uPiwgdmVjdG9yPFQyLi4uPiwgdmVjdG9yPFQzLi4uPj4gewogICAgdXNpbmcgdHlwZSA9IHZlY3RvcjxUMS4uLiwgVDIuLi4sIFQzLi4uPjsKfTsKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAzLiBUeXBlLUxldmVsIFBhcnRpdGlvbmluZyAoU3BsaXR0aW5nIGxpc3QgYXJvdW5kIGEgcGl2b3QpCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQp0ZW1wbGF0ZSA8Ym9vbCBDb25kLCB0eXBlbmFtZSBULCB0eXBlbmFtZSBMZXNzLCB0eXBlbmFtZSBHcmVhdGVyRXE+CnN0cnVjdCBwdXNoX2ltcGw7CgovLyBJZiB0cnVlOiBwdXNoIHRvIExlc3MgdmVjdG9yCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBMLCB0eXBlbmFtZS4uLiBHPgpzdHJ1Y3QgcHVzaF9pbXBsPHRydWUsIFQsIHZlY3RvcjxMLi4uPiwgdmVjdG9yPEcuLi4+PiB7CiAgICB1c2luZyBsZXNzID0gdmVjdG9yPEwuLi4sIFQ+OwogICAgdXNpbmcgZ3JlYXRlcl9lcSA9IHZlY3RvcjxHLi4uPjsKfTsKCi8vIElmIGZhbHNlOiBwdXNoIHRvIEdyZWF0ZXJFcSB2ZWN0b3IKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEwsIHR5cGVuYW1lLi4uIEc+CnN0cnVjdCBwdXNoX2ltcGw8ZmFsc2UsIFQsIHZlY3RvcjxMLi4uPiwgdmVjdG9yPEcuLi4+PiB7CiAgICB1c2luZyBsZXNzID0gdmVjdG9yPEwuLi4+OwogICAgdXNpbmcgZ3JlYXRlcl9lcSA9IHZlY3RvcjxHLi4uLCBUPjsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBQaXZvdCwgdHlwZW5hbWUgTGlzdCwgdGVtcGxhdGU8dHlwZW5hbWUsIHR5cGVuYW1lPiBjbGFzcyBQcmVkLCB0eXBlbmFtZSBMZXNzTGlzdCA9IHZlY3Rvcjw+LCB0eXBlbmFtZSBHcmVhdGVyRXFMaXN0ID0gdmVjdG9yPD4+CnN0cnVjdCBwYXJ0aXRpb247CgovLyBCYXNlIENhc2U6IEVtcHR5IExpc3QKdGVtcGxhdGUgPHR5cGVuYW1lIFBpdm90LCB0ZW1wbGF0ZTx0eXBlbmFtZSwgdHlwZW5hbWU+IGNsYXNzIFByZWQsIHR5cGVuYW1lIExlc3NMaXN0LCB0eXBlbmFtZSBHcmVhdGVyRXFMaXN0PgpzdHJ1Y3QgcGFydGl0aW9uPFBpdm90LCB2ZWN0b3I8PiwgUHJlZCwgTGVzc0xpc3QsIEdyZWF0ZXJFcUxpc3Q+IHsKICAgIHVzaW5nIGxlc3MgPSBMZXNzTGlzdDsKICAgIHVzaW5nIGdyZWF0ZXJfZXEgPSBHcmVhdGVyRXFMaXN0Owp9OwoKLy8gUmVjdXJzaXZlIENhc2U6IEV2YWx1YXRlIEhlYWQgYWdhaW5zdCBQaXZvdCwgcHVzaCB0byBjb3JyZWN0IGxpc3QsIHJlY3Vyc2Ugb24gVGFpbAp0ZW1wbGF0ZSA8dHlwZW5hbWUgUGl2b3QsIHR5cGVuYW1lIEhlYWQsIHR5cGVuYW1lLi4uIFRhaWwsIHRlbXBsYXRlPHR5cGVuYW1lLCB0eXBlbmFtZT4gY2xhc3MgUHJlZCwgdHlwZW5hbWUgTGVzc0xpc3QsIHR5cGVuYW1lIEdyZWF0ZXJFcUxpc3Q+CnN0cnVjdCBwYXJ0aXRpb248UGl2b3QsIHZlY3RvcjxIZWFkLCBUYWlsLi4uPiwgUHJlZCwgTGVzc0xpc3QsIEdyZWF0ZXJFcUxpc3Q+IHsKICAgIC8vIDEuIENoZWNrIGlmIEhlYWQgPCBQaXZvdAogICAgc3RhdGljIGNvbnN0ZXhwciBib29sIGlzX2xlc3MgPSBQcmVkPEhlYWQsIFBpdm90Pjo6dmFsdWU7CiAgICAKICAgIC8vIDIuIFJvdXRlIHRoZSBIZWFkIGludG8gdGhlIHRlbXBvcmFyeSBsZXNzL2dyZWF0ZXIgbGlzdHMKICAgIHVzaW5nIHN0ZXAgPSBwdXNoX2ltcGw8aXNfbGVzcywgSGVhZCwgTGVzc0xpc3QsIEdyZWF0ZXJFcUxpc3Q+OwogICAgCiAgICAvLyAzLiBSZWN1cnNlIGRvd24gdGhlIFRhaWwKICAgIHVzaW5nIHJlY3Vyc2UgPSBwYXJ0aXRpb248UGl2b3QsIHZlY3RvcjxUYWlsLi4uPiwgUHJlZCwgdHlwZW5hbWUgc3RlcDo6bGVzcywgdHlwZW5hbWUgc3RlcDo6Z3JlYXRlcl9lcT47CiAgICAKICAgIHVzaW5nIGxlc3MgPSB0eXBlbmFtZSByZWN1cnNlOjpsZXNzOwogICAgdXNpbmcgZ3JlYXRlcl9lcSA9IHR5cGVuYW1lIHJlY3Vyc2U6OmdyZWF0ZXJfZXE7Cn07CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gNC4gVEhFIFNPUlQgQUxHT1JJVEhNIChUeXBlLUxldmVsIFF1aWNrc29ydCkKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CnRlbXBsYXRlIDx0eXBlbmFtZSBMaXN0LCB0ZW1wbGF0ZTx0eXBlbmFtZSwgdHlwZW5hbWU+IGNsYXNzIFByZWQgPSBsZXNzPgpzdHJ1Y3Qgc29ydDsKCi8vIEJhc2UgQ2FzZTogRW1wdHkgbGlzdCBpcyBhbHJlYWR5IHNvcnRlZAp0ZW1wbGF0ZSA8dGVtcGxhdGU8dHlwZW5hbWUsIHR5cGVuYW1lPiBjbGFzcyBQcmVkPgpzdHJ1Y3Qgc29ydDx2ZWN0b3I8PiwgUHJlZD4gewogICAgdXNpbmcgdHlwZSA9IHZlY3Rvcjw+Owp9OwoKLy8gUmVjdXJzaXZlIFF1aWNrc29ydAp0ZW1wbGF0ZSA8dHlwZW5hbWUgUGl2b3QsIHR5cGVuYW1lLi4uIFRhaWwsIHRlbXBsYXRlPHR5cGVuYW1lLCB0eXBlbmFtZT4gY2xhc3MgUHJlZD4Kc3RydWN0IHNvcnQ8dmVjdG9yPFBpdm90LCBUYWlsLi4uPiwgUHJlZD4gewogICAgLy8gMS4gUGFydGl0aW9uIHRoZSBUYWlsIGFyb3VuZCB0aGUgUGl2b3QKICAgIHVzaW5nIHBhcnRzID0gcGFydGl0aW9uPFBpdm90LCB2ZWN0b3I8VGFpbC4uLj4sIFByZWQ+OwogICAgCiAgICAvLyAyLiBTb3J0IHRoZSBMZXNzIGxpc3QKICAgIHVzaW5nIHNvcnRlZF9sZXNzID0gdHlwZW5hbWUgc29ydDx0eXBlbmFtZSBwYXJ0czo6bGVzcywgUHJlZD46OnR5cGU7CiAgICAKICAgIC8vIDMuIFNvcnQgdGhlIEdyZWF0ZXIgbGlzdAogICAgdXNpbmcgc29ydGVkX2dyZWF0ZXIgPSB0eXBlbmFtZSBzb3J0PHR5cGVuYW1lIHBhcnRzOjpncmVhdGVyX2VxLCBQcmVkPjo6dHlwZTsKICAgIAogICAgLy8gNC4gQ29uY2F0OiBbU29ydGVkIExlc3NdICsgW1Bpdm90XSArIFtTb3J0ZWQgR3JlYXRlcl0KICAgIHVzaW5nIHR5cGUgPSB0eXBlbmFtZSBjb25jYXQ8c29ydGVkX2xlc3MsIHZlY3RvcjxQaXZvdD4sIHNvcnRlZF9ncmVhdGVyPjo6dHlwZTsKfTsKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQUk9PRiBJVCBXT1JLUyAoU3RyaWN0bHkgQ29tcGlsZS1UaW1lIFZlcmlmaWNhdGlvbikKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgp1c2luZyBVbnNvcnRlZERhdGEgPSB2ZWN0b3I8aW50Xzw4PiwgaW50XzwzPiwgaW50Xzw5PiwgaW50XzwxPiwgaW50Xzw0Pj47CgovLyDwn5KlIFRIRSBDT01QSUxFUiBTT1JUUyBUSEUgVFlQRVMgSEVSRSDwn5KlCnVzaW5nIFNvcnRlZERhdGEgPSBzb3J0PFVuc29ydGVkRGF0YT46OnR5cGU7CgovLyBXZSB1c2Ugc3RkOjppc19zYW1lIHRvIHByb3ZlIHRvIHRoZSBjb21waWxlciB0aGF0IFNvcnRlZERhdGEgaXMgZXhhY3RseSAKLy8gZXF1aXZhbGVudCB0byBhIG1hbnVhbGx5IHNvcnRlZCB2ZWN0b3IuIElmIHRoaXMgZmFpbHMsIGNvbXBpbGF0aW9uIHN0b3BzLgpzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTwKICAgIFNvcnRlZERhdGEsIAogICAgdmVjdG9yPGludF88MT4sIGludF88Mz4sIGludF88ND4sIGludF88OD4sIGludF88OT4+Cj46OnZhbHVlLCAiQm9vc3QuTVBMIFNvcnQgRmFpbGVkISIpOwoKaW50IG1haW4oKSB7CiAgICBzdGQ6OmNvdXQgPDwgIlR5cGUtTGV2ZWwgTWV0YXByb2dyYW1taW5nIFNvcnQgc3VjY2Vzc2Z1bCFcbiI7CiAgICBzdGQ6OmNvdXQgPDwgIlRoZSBzb3J0aW5nIGRpZG4ndCBoYXBwZW4gaW4gMG1zLi4uIGl0IG5ldmVyICdoYXBwZW5lZCcgYXQgYWxsLlxuIjsKICAgIHN0ZDo6Y291dCA8PCAiVGhlIHR5cGVzIHRoZW1zZWx2ZXMgZGljdGF0ZSB0aGUgc29ydGVkIG9yZGVyLlxuIjsKICAgIHJldHVybiAwOwp9