Coverage Report

Created: 2025-06-20 06:58

/src/PROJ/include/proj/internal/internal.hpp
Line
Count
Source (jump to first uncovered line)
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 FROM_PROJ_CPP
30
#error This file should only be included from a PROJ cpp file
31
#endif
32
33
#ifndef INTERNAL_HH_INCLUDED
34
#define INTERNAL_HH_INCLUDED
35
36
#if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
37
#error Must have C++11 or newer.
38
#endif
39
40
#include <cassert>
41
#include <cstring>
42
#include <memory>
43
#include <string>
44
#ifndef DOXYGEN_ENABLED
45
#include <type_traits> // for std::is_base_of
46
#endif
47
#include <vector>
48
49
#include "proj/util.hpp"
50
51
//! @cond Doxygen_Suppress
52
53
// Use "PROJ_FALLTHROUGH;" to annotate deliberate fall-through in switches,
54
// use it analogously to "break;".  The trailing semi-colon is required.
55
#if !defined(PROJ_FALLTHROUGH) && defined(__has_cpp_attribute)
56
#if __cplusplus >= 201703L && __has_cpp_attribute(fallthrough)
57
0
#define PROJ_FALLTHROUGH [[fallthrough]]
58
#elif __cplusplus >= 201103L && __has_cpp_attribute(gnu::fallthrough)
59
#define PROJ_FALLTHROUGH [[gnu::fallthrough]]
60
#elif __cplusplus >= 201103L && __has_cpp_attribute(clang::fallthrough)
61
#define PROJ_FALLTHROUGH [[clang::fallthrough]]
62
#endif
63
#endif
64
65
#ifndef PROJ_FALLTHROUGH
66
#define PROJ_FALLTHROUGH ((void)0)
67
#endif
68
69
#if defined(__clang__) || defined(_MSC_VER)
70
#define COMPILER_WARNS_ABOUT_ABSTRACT_VBASE_INIT
71
#endif
72
73
NS_PROJ_START
74
75
namespace operation {
76
class OperationParameterValue;
77
} // namespace operation
78
79
namespace internal {
80
81
/** Use cpl::down_cast<Derived*>(pointer_to_base) as equivalent of
82
 * static_cast<Derived*>(pointer_to_base) with safe checking in debug
83
 * mode.
84
 *
85
 * Only works if no virtual inheritance is involved.
86
 *
87
 * @param f pointer to a base class
88
 * @return pointer to a derived class
89
 */
90
template <typename To, typename From> inline To down_cast(From *f) {
91
    static_assert(
92
        (std::is_base_of<From, typename std::remove_pointer<To>::type>::value),
93
        "target type not derived from source type");
94
    assert(f == nullptr || dynamic_cast<To>(f) != nullptr);
95
    return static_cast<To>(f);
96
}
97
98
PROJ_FOR_TEST std::string replaceAll(const std::string &str,
99
                                     const std::string &before,
100
                                     const std::string &after);
101
102
PROJ_DLL size_t ci_find(const std::string &osStr, const char *needle) noexcept;
103
104
size_t ci_find(const std::string &osStr, const std::string &needle,
105
               size_t startPos = 0) noexcept;
106
107
inline bool starts_with(const std::string &str,
108
1.53M
                        const std::string &prefix) noexcept {
109
1.53M
    if (str.size() < prefix.size()) {
110
140k
        return false;
111
140k
    }
112
1.39M
    return std::memcmp(str.c_str(), prefix.c_str(), prefix.size()) == 0;
113
1.53M
}
114
115
42.1M
inline bool starts_with(const std::string &str, const char *prefix) noexcept {
116
42.1M
    const size_t prefixSize = std::strlen(prefix);
117
42.1M
    if (str.size() < prefixSize) {
118
14.2M
        return false;
119
14.2M
    }
120
27.9M
    return std::memcmp(str.c_str(), prefix, prefixSize) == 0;
121
42.1M
}
122
123
bool ci_less(const std::string &a, const std::string &b) noexcept;
124
125
PROJ_DLL bool ci_starts_with(const char *str, const char *prefix) noexcept;
126
127
bool ci_starts_with(const std::string &str, const std::string &prefix) noexcept;
128
129
bool ends_with(const std::string &str, const std::string &suffix) noexcept;
130
131
PROJ_FOR_TEST std::string tolower(const std::string &osStr);
132
133
std::string toupper(const std::string &osStr);
134
135
PROJ_FOR_TEST std::vector<std::string> split(const std::string &osStr,
136
                                             char separator);
137
138
PROJ_FOR_TEST std::vector<std::string> split(const std::string &osStr,
139
                                             const std::string &separator);
140
141
bool ci_equal(const char *a, const char *b) noexcept;
142
143
bool ci_equal(const char *a, const std::string &b) = delete;
144
145
PROJ_FOR_TEST bool ci_equal(const std::string &a, const char *b) noexcept;
146
147
PROJ_FOR_TEST bool ci_equal(const std::string &a,
148
                            const std::string &b) noexcept;
149
150
std::string stripQuotes(const std::string &osStr);
151
152
std::string toString(int val);
153
154
PROJ_FOR_TEST std::string toString(double val, int precision = 15);
155
156
PROJ_FOR_TEST double
157
c_locale_stod(const std::string &s); // throw(std::invalid_argument)
158
159
// Variant of above that doesn't emit exceptions
160
double c_locale_stod(const std::string &s, bool &success);
161
162
std::string concat(const std::string &, const std::string &) = delete;
163
std::string concat(const char *, const char *) = delete;
164
std::string concat(const char *a, const std::string &b);
165
std::string concat(const std::string &, const char *) = delete;
166
std::string concat(const char *, const char *, const char *) = delete;
167
std::string concat(const char *, const char *, const std::string &) = delete;
168
std::string concat(const char *a, const std::string &b, const char *c);
169
std::string concat(const char *, const std::string &,
170
                   const std::string &) = delete;
171
std::string concat(const std::string &, const char *, const char *) = delete;
172
std::string concat(const std::string &, const char *,
173
                   const std::string &) = delete;
174
std::string concat(const std::string &, const std::string &,
175
                   const char *) = delete;
176
std::string concat(const std::string &, const std::string &,
177
                   const std::string &) = delete;
178
179
double getRoundedEpochInDecimalYear(double year);
180
181
} // namespace internal
182
183
NS_PROJ_END
184
185
//! @endcond
186
187
#endif // INTERNAL_HH_INCLUDED