#include <iostream>
#include <typeinfo>
using namespace std;
/// Helper class to wrap incomplete types and avoid instantiation of T
template<class T> struct Wrapper {};
namespace CTList {
/// The front of compile-time lists
struct Nil {};
} //namespace
/// Compile-time list helper
template< typename ListId, typename Item >
Item NextInListHelper( ::Wrapper<ListId>, ::Wrapper<Item> );
#define Back(ListId) \
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
decltype( NextInListHelper( ::Wrapper<ListId>(), ::Wrapper<\
CTList::Nil \
>())) \
>())) \
>())) \
>())) \
>())) \
>())) \
>())) \
>())) \
>())) \
>()))
/// Add a new element (type) to the list
#define PushBack( ListId, item) \
item NextInListHelper( ::Wrapper< ListId >, ::Wrapper< Back(ListId) > )
/// The next element in the ('ListId') list after 'item'
#define Next(ListId, item) decltype(NextInListHelper(::Wrapper<ListId>(), ::Wrapper<item>() ))
struct A {};
namespace NS1 {
struct B {};
struct C {};
struct D {};
// building up the compile-time list
struct Head;
PushBack(Head, A);
PushBack(Head, B);
}
PushBack(NS1::Head, NS1::C);
namespace NS1 {
PushBack(Head, D);
}
namespace NS2 {
// iterate through the list
template <class ListId, class Item>
void print(Wrapper<Item>, Wrapper<Item>) {}
template <class ListId, class PrevItem, class Item>
void print(Wrapper<PrevItem>, Wrapper<Item>)
{
cout << typeid(Item).name() << endl;
print<ListId>(Wrapper<Item>(), Wrapper< Next(ListId, Item) >());
}
}
#include <vector>
#include <string>
namespace CTList {
/// Helper for iterating through compile-time lists
template<class ListId, class PrevItem, class Item>
struct Iterator {};
/// Workaround for gcc's decltype():: bug
template<class Iterator> struct IterTraits{};
template<class ListId, class PrevItem, class Item>
struct IterTraits<Iterator<ListId, PrevItem, Item>>
{
typedef ListId id;
typedef Item item;
typedef PrevItem prev;
};
}
/// Iterator to the first element
#define Begin(ListId) CTList::Iterator<ListId, CTList::Nil, Next(ListId, CTList::Nil)>()
/// Iterator to the next element after iterator @c it
#define IteratorInc(it) \
CTList::Iterator< \
typename CTList::IterTraits<decltype(it)>::id, \
typename CTList::IterTraits<decltype(it)>::item, \
Next( \
typename CTList::IterTraits<decltype(it)>::id, \
typename CTList::IterTraits<decltype(it)>::item \
) \
>()
namespace NS3 {
// iterating through the list with an 'iterator'
template <class UserData, class ListId, class Item>
void process(UserData&, CTList::Iterator<ListId, Item, Item> ) {}
template <class UserData, class ListId, class PrevItem, class Item>
void process(UserData& u, CTList::Iterator<ListId, PrevItem, Item> it)
{
u.push_back(typeid(Item).name());
process(u, IteratorInc(it));
}
}
int main()
{
NS2::print<NS1::Head>(::Wrapper<CTList::Nil>(), ::Wrapper<Next(NS1::Head, CTList::Nil)>() );
vector<string> a, b = { typeid(A).name(), typeid(NS1::B).name() , typeid(NS1::C).name(), typeid(NS1::D).name() };
NS3::process(a, Begin(NS1::Head));
if (a == b) cout << "Passed!\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCi8vLyBIZWxwZXIgY2xhc3MgdG8gd3JhcCBpbmNvbXBsZXRlIHR5cGVzIGFuZCBhdm9pZCBpbnN0YW50aWF0aW9uIG9mIFQKdGVtcGxhdGU8Y2xhc3MgVD4gc3RydWN0IFdyYXBwZXIge307CgoKbmFtZXNwYWNlIENUTGlzdCB7CgogICAgLy8vIFRoZSBmcm9udCBvZiBjb21waWxlLXRpbWUgbGlzdHMKICAgIHN0cnVjdCBOaWwge307Cgp9IC8vbmFtZXNwYWNlCgoKLy8vIENvbXBpbGUtdGltZSBsaXN0IGhlbHBlcgp0ZW1wbGF0ZTwgdHlwZW5hbWUgTGlzdElkLCB0eXBlbmFtZSBJdGVtID4KSXRlbSBOZXh0SW5MaXN0SGVscGVyKCA6OldyYXBwZXI8TGlzdElkPiwgOjpXcmFwcGVyPEl0ZW0+ICk7CgojZGVmaW5lIEJhY2soTGlzdElkKSBcCiAgICBkZWNsdHlwZSggTmV4dEluTGlzdEhlbHBlciggOjpXcmFwcGVyPExpc3RJZD4oKSwgOjpXcmFwcGVyPFwKICAgIGRlY2x0eXBlKCBOZXh0SW5MaXN0SGVscGVyKCA6OldyYXBwZXI8TGlzdElkPigpLCA6OldyYXBwZXI8XAogICAgZGVjbHR5cGUoIE5leHRJbkxpc3RIZWxwZXIoIDo6V3JhcHBlcjxMaXN0SWQ+KCksIDo6V3JhcHBlcjxcCiAgICBkZWNsdHlwZSggTmV4dEluTGlzdEhlbHBlciggOjpXcmFwcGVyPExpc3RJZD4oKSwgOjpXcmFwcGVyPFwKICAgIGRlY2x0eXBlKCBOZXh0SW5MaXN0SGVscGVyKCA6OldyYXBwZXI8TGlzdElkPigpLCA6OldyYXBwZXI8XAogICAgZGVjbHR5cGUoIE5leHRJbkxpc3RIZWxwZXIoIDo6V3JhcHBlcjxMaXN0SWQ+KCksIDo6V3JhcHBlcjxcCiAgICBkZWNsdHlwZSggTmV4dEluTGlzdEhlbHBlciggOjpXcmFwcGVyPExpc3RJZD4oKSwgOjpXcmFwcGVyPFwKICAgIGRlY2x0eXBlKCBOZXh0SW5MaXN0SGVscGVyKCA6OldyYXBwZXI8TGlzdElkPigpLCA6OldyYXBwZXI8XAogICAgZGVjbHR5cGUoIE5leHRJbkxpc3RIZWxwZXIoIDo6V3JhcHBlcjxMaXN0SWQ+KCksIDo6V3JhcHBlcjxcCiAgICBkZWNsdHlwZSggTmV4dEluTGlzdEhlbHBlciggOjpXcmFwcGVyPExpc3RJZD4oKSwgOjpXcmFwcGVyPFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDVExpc3Q6Ok5pbCBcCiAgICAgPigpKSkgXAogICAgID4oKSkpIFwKICAgICA+KCkpKSBcCiAgICAgPigpKSkgXAogICAgID4oKSkpIFwKICAgICA+KCkpKSBcCiAgICAgPigpKSkgXAogICAgID4oKSkpIFwKICAgICA+KCkpKSBcCiAgICAgPigpKSkKCgoKLy8vIEFkZCBhIG5ldyBlbGVtZW50ICh0eXBlKSB0byB0aGUgbGlzdAojZGVmaW5lIFB1c2hCYWNrKCBMaXN0SWQsIGl0ZW0pIFwKICAgIGl0ZW0gTmV4dEluTGlzdEhlbHBlciggOjpXcmFwcGVyPCBMaXN0SWQgPiwgOjpXcmFwcGVyPCBCYWNrKExpc3RJZCkgPiApCgovLy8gVGhlIG5leHQgZWxlbWVudCBpbiB0aGUgKCdMaXN0SWQnKSBsaXN0IGFmdGVyICdpdGVtJwojZGVmaW5lIE5leHQoTGlzdElkLCBpdGVtKSBkZWNsdHlwZShOZXh0SW5MaXN0SGVscGVyKDo6V3JhcHBlcjxMaXN0SWQ+KCksIDo6V3JhcHBlcjxpdGVtPigpICkpCgoKCgpzdHJ1Y3QgQSB7fTsKCgpuYW1lc3BhY2UgTlMxIHsKICAgIHN0cnVjdCBCIHt9OwogICAgc3RydWN0IEMge307CiAgICBzdHJ1Y3QgRCB7fTsKCiAgICAvLyBidWlsZGluZyB1cCB0aGUgY29tcGlsZS10aW1lIGxpc3QKICAgIHN0cnVjdCBIZWFkOwoKICAgIFB1c2hCYWNrKEhlYWQsIEEpOwogICAgUHVzaEJhY2soSGVhZCwgQik7Cgp9CgpQdXNoQmFjayhOUzE6OkhlYWQsIE5TMTo6Qyk7CgpuYW1lc3BhY2UgTlMxIHsKICAgIFB1c2hCYWNrKEhlYWQsIEQpOwp9CgoKCm5hbWVzcGFjZSBOUzIgewoKICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCB0aGUgbGlzdAogICAgdGVtcGxhdGUgPGNsYXNzIExpc3RJZCwgY2xhc3MgSXRlbT4KICAgIHZvaWQgcHJpbnQoV3JhcHBlcjxJdGVtPiwgV3JhcHBlcjxJdGVtPikge30KCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgTGlzdElkLCBjbGFzcyBQcmV2SXRlbSwgY2xhc3MgSXRlbT4KICAgIHZvaWQgcHJpbnQoV3JhcHBlcjxQcmV2SXRlbT4sIFdyYXBwZXI8SXRlbT4pCiAgICB7CiAgICAgICAgY291dCA8PCB0eXBlaWQoSXRlbSkubmFtZSgpIDw8IGVuZGw7CiAgICAgICAgcHJpbnQ8TGlzdElkPihXcmFwcGVyPEl0ZW0+KCksIFdyYXBwZXI8IE5leHQoTGlzdElkLCBJdGVtKSA+KCkpOwogICAgfQoKfQoKCiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxzdHJpbmc+CgpuYW1lc3BhY2UgQ1RMaXN0IHsKCgogICAgLy8vIEhlbHBlciBmb3IgaXRlcmF0aW5nIHRocm91Z2ggY29tcGlsZS10aW1lIGxpc3RzCiAgICB0ZW1wbGF0ZTxjbGFzcyBMaXN0SWQsIGNsYXNzIFByZXZJdGVtLCBjbGFzcyBJdGVtPgogICAgc3RydWN0IEl0ZXJhdG9yIHt9OwoKICAgIC8vLyBXb3JrYXJvdW5kIGZvciBnY2MncyBkZWNsdHlwZSgpOjogYnVnCiAgICB0ZW1wbGF0ZTxjbGFzcyBJdGVyYXRvcj4gc3RydWN0IEl0ZXJUcmFpdHN7fTsKICAgIHRlbXBsYXRlPGNsYXNzIExpc3RJZCwgY2xhc3MgUHJldkl0ZW0sIGNsYXNzIEl0ZW0+CiAgICBzdHJ1Y3QgSXRlclRyYWl0czxJdGVyYXRvcjxMaXN0SWQsIFByZXZJdGVtLCBJdGVtPj4KICAgIHsKICAgICAgICB0eXBlZGVmIExpc3RJZCBpZDsKICAgICAgICB0eXBlZGVmIEl0ZW0gaXRlbTsKICAgICAgICB0eXBlZGVmIFByZXZJdGVtIHByZXY7CgogICAgfTsKCn0KCgovLy8gSXRlcmF0b3IgdG8gdGhlIGZpcnN0IGVsZW1lbnQKI2RlZmluZSBCZWdpbihMaXN0SWQpIENUTGlzdDo6SXRlcmF0b3I8TGlzdElkLCBDVExpc3Q6Ok5pbCwgTmV4dChMaXN0SWQsIENUTGlzdDo6TmlsKT4oKQoKLy8vIEl0ZXJhdG9yIHRvIHRoZSBuZXh0IGVsZW1lbnQgYWZ0ZXIgaXRlcmF0b3IgQGMgaXQKI2RlZmluZSBJdGVyYXRvckluYyhpdCkgIFwKICAgIENUTGlzdDo6SXRlcmF0b3I8IFwKICAgICAgICB0eXBlbmFtZSBDVExpc3Q6Okl0ZXJUcmFpdHM8ZGVjbHR5cGUoaXQpPjo6aWQsIFwKICAgICAgICB0eXBlbmFtZSBDVExpc3Q6Okl0ZXJUcmFpdHM8ZGVjbHR5cGUoaXQpPjo6aXRlbSwgXAogICAgICAgIE5leHQoIFwKICAgICAgICAgICAgdHlwZW5hbWUgQ1RMaXN0OjpJdGVyVHJhaXRzPGRlY2x0eXBlKGl0KT46OmlkLCAgXAogICAgICAgICAgICB0eXBlbmFtZSBDVExpc3Q6Okl0ZXJUcmFpdHM8ZGVjbHR5cGUoaXQpPjo6aXRlbSBcCiAgICAgICAgKSBcCiAgICA+KCkKCm5hbWVzcGFjZSBOUzMgewoKICAgIC8vIGl0ZXJhdGluZyB0aHJvdWdoIHRoZSBsaXN0IHdpdGggYW4gJ2l0ZXJhdG9yJwogICAgdGVtcGxhdGUgPGNsYXNzIFVzZXJEYXRhLCBjbGFzcyBMaXN0SWQsIGNsYXNzIEl0ZW0+CiAgICB2b2lkIHByb2Nlc3MoVXNlckRhdGEmLCBDVExpc3Q6Okl0ZXJhdG9yPExpc3RJZCwgSXRlbSwgSXRlbT4gKSB7fQoKICAgIHRlbXBsYXRlIDxjbGFzcyBVc2VyRGF0YSwgY2xhc3MgTGlzdElkLCBjbGFzcyBQcmV2SXRlbSwgY2xhc3MgSXRlbT4KICAgIHZvaWQgcHJvY2VzcyhVc2VyRGF0YSYgdSwgQ1RMaXN0OjpJdGVyYXRvcjxMaXN0SWQsIFByZXZJdGVtLCBJdGVtPiBpdCkKICAgIHsKICAgICAgICB1LnB1c2hfYmFjayh0eXBlaWQoSXRlbSkubmFtZSgpKTsKICAgICAgICBwcm9jZXNzKHUsIEl0ZXJhdG9ySW5jKGl0KSk7CiAgICB9Cgp9CgppbnQgbWFpbigpCnsKICAgIE5TMjo6cHJpbnQ8TlMxOjpIZWFkPig6OldyYXBwZXI8Q1RMaXN0OjpOaWw+KCksIDo6V3JhcHBlcjxOZXh0KE5TMTo6SGVhZCwgQ1RMaXN0OjpOaWwpPigpICk7CgogICAgdmVjdG9yPHN0cmluZz4gYSwgYiA9IHsgdHlwZWlkKEEpLm5hbWUoKSwgdHlwZWlkKE5TMTo6QikubmFtZSgpICwgdHlwZWlkKE5TMTo6QykubmFtZSgpLCB0eXBlaWQoTlMxOjpEKS5uYW1lKCkgfTsKICAgIE5TMzo6cHJvY2VzcyhhLCBCZWdpbihOUzE6OkhlYWQpKTsKICAgIGlmIChhID09IGIpIGNvdXQgPDwgIlBhc3NlZCFcbiI7CiAgICByZXR1cm4gMDsKfQoKCgoKCgoKCgo=