static inline void process_polygon(Polygon const& polygon,
            double* xp, double* yp, int* parts,
            int& offset, int& ring)
    {
        parts[ring++] = offset;
        offset = range_to_part(geometry::exterior_ring(polygon), xp, yp, offset);

        typename interior_return_type<Polygon const>::type rings
                    = interior_rings(polygon);
        for (BOOST_AUTO_TPL(it, boost::begin(rings)); it != boost::end(rings); ++it)
        {
            parts[ring++] = offset;
            offset = range_to_part(*it, xp, yp, offset);
        }
    }
    static inline SHPObject* apply(MultiPoint const& multi)
    {
        int const n = boost::size(multi);
        boost::scoped_array<double> x(new double[n]);
        boost::scoped_array<double> y(new double[n]);

        range_to_part(multi, x.get(), y.get());

        int const parts = 0;
        return ::SHPCreateObject(SHPT_MULTIPOINT, -1, 1, &parts, NULL,
                                    n, x.get(), y.get(), NULL, NULL);
    }
    static inline SHPObject* apply(Range const& range)
    {
        int const n = boost::size(range);

        boost::scoped_array<double> x(new double[n]);
        boost::scoped_array<double> y(new double[n]);

        range_to_part(range, x.get(), y.get());

        int const parts = 0;

        return ::SHPCreateObject(ShapeType, -1, 1, &parts, NULL,
                                    n, x.get(), y.get(), NULL, NULL);
    }
    static inline SHPObject* apply(MultiLinestring const& multi)
    {
        int const n = geometry::num_points(multi);
        int const part_count = boost::size(multi);

        boost::scoped_array<double> x(new double[n]);
        boost::scoped_array<double> y(new double[n]);
        boost::scoped_array<int> parts(new int[part_count]);

        int ring = 0;
        int offset = 0;

        for (typename boost::range_iterator<MultiLinestring const>::type
                    it = boost::begin(multi);
            it != boost::end(multi);
            ++it)
        {
            parts[ring++] = offset;
            offset = range_to_part(*it, x.get(), y.get(), offset);
        }

        return ::SHPCreateObject(SHPT_ARC, -1, part_count, parts.get(), NULL,
                                    n, x.get(), y.get(), NULL, NULL);
    }