1 // Boost.Geometry
2 
3 // Copyright (c) 2017-2018, Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
5 
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
11 #define BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
12 
13 
14 #include <boost/geometry/core/radius.hpp>
15 #include <boost/geometry/core/tag.hpp>
16 #include <boost/geometry/core/tags.hpp>
17 
18 #include <boost/geometry/srs/projections/exception.hpp>
19 #include <boost/geometry/srs/projections/par_data.hpp>
20 #include <boost/geometry/srs/sphere.hpp>
21 #include <boost/geometry/srs/spheroid.hpp>
22 
23 #include <boost/mpl/assert.hpp>
24 #include <boost/mpl/if.hpp>
25 #include <boost/range/begin.hpp>
26 #include <boost/range/end.hpp>
27 #include <boost/range/size.hpp>
28 #include <boost/range/value_type.hpp>
29 #include <boost/tuple/tuple.hpp>
30 #include <boost/type_traits/integral_constant.hpp>
31 #include <boost/type_traits/is_convertible.hpp>
32 #include <boost/type_traits/is_same.hpp>
33 #include <boost/type_traits/is_void.hpp>
34 #include <boost/variant/variant.hpp>
35 
36 #include <string>
37 #include <vector>
38 
39 namespace boost { namespace geometry { namespace srs
40 {
41 
42 namespace detail
43 {
44 
45 template
46 <
47     typename Types,
48     typename T,
49     typename Iter = typename boost::mpl::begin<Types>::type,
50     typename End = typename boost::mpl::end<Types>::type,
51     int I = 0
52 >
53 struct find_type_index
54 {
55     typedef typename boost::mpl::deref<Iter>::type type;
56     static const int value = boost::is_same<type, T>::value
57                            ? I
58                            : find_type_index
59                                 <
60                                     Types,
61                                     T,
62                                     typename boost::mpl::next<Iter>::type,
63                                     End,
64                                     I + 1
65                                 >::value;
66 
67 };
68 
69 template
70 <
71     typename Types,
72     typename T,
73     typename End,
74     int I
75 >
76 struct find_type_index<Types, T, End, End, I>
77 {
78     static const int value = I;
79 };
80 
81 
82 template
83 <
84     typename Range,
85     typename ToValue,
86     bool IsRange = boost::has_range_iterator<Range>::value
87 >
88 struct is_convertible_range
89     : boost::is_convertible
90         <
91             typename boost::range_value<Range>::type,
92             ToValue
93         >
94 {};
95 
96 template
97 <
98     typename Range,
99     typename ToValue
100 >
101 struct is_convertible_range<Range, ToValue, false>
102     : boost::false_type
103 {};
104 
105 } // namespace detail
106 
107 
108 namespace dpar
109 {
110 
111 enum value_datum
112 {
113     datum_wgs84 = 0,
114     datum_ggrs87,
115     datum_nad83,
116     datum_nad27,
117     datum_potsdam,
118     datum_carthage,
119     datum_hermannskogel,
120     datum_ire65,
121     datum_nzgd49,
122     datum_osgb36,
123 };
124 
125 enum value_ellps
126 {
127     ellps_merit = 0,
128     ellps_sgs85,
129     ellps_grs80,
130     ellps_iau76,
131     ellps_airy,
132     ellps_apl4_9,
133     ellps_nwl9d,
134     ellps_mod_airy,
135     ellps_andrae,
136     ellps_aust_sa,
137     ellps_grs67,
138     ellps_bessel,
139     ellps_bess_nam,
140     ellps_clrk66,
141     ellps_clrk80,
142     ellps_clrk80ign,
143     ellps_cpm,
144     ellps_delmbr,
145     ellps_engelis,
146     ellps_evrst30,
147     ellps_evrst48,
148     ellps_evrst56,
149     ellps_evrst69,
150     ellps_evrstss,
151     ellps_fschr60,
152     ellps_fschr60m,
153     ellps_fschr68,
154     ellps_helmert,
155     ellps_hough,
156     ellps_intl,
157     ellps_krass,
158     ellps_kaula,
159     ellps_lerch,
160     ellps_mprts,
161     ellps_new_intl,
162     ellps_plessis,
163     ellps_seasia,
164     ellps_walbeck,
165     ellps_wgs60,
166     ellps_wgs66,
167     ellps_wgs72,
168     ellps_wgs84,
169     ellps_sphere
170 };
171 
172 enum value_mode
173 {
174     mode_plane = 0,
175     mode_di,
176     mode_dd,
177     mode_hex
178 };
179 
180 enum value_orient
181 {
182     orient_isea = 0,
183     orient_pole,
184 };
185 
186 enum value_pm
187 {
188     pm_greenwich = 0,
189     pm_lisbon,
190     pm_paris,
191     pm_bogota,
192     pm_madrid,
193     pm_rome,
194     pm_bern,
195     pm_jakarta,
196     pm_ferro,
197     pm_brussels,
198     pm_stockholm,
199     pm_athens,
200     pm_oslo
201 };
202 
203 enum value_proj
204 {
205     proj_unknown = 0,
206     proj_aea, proj_leac,
207     proj_aeqd,
208     proj_airy,
209     proj_aitoff, proj_wintri,
210     proj_august,
211     proj_apian, proj_ortel, proj_bacon,
212     proj_bipc,
213     proj_boggs,
214     proj_bonne,
215     proj_cass,
216     proj_cc,
217     proj_cea,
218     proj_chamb,
219     proj_collg,
220     proj_crast,
221     proj_denoy,
222     proj_eck1,
223     proj_eck2,
224     proj_eck3, proj_putp1, proj_wag6, proj_kav7,
225     proj_eck4,
226     proj_eck5,
227     proj_eqc,
228     proj_eqdc,
229     proj_etmerc, proj_utm,
230     proj_fahey,
231     proj_fouc_s,
232     proj_gall,
233     proj_geocent,
234     proj_geos,
235     proj_gins8,
236     proj_gn_sinu, proj_sinu, proj_eck6, proj_mbtfps,
237     proj_gnom,
238     proj_goode,
239     proj_gstmerc,
240     proj_hammer,
241     proj_hatano,
242     proj_healpix,
243     proj_rhealpix,
244     proj_igh,
245     proj_imw_p,
246     proj_isea,
247     proj_krovak,
248     proj_labrd,
249     proj_laea,
250     proj_lagrng,
251     proj_larr,
252     proj_lask,
253     proj_lonlat, proj_latlon, proj_latlong, proj_longlat,
254     proj_lcc,
255     proj_lcca,
256     proj_loxim,
257     proj_lsat,
258     proj_mbt_fps,
259     proj_mbtfpp,
260     proj_mbtfpq,
261     proj_merc,
262     proj_mill,
263     proj_mil_os, proj_lee_os, proj_gs48, proj_alsk, proj_gs50,
264     proj_moll, proj_wag4, proj_wag5,
265     proj_natearth,
266     proj_nell,
267     proj_nell_h,
268     proj_nicol,
269     proj_nsper, proj_tpers,
270     proj_nzmg,
271     proj_ob_tran,
272     proj_ocea,
273     proj_oea,
274     proj_omerc,
275     proj_ortho,
276     proj_poly,
277     proj_putp2,
278     proj_putp3, proj_putp3p,
279     proj_putp4p, proj_weren,
280     proj_putp5, proj_putp5p,
281     proj_putp6, proj_putp6p,
282     proj_qsc,
283     proj_robin,
284     proj_rouss,
285     proj_rpoly,
286     proj_euler, proj_murd1, proj_murd2, proj_murd3, proj_pconic, proj_tissot, proj_vitk1,
287     proj_somerc,
288     proj_stere, proj_ups,
289     proj_sterea,
290     proj_kav5, proj_qua_aut, proj_fouc, proj_mbt_s,
291     proj_tcc,
292     proj_tcea,
293     proj_tmerc,
294     proj_tpeqd,
295     proj_urm5,
296     proj_urmfps, proj_wag1,
297     proj_vandg,
298     proj_vandg2, proj_vandg3,
299     proj_vandg4,
300     proj_wag2,
301     proj_wag3,
302     proj_wag7,
303     proj_wink1,
304     proj_wink2
305 };
306 
307 enum value_sweep
308 {
309     sweep_x = 0, sweep_y
310 };
311 
312 enum value_units
313 {
314     units_km = 0,
315     units_m,
316     units_dm,
317     units_cm,
318     units_mm,
319     units_kmi,
320     units_in,
321     units_ft,
322     units_yd,
323     units_mi,
324     units_fath,
325     units_ch,
326     units_link,
327     units_us_in,
328     units_us_ft,
329     units_us_yd,
330     units_us_ch,
331     units_us_mi,
332     units_ind_yd,
333     units_ind_ft,
334     units_ind_ch
335 };
336 
337 enum name_f
338 {
339     a = 0,
340     b,
341     e,
342     es,
343     f,
344     h,
345     //h_0, // currently not used
346     k = 7,
347     k_0,
348     m, // also used for M
349     n,
350     //phdg_0, // currently not used
351     //plat_0, // currently not used
352     //plon_0, // currently not used
353     q = 14,
354     r, // originally R
355     rf,
356     to_meter,
357     vto_meter,
358     w, // originally W
359     x_0,
360     y_0
361 };
362 
363 enum name_r
364 {
365     alpha = 22,
366     azi,
367     gamma,
368     lat_0,
369     lat_1,
370     lat_2,
371     lat_3,
372     lat_b,
373     lat_ts, // 30
374     lon_0,
375     lon_1,
376     lon_2,
377     lon_3,
378     lon_wrap,
379     lonc,
380     o_alpha,
381     o_lat_1,
382     o_lat_2,
383     o_lat_c, // 40
384     o_lat_p,
385     o_lon_1,
386     o_lon_2,
387     o_lon_c,
388     o_lon_p,
389     r_lat_a, // originally R_lat_a
390     r_lat_g, // originally R_lat_g
391     theta,
392     tilt
393 };
394 
395 enum name_i
396 {
397     aperture = 50,
398     lsat,
399     north_square,
400     path,
401     resolution,
402     south_square,
403     zone
404 };
405 
406 enum name_be
407 {
408     czech = 57,
409     geoc,
410     guam,
411     no_cut, // 60
412     no_defs,
413     no_rot,
414     ns,
415     over,
416     r_au, // originally R_A
417     r_a, // originally R_a
418     r_g, // originally R_g
419     r_h, // originally R_h
420     r_v, // originally R_V
421     rescale, // 70
422     south
423 };
424 
425 /*enum name_catalog
426 {
427     catalog = 72 // currently not used
428 };
429 
430 enum name_date
431 {
432     date = 73 // currently not used
433 };*/
434 
435 enum name_datum
436 {
437     datum = 74
438 };
439 
440 enum name_ellps
441 {
442     ellps = 75 // id, sphere or spheroid
443 };
444 
445 /*enum name_geoidgrids
446 {
447     geoidgrids = 76 // currently not used
448 };*/
449 
450 enum name_mode
451 {
452     mode = 77
453 };
454 
455 enum name_nadgrids
456 {
457     nadgrids = 78 // arbitrary-length list of strings
458 };
459 
460 enum name_orient
461 {
462     orient = 79
463 };
464 
465 enum name_pm
466 {
467     pm = 80 // id or angle
468 };
469 
470 enum name_proj
471 {
472     o_proj = 81,
473     proj
474 };
475 
476 enum name_sweep
477 {
478     sweep = 83
479 };
480 
481 enum name_towgs84
482 {
483     towgs84 = 84 // 3 or 7 element list of numbers
484 };
485 
486 enum name_units
487 {
488     units = 85,
489     vunits
490 };
491 
492 template <typename T>
493 struct parameter
494 {
parameterboost::geometry::srs::dpar::parameter495     parameter()
496         : m_id(-1), m_value(false)
497     {}
498 
parameterboost::geometry::srs::dpar::parameter499     parameter(name_f id, T const& v)
500         : m_id(id), m_value(v)
501     {}
502 
503     // TODO various angle units
parameterboost::geometry::srs::dpar::parameter504     parameter(name_r id, T const& v)
505         : m_id(id), m_value(v)
506     {}
507 
parameterboost::geometry::srs::dpar::parameter508     parameter(name_i id, int v)
509         : m_id(id), m_value(v)
510     {}
511 
parameterboost::geometry::srs::dpar::parameter512     parameter(name_be id)
513         : m_id(id), m_value(true)
514     {}
515 
parameterboost::geometry::srs::dpar::parameter516     parameter(name_be id, bool v)
517         : m_id(id), m_value(v)
518     {}
519 
parameterboost::geometry::srs::dpar::parameter520     parameter(name_datum id, value_datum v)
521         : m_id(id), m_value(int(v))
522     {}
523 
parameterboost::geometry::srs::dpar::parameter524     parameter(value_datum v)
525         : m_id(datum), m_value(int(v))
526     {}
527 
528     // TODO: store model at this point?
parameterboost::geometry::srs::dpar::parameter529     parameter(name_ellps id, value_ellps v)
530         : m_id(id), m_value(int(v))
531     {}
532     // TODO: store model at this point?
parameterboost::geometry::srs::dpar::parameter533     parameter(value_ellps v)
534         : m_id(ellps), m_value(int(v))
535     {}
536 
537     template <typename Sphere>
parameterboost::geometry::srs::dpar::parameter538     parameter(name_ellps id, Sphere const& v,
539               typename boost::enable_if_c
540                 <
541                     boost::is_same<typename geometry::tag<Sphere>::type, srs_sphere_tag>::value
542                 >::type * = 0)
543         : m_id(id)
544         , m_value(T(get_radius<0>(v)))
545     {}
546 
547     template <typename Spheroid>
parameterboost::geometry::srs::dpar::parameter548     parameter(name_ellps id, Spheroid const& v,
549               typename boost::enable_if_c
550                 <
551                     boost::is_same<typename geometry::tag<Spheroid>::type, srs_spheroid_tag>::value
552                 >::type * = 0)
553         : m_id(id)
554         , m_value(srs::spheroid<T>(get_radius<0>(v), get_radius<2>(v)))
555     {}
556 
parameterboost::geometry::srs::dpar::parameter557     parameter(name_mode id, value_mode v)
558         : m_id(id), m_value(int(v))
559     {}
560 
parameterboost::geometry::srs::dpar::parameter561     parameter(value_mode v)
562         : m_id(mode), m_value(int(v))
563     {}
564 
565     template <typename Range>
parameterboost::geometry::srs::dpar::parameter566     parameter(name_nadgrids id, Range const& v,
567               typename boost::enable_if_c
568                 <
569                     detail::is_convertible_range<Range const, std::string>::value
570                 >::type * = 0)
571         : m_id(id)
572         , m_value(srs::detail::nadgrids(boost::begin(v), boost::end(v)))
573     {}
574 
575 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
parameterboost::geometry::srs::dpar::parameter576     parameter(name_nadgrids id, std::initializer_list<std::string> v)
577         : m_id(id)
578         , m_value(srs::detail::nadgrids(v))
579     {}
580 #endif
581 
parameterboost::geometry::srs::dpar::parameter582     parameter(name_orient id, value_orient v)
583         : m_id(id), m_value(int(v))
584     {}
585 
parameterboost::geometry::srs::dpar::parameter586     parameter(value_orient v)
587         : m_id(orient), m_value(int(v))
588     {}
589 
590     // TODO: store to_meters at this point?
parameterboost::geometry::srs::dpar::parameter591     parameter(name_pm id, value_pm v)
592         : m_id(id), m_value(int(v))
593     {}
594     // TODO: store to_meters at this point?
parameterboost::geometry::srs::dpar::parameter595     parameter(value_pm v)
596         : m_id(pm), m_value(int(v))
597     {}
598 
599     // TODO angle units
parameterboost::geometry::srs::dpar::parameter600     parameter(name_pm id, T const& v)
601         : m_id(id), m_value(v)
602     {}
603 
parameterboost::geometry::srs::dpar::parameter604     parameter(name_proj id, value_proj v)
605         : m_id(id), m_value(int(v))
606     {}
607 
parameterboost::geometry::srs::dpar::parameter608     parameter(value_proj v)
609         : m_id(proj), m_value(int(v))
610     {}
611 
parameterboost::geometry::srs::dpar::parameter612     parameter(name_sweep id, value_sweep v)
613         : m_id(id), m_value(int(v))
614     {}
615 
parameterboost::geometry::srs::dpar::parameter616     parameter(value_sweep v)
617         : m_id(sweep), m_value(int(v))
618     {}
619 
620     template <typename Range>
parameterboost::geometry::srs::dpar::parameter621     parameter(name_towgs84 id, Range const& v,
622               typename boost::enable_if_c
623                 <
624                     detail::is_convertible_range<Range const, T>::value
625                 >::type * = 0)
626         : m_id(id)
627         , m_value(srs::detail::towgs84<T>(boost::begin(v), boost::end(v)))
628     {
629         std::size_t n = boost::size(v);
630         if (n != 3 && n != 7)
631         {
632             BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
633         }
634     }
635 
636 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
parameterboost::geometry::srs::dpar::parameter637     parameter(name_towgs84 id, std::initializer_list<T> v)
638         : m_id(id)
639         , m_value(srs::detail::towgs84<T>(v))
640     {
641         std::size_t n = v.size();
642         if (n != 3 && n != 7)
643         {
644             BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
645         }
646     }
647 #endif
648 
parameterboost::geometry::srs::dpar::parameter649     parameter(name_units id, value_units v)
650         : m_id(id), m_value(int(v))
651     {}
652 
parameterboost::geometry::srs::dpar::parameter653     parameter(value_units v)
654         : m_id(units), m_value(int(v))
655     {}
656 
657 private:
658     typedef boost::variant
659         <
660             bool,
661             int,
662             T,
663             srs::spheroid<T>,
664             srs::detail::nadgrids,
665             srs::detail::towgs84<T>
666         > variant_type;
667 
668 public:
is_id_equalboost::geometry::srs::dpar::parameter669     bool is_id_equal(name_f const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter670     bool is_id_equal(name_r const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter671     bool is_id_equal(name_i const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter672     bool is_id_equal(name_be const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter673     bool is_id_equal(name_datum const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter674     bool is_id_equal(name_ellps const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter675     bool is_id_equal(name_mode const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter676     bool is_id_equal(name_nadgrids const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter677     bool is_id_equal(name_orient const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter678     bool is_id_equal(name_pm const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter679     bool is_id_equal(name_proj const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter680     bool is_id_equal(name_sweep const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter681     bool is_id_equal(name_towgs84 const& id) const { return m_id == int(id); }
is_id_equalboost::geometry::srs::dpar::parameter682     bool is_id_equal(name_units const& id) const { return m_id == int(id); }
683 
684     template <typename V>
get_valueboost::geometry::srs::dpar::parameter685     V const& get_value() const
686     {
687         return boost::get<V>(m_value);
688     }
689 
690     template <typename V>
is_value_setboost::geometry::srs::dpar::parameter691     bool is_value_set() const
692     {
693         return m_value.which() == srs::detail::find_type_index
694             <
695                 typename variant_type::types,
696                 V
697             >::value;
698     }
699 
700 private:
701     int m_id;
702     variant_type m_value;
703 };
704 
705 template <typename T = double>
706 class parameters
707 {
708     typedef std::vector<parameter<T> > container_type;
709 
710 public:
711     typedef typename container_type::value_type value_type;
712     typedef typename container_type::const_iterator const_iterator;
713     typedef typename container_type::const_reference const_reference;
714     typedef typename container_type::size_type size_type;
715 
parameters()716     BOOST_DEFAULTED_FUNCTION(parameters(), {})
717 
718 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
719     template <typename Id>
720     explicit parameters(Id id)
721     {
722         add(id);
723     }
724 
725     template <typename Id>
add(Id id)726     parameters & add(Id id)
727     {
728         m_params.push_back(parameter<T>(id));
729         return *this;
730     }
731 
732     template <typename Id>
operator ()(Id id)733     parameters & operator()(Id id)
734     {
735         return add(id);
736     }
737 
738     template <typename Id, typename V>
parameters(Id id,V const & value)739     parameters(Id id, V const& value)
740     {
741         add(id, value);
742     }
743 
744     template <typename Id, typename V>
add(Id id,V const & value)745     parameters & add(Id id, V const& value)
746     {
747         m_params.push_back(parameter<T>(id, value));
748         return *this;
749     }
750 
751     template <typename Id, typename V>
operator ()(Id id,V const & value)752     parameters & operator()(Id id, V const& value)
753     {
754         return add(id, value);
755     }
756 
757 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
758     template <typename Id, typename V>
parameters(Id id,std::initializer_list<V> value)759     parameters(Id id, std::initializer_list<V> value)
760     {
761         add(id, value);
762     }
763 
764     template <typename Id, typename V>
add(Id id,std::initializer_list<V> value)765     parameters & add(Id id, std::initializer_list<V> value)
766     {
767         m_params.push_back(parameter<T>(id, value));
768         return *this;
769     }
770 
771     template <typename Id, typename V>
operator ()(Id id,std::initializer_list<V> value)772     parameters & operator()(Id id, std::initializer_list<V> value)
773     {
774         return add(id, value);
775     }
776 #endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
777 #else // BOOST_NO_CXX11_RVALUE_REFERENCES || BOOST_NO_CXX11_RVALUE_REFERENCES
778     template <typename Id>
779     explicit parameters(Id id)
780     {
781         add(id);
782     }
783 
784     template <typename Id>
785     parameters & add(Id id)
786     {
787         m_params.emplace_back(id);
788         return *this;
789     }
790 
791     template <typename Id>
792     parameters & operator()(Id id)
793     {
794         return add(id);
795     }
796 
797     template <typename Id, typename V>
798     parameters(Id id, V && value)
799     {
800         add(id, std::forward<V>(value));
801     }
802 
803     template <typename Id, typename V>
804     parameters & add(Id id, V && value)
805     {
806         m_params.emplace_back(id, std::forward<V>(value));
807         return *this;
808     }
809 
810     template <typename Id, typename V>
811     parameters & operator()(Id id, V && value)
812     {
813         return add(id, std::forward<V>(value));
814     }
815 
816 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
817     template <typename Id, typename V>
818     parameters(Id id, std::initializer_list<V> value)
819     {
820         add(id, value);
821     }
822 
823     template <typename Id, typename V>
824     parameters & add(Id id, std::initializer_list<V> value)
825     {
826         m_params.emplace_back(id, value);
827         return *this;
828     }
829 
830     template <typename Id, typename V>
831     parameters & operator()(Id id, std::initializer_list<V> value)
832     {
833         return add(id, value);
834     }
835 #endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
836 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES || BOOST_NO_CXX11_RVALUE_REFERENCES
837 
begin() const838     const_iterator begin() const { return m_params.begin(); }
end() const839     const_iterator end() const { return m_params.end(); }
operator [](size_type i) const840     const_reference operator[](size_type i) const { return m_params[i]; }
size()841     size_type size() { return m_params.size(); }
empty()842     bool empty() { return m_params.empty(); }
843 
844 private:
845     container_type m_params;
846 };
847 
848 
849 } // namespace dpar
850 
851 
852 }}} // namespace boost::geometry::srs
853 
854 
855 #endif // BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
856