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