1 /******************************************************************************
2 *
3 * Project: PROJ
4 * Purpose: ISO19111:2019 implementation
5 * Author: Even Rouault <even dot rouault at spatialys dot com>
6 *
7 ******************************************************************************
8 * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #ifndef UTIL_HH_INCLUDED
30 #define UTIL_HH_INCLUDED
31
32 #if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
33 #error Must have C++11 or newer.
34 #endif
35
36 #include <exception>
37 #include <map>
38 #include <memory>
39 #include <string>
40 #include <vector>
41
42 #ifndef NS_PROJ
43 /** osgeo namespace */
44 namespace osgeo {
45 /** osgeo.proj namespace */
46 namespace proj {}
47 } // namespace osgeo
48 #endif
49
50 //! @cond Doxygen_Suppress
51
52 #ifndef PROJ_DLL
53 #ifdef PROJ_MSVC_DLL_EXPORT
54 #define PROJ_DLL __declspec(dllexport)
55 #elif defined(PROJ_MSVC_DLL_IMPORT)
56 #define PROJ_DLL __declspec(dllimport)
57 #elif defined(__GNUC__)
58 #define PROJ_DLL __attribute__((visibility("default")))
59 #else
60 #define PROJ_DLL
61 #endif
62 #endif
63
64 #ifndef PROJ_MSVC_DLL
65
66 #ifdef PROJ_MSVC_DLL_EXPORT
67 #define PROJ_MSVC_DLL PROJ_DLL
68 #define PROJ_GCC_DLL
69 #define PROJ_INTERNAL
70 #elif defined(PROJ_MSVC_DLL_IMPORT)
71 #define PROJ_MSVC_DLL PROJ_DLL
72 #define PROJ_GCC_DLL
73 #define PROJ_INTERNAL
74 #elif defined(__GNUC__)
75 #define PROJ_MSVC_DLL
76 #define PROJ_GCC_DLL PROJ_DLL
77 #if !defined(__MINGW32__)
78 #define PROJ_INTERNAL __attribute__((visibility("hidden")))
79 #else
80 #define PROJ_INTERNAL
81 #endif
82 #else
83 #define PROJ_MSVC_DLL
84 #define PROJ_GCC_DLL
85 #define PROJ_INTERNAL
86 #endif
87
88 #define PROJ_FOR_TEST PROJ_DLL
89
90 #endif
91
92 #include "nn.hpp"
93
94 /* To allow customizing the base namespace of PROJ */
95 #ifdef PROJ_INTERNAL_CPP_NAMESPACE
96 #define NS_PROJ osgeo::internalproj
97 #define NS_PROJ_START \
98 namespace osgeo { \
99 namespace internalproj {
100 #define NS_PROJ_END \
101 } \
102 }
103 #else
104 #ifndef NS_PROJ
105 #define NS_PROJ osgeo::proj
106 #define NS_PROJ_START \
107 namespace osgeo { \
108 namespace proj {
109 #define NS_PROJ_END \
110 } \
111 }
112 #endif
113 #endif
114
115 // Private-implementation (Pimpl) pattern
116 #define PROJ_OPAQUE_PRIVATE_DATA \
117 private: \
118 struct PROJ_INTERNAL Private; \
119 std::unique_ptr<Private> d; \
120 \
121 protected: \
122 PROJ_INTERNAL Private *getPrivate() noexcept { return d.get(); } \
123 PROJ_INTERNAL const Private *getPrivate() const noexcept { \
124 return d.get(); \
125 } \
126 \
127 private:
128
129 // To include in the protected/private section of a class definition,
130 // to be able to call make_shared on a protected/private constructor
131 #define INLINED_MAKE_SHARED \
132 template <typename T, typename... Args> \
133 static std::shared_ptr<T> make_shared(Args &&... args) { \
134 return std::shared_ptr<T>(new T(std::forward<Args>(args)...)); \
135 } \
136 template <typename T, typename... Args> \
137 static util::nn_shared_ptr<T> nn_make_shared(Args &&... args) { \
138 return util::nn_shared_ptr<T>( \
139 util::i_promise_i_checked_for_null, \
140 std::shared_ptr<T>(new T(std::forward<Args>(args)...))); \
141 }
142
143 // To include in the protected/private section of a class definition,
144 // to be able to call make_unique on a protected/private constructor
145 #define INLINED_MAKE_UNIQUE \
146 template <typename T, typename... Args> \
147 static std::unique_ptr<T> make_unique(Args &&... args) { \
148 return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); \
149 }
150
151 #ifdef DOXYGEN_ENABLED
152 #define PROJ_FRIEND(mytype)
153 #define PROJ_FRIEND_OPTIONAL(mytype)
154 #else
155 #define PROJ_FRIEND(mytype) friend class mytype
156 #define PROJ_FRIEND_OPTIONAL(mytype) friend class util::optional<mytype>
157 #endif
158
159 #ifndef PROJ_PRIVATE
160 #define PROJ_PRIVATE public
161 #endif
162
163 #if defined(__GNUC__)
164 #define PROJ_NO_INLINE __attribute__((noinline))
165 #define PROJ_NO_RETURN __attribute__((noreturn))
166 // Applies to a function that has no side effect.
167 #define PROJ_PURE_DECL const noexcept __attribute__((pure))
168 #else
169 #define PROJ_NO_RETURN
170 #define PROJ_NO_INLINE
171 #define PROJ_PURE_DECL const noexcept
172 #endif
173 #define PROJ_PURE_DEFN const noexcept
174
175 //! @endcond
176
177 NS_PROJ_START
178
179 //! @cond Doxygen_Suppress
180 namespace io {
181 class DatabaseContext;
182 using DatabaseContextPtr = std::shared_ptr<DatabaseContext>;
183 }
184 //! @endcond
185
186 /** osgeo.proj.util namespace.
187 *
188 * \brief A set of base types from ISO 19103, \ref GeoAPI and other PROJ
189 * specific classes.
190 */
191 namespace util {
192
193 //! @cond Doxygen_Suppress
194 // Import a few classes from nn.hpp to expose them under our ::util namespace
195 // for conveniency.
196 using ::dropbox::oxygen::i_promise_i_checked_for_null;
197 using ::dropbox::oxygen::nn;
198 using ::dropbox::oxygen::nn_dynamic_pointer_cast;
199 using ::dropbox::oxygen::nn_make_shared;
200
201 // For return statements, to convert from derived type to base type
202 using ::dropbox::oxygen::nn_static_pointer_cast;
203
204 template <typename T> using nn_shared_ptr = nn<std::shared_ptr<T>>;
205
206 #define NN_NO_CHECK(p) \
207 ::dropbox::oxygen::nn<typename std::remove_const< \
208 typename std::remove_reference<decltype(p)>::type>::type>( \
209 dropbox::oxygen::i_promise_i_checked_for_null, (p))
210
211 //! @endcond
212
213 // To avoid formatting differences between clang-format 3.8 and 7
214 #define PROJ_NOEXCEPT noexcept
215
216 //! @cond Doxygen_Suppress
217 // isOfExactType<MyType>(*p) checks that the type of *p is exactly MyType
218 template <typename TemplateT, typename ObjectT>
isOfExactType(const ObjectT & o)219 inline bool isOfExactType(const ObjectT &o) {
220 return typeid(TemplateT).hash_code() == typeid(o).hash_code();
221 }
222 //! @endcond
223
224 /** \brief Loose transposition of [std::optional]
225 * (https://en.cppreference.com/w/cpp/utility/optional) available from C++17. */
226 template <class T> class optional {
227 public:
228 //! @cond Doxygen_Suppress
optional()229 inline optional() : hasVal_(false) {}
optional(const T & val)230 inline explicit optional(const T &val) : hasVal_(true), val_(val) {}
optional(T && val)231 inline explicit optional(T &&val)
232 : hasVal_(true), val_(std::forward<T>(val)) {}
233
234 inline optional(const optional &) = default;
optional(optional && other)235 inline optional(optional &&other) PROJ_NOEXCEPT
236 : hasVal_(other.hasVal_),
237 // cppcheck-suppress functionStatic
238 val_(std::forward<T>(other.val_)) {
239 other.hasVal_ = false;
240 }
241
operator =(const T & val)242 inline optional &operator=(const T &val) {
243 hasVal_ = true;
244 val_ = val;
245 return *this;
246 }
operator =(T && val)247 inline optional &operator=(T &&val) noexcept {
248 hasVal_ = true;
249 val_ = std::forward<T>(val);
250 return *this;
251 }
252 inline optional &operator=(const optional &) = default;
operator =(optional && other)253 inline optional &operator=(optional &&other) noexcept {
254 hasVal_ = other.hasVal_;
255 val_ = std::forward<T>(other.val_);
256 other.hasVal_ = false;
257 return *this;
258 }
259
operator ->()260 inline T *operator->() { return &val_; }
operator *()261 inline T &operator*() { return val_; }
262
263 //! @endcond
264
265 /** Returns a pointer to the contained value. */
operator ->() const266 inline const T *operator->() const { return &val_; }
267
268 /** Returns a reference to the contained value. */
operator *() const269 inline const T &operator*() const { return val_; }
270
271 /** Return whether the optional has a value */
operator bool() const272 inline explicit operator bool() const noexcept { return hasVal_; }
273
274 /** Return whether the optional has a value */
has_value() const275 inline bool has_value() const noexcept { return hasVal_; }
276
277 private:
278 bool hasVal_;
279 T val_{};
280 };
281
282 // ---------------------------------------------------------------------------
283
284 class BaseObject;
285 /** Shared pointer of BaseObject. */
286 using BaseObjectPtr = std::shared_ptr<BaseObject>;
287 #if 1
288 /** Non-null shared pointer of BaseObject. */
289 struct BaseObjectNNPtr : public util::nn<BaseObjectPtr> {
290 // This trick enables to avoid inlining of the destructor.
291 // This is mostly an alias of the base class.
292 //! @cond Doxygen_Suppress
293 template <class T>
294 // cppcheck-suppress noExplicitConstructor
BaseObjectNNPtrutil::BaseObjectNNPtr295 BaseObjectNNPtr(const util::nn<std::shared_ptr<T>> &x)
296 : util::nn<BaseObjectPtr>(x) {}
297
298 template <class T>
299 // cppcheck-suppress noExplicitConstructor
BaseObjectNNPtrutil::BaseObjectNNPtr300 BaseObjectNNPtr(util::nn<std::shared_ptr<T>> &&x) noexcept
301 : util::nn<BaseObjectPtr>(NN_NO_CHECK(std::move(x.as_nullable()))) {}
302
BaseObjectNNPtrutil::BaseObjectNNPtr303 explicit BaseObjectNNPtr(::dropbox::oxygen::i_promise_i_checked_for_null_t,
304 BaseObjectPtr &&arg) noexcept
305 : util::nn<BaseObjectPtr>(i_promise_i_checked_for_null,
306 std::move(arg)) {}
307 BaseObjectNNPtr(const BaseObjectNNPtr &) = default;
308 BaseObjectNNPtr &operator=(const BaseObjectNNPtr &) = default;
309
310 PROJ_DLL ~BaseObjectNNPtr();
311 //! @endcond
312 };
313 #else
314 using BaseObjectNNPtr = util::nn<BaseObjectPtr>;
315 #endif
316
317 /** \brief Class that can be derived from, to emulate Java's Object behavior.
318 */
319 class PROJ_GCC_DLL BaseObject {
320 public:
321 //! @cond Doxygen_Suppress
322 virtual PROJ_DLL ~BaseObject();
323 //! @endcond
324
325 PROJ_PRIVATE :
326 //! @cond Doxygen_Suppress
327 PROJ_INTERNAL BaseObjectNNPtr
328 shared_from_this() const;
329 //! @endcond
330
331 protected:
332 PROJ_INTERNAL BaseObject();
333 PROJ_INTERNAL void assignSelf(const BaseObjectNNPtr &self);
334
335 private:
336 PROJ_OPAQUE_PRIVATE_DATA
337 };
338
339 // ---------------------------------------------------------------------------
340
341 /** \brief Interface for an object that can be compared to another.
342 */
343 class PROJ_GCC_DLL IComparable {
344 public:
345 //! @cond Doxygen_Suppress
346 PROJ_DLL virtual ~IComparable();
347 //! @endcond
348
349 /** \brief Comparison criterion. */
350 enum class PROJ_MSVC_DLL Criterion {
351 /** All properties are identical. */
352 STRICT,
353
354 /** The objects are equivalent for the purpose of coordinate
355 * operations. They can differ by the name of their objects,
356 * identifiers, other metadata.
357 * Parameters may be expressed in different units, provided that the
358 * value is (with some tolerance) the same once expressed in a
359 * common unit.
360 */
361 EQUIVALENT,
362
363 /** Same as EQUIVALENT, relaxed with an exception that the axis order
364 * of the base CRS of a DerivedCRS/ProjectedCRS or the axis order of
365 * a GeographicCRS is ignored. Only to be used
366 * with DerivedCRS/ProjectedCRS/GeographicCRS */
367 EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
368 };
369
370 PROJ_DLL bool
371 isEquivalentTo(const IComparable *other,
372 Criterion criterion = Criterion::STRICT,
373 const io::DatabaseContextPtr &dbContext = nullptr) const;
374
375 PROJ_PRIVATE :
376
377 //! @cond Doxygen_Suppress
378 PROJ_INTERNAL virtual bool
379 _isEquivalentTo(
380 const IComparable *other, Criterion criterion = Criterion::STRICT,
381 const io::DatabaseContextPtr &dbContext = nullptr) const = 0;
382 //! @endcond
383 };
384
385 // ---------------------------------------------------------------------------
386
387 /** \brief Encapsulate standard datatypes in an object.
388 */
389 class BoxedValue final : public BaseObject {
390 public:
391 //! @cond Doxygen_Suppress
392 /** Type of data stored in the BoxedValue. */
393 enum class Type {
394 /** a std::string */
395 STRING,
396 /** an integer */
397 INTEGER,
398 /** a boolean */
399 BOOLEAN
400 };
401 //! @endcond
402
403 // cppcheck-suppress noExplicitConstructor
404 PROJ_DLL BoxedValue(const char *stringValueIn); // needed to avoid the bool
405 // constructor to be taken !
406 // cppcheck-suppress noExplicitConstructor
407 PROJ_DLL BoxedValue(const std::string &stringValueIn);
408 // cppcheck-suppress noExplicitConstructor
409 PROJ_DLL BoxedValue(int integerValueIn);
410 // cppcheck-suppress noExplicitConstructor
411 PROJ_DLL BoxedValue(bool booleanValueIn);
412
413 PROJ_PRIVATE :
414 //! @cond Doxygen_Suppress
415 PROJ_INTERNAL
416 BoxedValue(const BoxedValue &other);
417
418 PROJ_DLL ~BoxedValue() override;
419
420 PROJ_INTERNAL const Type &type() const;
421 PROJ_INTERNAL const std::string &stringValue() const;
422 PROJ_INTERNAL int integerValue() const;
423 PROJ_INTERNAL bool booleanValue() const;
424 //! @endcond
425
426 private:
427 PROJ_OPAQUE_PRIVATE_DATA
428 BoxedValue &operator=(const BoxedValue &) = delete;
429
430 PROJ_INTERNAL BoxedValue();
431 };
432
433 /** Shared pointer of BoxedValue. */
434 using BoxedValuePtr = std::shared_ptr<BoxedValue>;
435 /** Non-null shared pointer of BoxedValue. */
436 using BoxedValueNNPtr = util::nn<BoxedValuePtr>;
437
438 // ---------------------------------------------------------------------------
439
440 class ArrayOfBaseObject;
441 /** Shared pointer of ArrayOfBaseObject. */
442 using ArrayOfBaseObjectPtr = std::shared_ptr<ArrayOfBaseObject>;
443 /** Non-null shared pointer of ArrayOfBaseObject. */
444 using ArrayOfBaseObjectNNPtr = util::nn<ArrayOfBaseObjectPtr>;
445
446 /** \brief Array of BaseObject.
447 */
448 class ArrayOfBaseObject final : public BaseObject {
449 public:
450 //! @cond Doxygen_Suppress
451 PROJ_DLL ~ArrayOfBaseObject() override;
452 //! @endcond
453
454 PROJ_DLL void add(const BaseObjectNNPtr &obj);
455
456 PROJ_DLL static ArrayOfBaseObjectNNPtr create();
457
458 PROJ_PRIVATE :
459 //! @cond Doxygen_Suppress
460 std::vector<BaseObjectNNPtr>::const_iterator
461 begin() const;
462 std::vector<BaseObjectNNPtr>::const_iterator end() const;
463 bool empty() const;
464 //! @endcond
465
466 protected:
467 ArrayOfBaseObject();
468 INLINED_MAKE_SHARED
469
470 private:
471 ArrayOfBaseObject(const ArrayOfBaseObject &other) = delete;
472 ArrayOfBaseObject &operator=(const ArrayOfBaseObject &other) = delete;
473 PROJ_OPAQUE_PRIVATE_DATA
474 };
475
476 // ---------------------------------------------------------------------------
477
478 /** \brief Wrapper of a std::map<std::string, BaseObjectNNPtr> */
479 class PropertyMap {
480 public:
481 PROJ_DLL PropertyMap();
482 //! @cond Doxygen_Suppress
483 PROJ_DLL PropertyMap(const PropertyMap &other);
484 PROJ_DLL ~PropertyMap();
485 //! @endcond
486
487 PROJ_DLL PropertyMap &set(const std::string &key,
488 const BaseObjectNNPtr &val);
489
490 //! @cond Doxygen_Suppress
491 template <class T>
set(const std::string & key,const nn_shared_ptr<T> & val)492 inline PropertyMap &set(const std::string &key,
493 const nn_shared_ptr<T> &val) {
494 return set(
495 key, BaseObjectNNPtr(i_promise_i_checked_for_null,
496 BaseObjectPtr(val.as_nullable(), val.get())));
497 }
498 //! @endcond
499
500 // needed to avoid the bool constructor to be taken !
501 PROJ_DLL PropertyMap &set(const std::string &key, const char *val);
502
503 PROJ_DLL PropertyMap &set(const std::string &key, const std::string &val);
504
505 PROJ_DLL PropertyMap &set(const std::string &key, int val);
506
507 PROJ_DLL PropertyMap &set(const std::string &key, bool val);
508
509 PROJ_DLL PropertyMap &set(const std::string &key,
510 const std::vector<std::string> &array);
511
512 PROJ_PRIVATE :
513 //! @cond Doxygen_Suppress
514 const BaseObjectNNPtr *
515 get(const std::string &key) const;
516
517 // throw(InvalidValueTypeException)
518 bool getStringValue(const std::string &key, std::string &outVal) const;
519 bool getStringValue(const std::string &key,
520 optional<std::string> &outVal) const;
521 void unset(const std::string &key);
522
523 static PropertyMap createAndSetName(const char *name);
524 static PropertyMap createAndSetName(const std::string &name);
525 //! @endcond
526
527 private:
528 PropertyMap &operator=(const PropertyMap &) = delete;
529
530 PROJ_OPAQUE_PRIVATE_DATA
531 };
532
533 // ---------------------------------------------------------------------------
534
535 class LocalName;
536 /** Shared pointer of LocalName. */
537 using LocalNamePtr = std::shared_ptr<LocalName>;
538 /** Non-null shared pointer of LocalName. */
539 using LocalNameNNPtr = util::nn<LocalNamePtr>;
540
541 class NameSpace;
542 /** Shared pointer of NameSpace. */
543 using NameSpacePtr = std::shared_ptr<NameSpace>;
544 /** Non-null shared pointer of NameSpace. */
545 using NameSpaceNNPtr = util::nn<NameSpacePtr>;
546
547 class GenericName;
548 /** Shared pointer of GenericName. */
549 using GenericNamePtr = std::shared_ptr<GenericName>;
550 /** Non-null shared pointer of GenericName. */
551 using GenericNameNNPtr = util::nn<GenericNamePtr>;
552
553 // ---------------------------------------------------------------------------
554
555 /** \brief A sequence of identifiers rooted within the context of a namespace.
556 *
557 * \remark Simplified version of [GenericName]
558 * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/GenericName.html) from
559 * \ref GeoAPI
560 */
561 class GenericName : public BaseObject {
562 public:
563 //! @cond Doxygen_Suppress
564 PROJ_DLL virtual ~GenericName() override;
565 //! @endcond
566
567 /** \brief Return the scope of the object, possibly a global one. */
568 PROJ_DLL virtual const NameSpacePtr scope() const = 0;
569
570 /** \brief Return the LocalName as a string. */
571 PROJ_DLL virtual std::string toString() const = 0;
572
573 /** \brief Return a fully qualified name corresponding to the local name.
574 *
575 * The namespace of the resulting name is a global one.
576 */
577 PROJ_DLL virtual GenericNameNNPtr toFullyQualifiedName() const = 0;
578
579 protected:
580 GenericName();
581 GenericName(const GenericName &other);
582
583 private:
584 PROJ_OPAQUE_PRIVATE_DATA
585 GenericName &operator=(const GenericName &other) = delete;
586 };
587
588 // ---------------------------------------------------------------------------
589
590 /** \brief A domain in which names given by strings are defined.
591 *
592 * \remark Simplified version of [NameSpace]
593 * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/NameSpace.html) from \ref
594 * GeoAPI
595 */
596 class NameSpace {
597 public:
598 //! @cond Doxygen_Suppress
599 PROJ_DLL ~NameSpace();
600 //! @endcond
601
602 PROJ_DLL bool isGlobal() const;
603 PROJ_DLL const GenericNamePtr &name() const;
604
605 protected:
606 PROJ_FRIEND(NameFactory);
607 PROJ_FRIEND(LocalName);
608 explicit NameSpace(const GenericNamePtr &name);
609 NameSpace(const NameSpace &other);
610 NameSpaceNNPtr getGlobalFromThis() const;
611 const std::string &separator() const;
612 static const NameSpaceNNPtr GLOBAL;
613 INLINED_MAKE_SHARED
614
615 private:
616 PROJ_OPAQUE_PRIVATE_DATA
617 NameSpace &operator=(const NameSpace &other) = delete;
618
619 static NameSpaceNNPtr createGLOBAL();
620 };
621
622 // ---------------------------------------------------------------------------
623
624 /** \brief Identifier within a NameSpace for a local object.
625 *
626 * Local names are names which are directly accessible to and maintained by a
627 * NameSpace within which they are local, indicated by the scope.
628 *
629 * \remark Simplified version of [LocalName]
630 * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/LocalName.html) from \ref
631 * GeoAPI
632 */
633 class LocalName : public GenericName {
634 public:
635 //! @cond Doxygen_Suppress
636 PROJ_DLL ~LocalName() override;
637 //! @endcond
638
639 PROJ_DLL const NameSpacePtr scope() const override;
640 PROJ_DLL std::string toString() const override;
641 PROJ_DLL GenericNameNNPtr toFullyQualifiedName() const override;
642
643 protected:
644 PROJ_FRIEND(NameFactory);
645 PROJ_FRIEND(NameSpace);
646 explicit LocalName(const std::string &nameIn);
647 LocalName(const LocalName &other);
648 LocalName(const NameSpacePtr &ns, const std::string &name);
649 INLINED_MAKE_SHARED
650
651 private:
652 PROJ_OPAQUE_PRIVATE_DATA
653 LocalName &operator=(const LocalName &other) = delete;
654 };
655
656 // ---------------------------------------------------------------------------
657
658 /** \brief Factory for generic names.
659 *
660 * \remark Simplified version of [NameFactory]
661 * (http://www.geoapi.org/3.0/javadoc/org/opengis/util/NameFactory.html) from
662 * \ref GeoAPI
663 */
664 class NameFactory {
665 public:
666 PROJ_DLL static NameSpaceNNPtr
667 createNameSpace(const GenericNameNNPtr &name,
668 const PropertyMap &properties);
669 PROJ_DLL static LocalNameNNPtr createLocalName(const NameSpacePtr &scope,
670 const std::string &name);
671 PROJ_DLL static GenericNameNNPtr
672 createGenericName(const NameSpacePtr &scope,
673 const std::vector<std::string> &parsedNames);
674 };
675
676 // ---------------------------------------------------------------------------
677
678 /** \brief Abstract class to define an enumeration of values.
679 */
680 class CodeList {
681 public:
682 //! @cond Doxygen_Suppress
683 PROJ_DLL ~CodeList();
684 //! @endcond
685
686 /** Return the CodeList item as a string. */
687 // cppcheck-suppress functionStatic
toString()688 inline const std::string &toString() PROJ_PURE_DECL { return name_; }
689
690 /** Return the CodeList item as a string. */
operator std::string()691 inline operator std::string() PROJ_PURE_DECL { return toString(); }
692
693 //! @cond Doxygen_Suppress
operator ==(const CodeList & other)694 inline bool operator==(const CodeList &other) PROJ_PURE_DECL {
695 return name_ == other.name_;
696 }
operator !=(const CodeList & other)697 inline bool operator!=(const CodeList &other) PROJ_PURE_DECL {
698 return name_ != other.name_;
699 }
700 //! @endcond
701 protected:
CodeList(const std::string & nameIn)702 explicit CodeList(const std::string &nameIn) : name_(nameIn) {}
703 CodeList(const CodeList &) = default;
704 CodeList &operator=(const CodeList &other);
705
706 private:
707 std::string name_{};
708 };
709
710 // ---------------------------------------------------------------------------
711
712 /** \brief Root exception class.
713 */
714 class PROJ_GCC_DLL Exception : public std::exception {
715 std::string msg_;
716
717 public:
718 //! @cond Doxygen_Suppress
719 PROJ_INTERNAL explicit Exception(const char *message);
720 PROJ_INTERNAL explicit Exception(const std::string &message);
721 PROJ_DLL Exception(const Exception &other);
722 PROJ_DLL ~Exception() override;
723 //! @endcond
724 PROJ_DLL virtual const char *what() const noexcept override;
725 };
726
727 // ---------------------------------------------------------------------------
728
729 /** \brief Exception thrown when an invalid value type is set as the value of
730 * a key of a PropertyMap.
731 */
732 class PROJ_GCC_DLL InvalidValueTypeException : public Exception {
733 public:
734 //! @cond Doxygen_Suppress
735 PROJ_INTERNAL explicit InvalidValueTypeException(const char *message);
736 PROJ_INTERNAL explicit InvalidValueTypeException(
737 const std::string &message);
738 PROJ_DLL InvalidValueTypeException(const InvalidValueTypeException &other);
739 PROJ_DLL ~InvalidValueTypeException() override;
740 //! @endcond
741 };
742
743 // ---------------------------------------------------------------------------
744
745 /** \brief Exception Thrown to indicate that the requested operation is not
746 * supported.
747 */
748 class PROJ_GCC_DLL UnsupportedOperationException : public Exception {
749 public:
750 //! @cond Doxygen_Suppress
751 PROJ_INTERNAL explicit UnsupportedOperationException(const char *message);
752 PROJ_INTERNAL explicit UnsupportedOperationException(
753 const std::string &message);
754 PROJ_DLL
755 UnsupportedOperationException(const UnsupportedOperationException &other);
756 PROJ_DLL ~UnsupportedOperationException() override;
757 //! @endcond
758 };
759
760 } // namespace util
761
762 NS_PROJ_END
763
764 #endif // UTIL_HH_INCLUDED
765