#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;
}
