#include <iostream>
#include <boost/geometry/geometry.hpp>
struct my_point
{
    my_point(double an_x = 0, double an_y = 0)
        : x(an_x)
        , y(an_y)
    {}
    double x, y;
};
struct my_ring : std::deque<my_point>
{};
struct my_polygon
{
    
    my_ring boundary;
    
    boost::array<my_ring, 2> holes;
    
    std::string name;
    my_polygon(std::string const& n = "") : name(n) {}
};
namespace boost { namespace geometry { namespace traits
{
template<> struct tag<my_polygon> { typedef polygon_tag type; };
template<> struct ring_const_type<my_polygon> { typedef my_ring const& type; };
template<> struct ring_mutable_type<my_polygon> { typedef my_ring& type; };
template<> struct interior_const_type<my_polygon>
{
    typedef boost::array<my_ring, 2> const& type;
};
template<> struct interior_mutable_type<my_polygon>
{
    typedef boost::array<my_ring, 2>& type;
};
{
    static my_ring& get(my_polygon& p)
    {
        return p.boundary;
    }
    static my_ring const& get(my_polygon const& p)
    {
        return p.boundary;
    }
};
{
    typedef boost::array<my_ring, 2> holes_type;
    static holes_type& get(my_polygon& p)
    {
        return p.holes;
    }
    static holes_type const& get(my_polygon const& p)
    {
        return p.holes;
    }
};
}}} 
int main()
{
    my_polygon p1("my polygon");
    
    p1.boundary.push_back(my_point(2, 0));
    p1.boundary.push_back(my_point(1, 5));
    p1.boundary.push_back(my_point(7, 6));
    p1.boundary.push_back(my_point(2, 0));
    
    p1.holes[0].push_back(my_point(2, 1));
    p1.holes[0].push_back(my_point(2.4, 2));
    p1.holes[0].push_back(my_point(1.9, 2));
    p1.holes[0].push_back(my_point(2, 1));
    
    p1.holes[1].push_back(my_point(3, 3));
    p1.holes[1].push_back(my_point(4, 3));
    p1.holes[1].push_back(my_point(4, 4));
    p1.holes[1].push_back(my_point(3, 4));
    p1.holes[1].push_back(my_point(3, 3));
    std::cout << "Representation of " << p1.name << ": "
        << boost::geometry::dsv(p1) << std::endl;
    std::cout << "Area of " << p1.name << ": "
    std::cout << "Perimeter of " << p1.name << ": "
    std::cout << "Centroid of " << p1.name << ": "
        << boost::geometry::dsv(boost::geometry::return_centroid<my_point>(p1)) << std::endl;
    return 0;
}