#include <array>
struct point_tag {};
struct triangle_tag {};
template<typename Geometry = void, typename Enable = void>
struct tag
{
typedef void type;
};
template <typename Point>
struct tag<std::array<Point, 3>,
typename std::enable_if <std::is_base_of<typename tag<Point>::type, point_tag>::value>::type>
{
typedef triangle_tag type;
};
template<typename Point>
using triangle =
typename std::enable_if
<
std::is_base_of<typename tag<Point>::type, point_tag>::value,
std::array<Point,3>
>::type;
class Point{};
template<>
struct tag<Point>
{
typedef point_tag type;
};
static_assert(std::is_same<triangle_tag, tag<std::array<Point, 3>>::type>::value, "");
static_assert(std::is_same<void, tag<std::array<int, 3>>::type>::value, "");
static_assert(std::is_same<triangle_tag, tag<triangle<Point>>::type>::value, "");
//static_assert(std::is_same<triangle_tag, tag<triangle<int>>::type>::value, ""); // Doesn't compile as triangle<int> is not valid
int main()
{
return 0;
}
I2luY2x1ZGUgPGFycmF5PgoKc3RydWN0IHBvaW50X3RhZyB7fTsKc3RydWN0IHRyaWFuZ2xlX3RhZyB7fTsKCnRlbXBsYXRlPHR5cGVuYW1lIEdlb21ldHJ5ID0gdm9pZCwgdHlwZW5hbWUgRW5hYmxlID0gdm9pZD4Kc3RydWN0IHRhZwp7CiAgICB0eXBlZGVmIHZvaWQgdHlwZTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBQb2ludD4Kc3RydWN0IHRhZzxzdGQ6OmFycmF5PFBvaW50LCAzPiwKICAgICAgICAgICB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZiA8c3RkOjppc19iYXNlX29mPHR5cGVuYW1lIHRhZzxQb2ludD46OnR5cGUsIHBvaW50X3RhZz46OnZhbHVlPjo6dHlwZT4KewogICAgdHlwZWRlZiB0cmlhbmdsZV90YWcgdHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFBvaW50Pgp1c2luZyB0cmlhbmdsZSA9CnR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmCjwKICAgIHN0ZDo6aXNfYmFzZV9vZjx0eXBlbmFtZSB0YWc8UG9pbnQ+Ojp0eXBlLCBwb2ludF90YWc+Ojp2YWx1ZSwKICAgIHN0ZDo6YXJyYXk8UG9pbnQsMz4KPjo6dHlwZTsKCmNsYXNzIFBvaW50e307Cgp0ZW1wbGF0ZTw+CnN0cnVjdCB0YWc8UG9pbnQ+CnsKICAgIHR5cGVkZWYgcG9pbnRfdGFnIHR5cGU7Cn07CgpzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTx0cmlhbmdsZV90YWcsIHRhZzxzdGQ6OmFycmF5PFBvaW50LCAzPj46OnR5cGU+Ojp2YWx1ZSwgIiIpOwpzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTx2b2lkLCB0YWc8c3RkOjphcnJheTxpbnQsIDM+Pjo6dHlwZT46OnZhbHVlLCAiIik7CnN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPHRyaWFuZ2xlX3RhZywgdGFnPHRyaWFuZ2xlPFBvaW50Pj46OnR5cGU+Ojp2YWx1ZSwgIiIpOwovL3N0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPHRyaWFuZ2xlX3RhZywgdGFnPHRyaWFuZ2xlPGludD4+Ojp0eXBlPjo6dmFsdWUsICIiKTsgLy8gRG9lc24ndCBjb21waWxlIGFzIHRyaWFuZ2xlPGludD4gaXMgbm90IHZhbGlkCgppbnQgbWFpbigpCnsKICAgIHJldHVybiAwOwp9Cg==