Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: CPL - Common Portability Library
4 : * Purpose: Convenience functions declarations.
5 : * This is intended to remain light weight.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1998, Frank Warmerdam
10 : * Copyright (c) 2007-2013, Even Rouault <even dot rouault at spatialys.com>
11 : *
12 : * SPDX-License-Identifier: MIT
13 : ****************************************************************************/
14 :
15 : #ifndef CPL_CONV_H_INCLUDED
16 : #define CPL_CONV_H_INCLUDED
17 :
18 : #include "cpl_port.h"
19 : #include "cpl_vsi.h"
20 : #include "cpl_error.h"
21 :
22 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
23 : #include <cstdint>
24 : #endif
25 :
26 : /**
27 : * \file cpl_conv.h
28 : *
29 : * Various convenience functions for CPL.
30 : *
31 : */
32 :
33 : /* -------------------------------------------------------------------- */
34 : /* Runtime check of various configuration items. */
35 : /* -------------------------------------------------------------------- */
36 : CPL_C_START
37 :
38 : /*! @cond Doxygen_Suppress */
39 : void CPL_DLL CPLVerifyConfiguration(void);
40 : /*! @endcond */
41 :
42 : bool CPL_DLL CPLIsDebugEnabled(void);
43 :
44 : const char CPL_DLL *CPL_STDCALL CPLGetConfigOption(const char *, const char *)
45 : CPL_WARN_UNUSED_RESULT;
46 : const char CPL_DLL *CPL_STDCALL CPLGetThreadLocalConfigOption(
47 : const char *, const char *) CPL_WARN_UNUSED_RESULT;
48 : const char CPL_DLL *CPL_STDCALL
49 : CPLGetGlobalConfigOption(const char *, const char *) CPL_WARN_UNUSED_RESULT;
50 : void CPL_DLL CPL_STDCALL CPLSetConfigOption(const char *, const char *);
51 : void CPL_DLL CPL_STDCALL CPLSetThreadLocalConfigOption(const char *pszKey,
52 : const char *pszValue);
53 : void CPL_DLL CPLDeclareKnownConfigOption(const char *pszKey,
54 : const char *pszDefinition);
55 : char CPL_DLL **CPLGetKnownConfigOptions(void);
56 :
57 : /** Callback for CPLSubscribeToSetConfigOption() */
58 : typedef void (*CPLSetConfigOptionSubscriber)(const char *pszKey,
59 : const char *pszValue,
60 : bool bThreadLocal,
61 : void *pUserData);
62 : int CPL_DLL CPLSubscribeToSetConfigOption(
63 : CPLSetConfigOptionSubscriber pfnCallback, void *pUserData);
64 : void CPL_DLL CPLUnsubscribeToSetConfigOption(int nSubscriberId);
65 :
66 : /*! @cond Doxygen_Suppress */
67 : void CPL_DLL CPL_STDCALL CPLFreeConfig(void);
68 : /*! @endcond */
69 : char CPL_DLL **CPLGetConfigOptions(void);
70 : void CPL_DLL CPLSetConfigOptions(const char *const *papszConfigOptions);
71 : char CPL_DLL **CPLGetThreadLocalConfigOptions(void);
72 : void CPL_DLL
73 : CPLSetThreadLocalConfigOptions(const char *const *papszConfigOptions);
74 : void CPL_DLL CPLLoadConfigOptionsFromFile(const char *pszFilename,
75 : int bOverrideEnvVars);
76 : void CPL_DLL CPLLoadConfigOptionsFromPredefinedFiles(void);
77 :
78 : /* -------------------------------------------------------------------- */
79 : /* Safe malloc() API. Thin cover over VSI functions with fatal */
80 : /* error reporting if memory allocation fails. */
81 : /* -------------------------------------------------------------------- */
82 : void CPL_DLL *CPLMalloc(size_t) CPL_WARN_UNUSED_RESULT;
83 : void CPL_DLL *CPLCalloc(size_t, size_t) CPL_WARN_UNUSED_RESULT;
84 : void CPL_DLL *CPLRealloc(void *, size_t) CPL_WARN_UNUSED_RESULT;
85 : char CPL_DLL *
86 : CPLStrdup(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
87 : char CPL_DLL *CPLStrlwr(char *);
88 :
89 : /** Alias of VSIFree() */
90 : #define CPLFree VSIFree
91 :
92 : /* -------------------------------------------------------------------- */
93 : /* Read a line from a text file, and strip of CR/LF. */
94 : /* -------------------------------------------------------------------- */
95 : char CPL_DLL *CPLFGets(char *, int, FILE *);
96 : const char CPL_DLL *CPLReadLine(FILE *);
97 : const char CPL_DLL *CPLReadLineL(VSILFILE *);
98 : const char CPL_DLL *CPLReadLine2L(VSILFILE *, int, CSLConstList);
99 : const char CPL_DLL *CPLReadLine3L(VSILFILE *, int, int *, CSLConstList);
100 :
101 : /* -------------------------------------------------------------------- */
102 : /* Convert ASCII string to floating point number */
103 : /* (THESE FUNCTIONS ARE NOT LOCALE AWARE!). */
104 : /* -------------------------------------------------------------------- */
105 : double CPL_DLL CPLAtof(const char *);
106 : double CPL_DLL CPLAtofDelim(const char *, char);
107 : double CPL_DLL CPLStrtod(const char *, char **);
108 : double CPL_DLL CPLStrtodM(const char *, char **);
109 : double CPL_DLL CPLStrtodDelim(const char *, char **, char);
110 : float CPL_DLL CPLStrtof(const char *, char **);
111 : float CPL_DLL CPLStrtofDelim(const char *, char **, char);
112 :
113 : /* -------------------------------------------------------------------- */
114 : /* Convert number to string. This function is locale agnostic */
115 : /* (i.e. it will support "," or "." regardless of current locale) */
116 : /* -------------------------------------------------------------------- */
117 : double CPL_DLL CPLAtofM(const char *);
118 :
119 : /* -------------------------------------------------------------------- */
120 : /* Read a numeric value from an ASCII character string. */
121 : /* -------------------------------------------------------------------- */
122 : char CPL_DLL *CPLScanString(const char *, int, int, int);
123 : double CPL_DLL CPLScanDouble(const char *, int);
124 : long CPL_DLL CPLScanLong(const char *, int);
125 : unsigned long CPL_DLL CPLScanULong(const char *, int);
126 : GUIntBig CPL_DLL CPLScanUIntBig(const char *, int);
127 : GIntBig CPL_DLL CPLAtoGIntBig(const char *pszString);
128 : GIntBig CPL_DLL CPLAtoGIntBigEx(const char *pszString, int bWarn,
129 : int *pbOverflow);
130 : void CPL_DLL *CPLScanPointer(const char *, int);
131 :
132 : /* -------------------------------------------------------------------- */
133 : /* Print a value to an ASCII character string. */
134 : /* -------------------------------------------------------------------- */
135 : int CPL_DLL CPLPrintString(char *, const char *, int);
136 : int CPL_DLL CPLPrintStringFill(char *, const char *, int);
137 : int CPL_DLL CPLPrintInt32(char *, GInt32, int);
138 : int CPL_DLL CPLPrintUIntBig(char *, GUIntBig, int);
139 : int CPL_DLL CPLPrintDouble(char *, const char *, double, const char *);
140 : int CPL_DLL CPLPrintTime(char *, int, const char *, const struct tm *,
141 : const char *);
142 : int CPL_DLL CPLPrintPointer(char *, void *, int);
143 :
144 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
145 : extern "C++"
146 : {
147 : std::string CPL_DLL CPLFormatReadableFileSize(uint64_t nSizeInBytes);
148 : std::string CPL_DLL CPLFormatReadableFileSize(double dfSizeInBytes);
149 : }
150 : #endif
151 :
152 : /* -------------------------------------------------------------------- */
153 : /* Fetch a function from DLL / so. */
154 : /* -------------------------------------------------------------------- */
155 :
156 : void CPL_DLL *CPLGetSymbol(const char *, const char *);
157 :
158 : /* -------------------------------------------------------------------- */
159 : /* Fetch executable path. */
160 : /* -------------------------------------------------------------------- */
161 : int CPL_DLL CPLGetExecPath(char *pszPathBuf, int nMaxLength);
162 :
163 : /* -------------------------------------------------------------------- */
164 : /* Filename handling functions. */
165 : /* -------------------------------------------------------------------- */
166 :
167 : #if defined(DOXYGEN_SKIP) || !defined(__cplusplus) || \
168 : !defined(GDAL_COMPILATION) || \
169 : (defined(__cplusplus) && defined(ALLOW_DEPRECATED_CPL_PATH_FUNCTIONS))
170 : const char CPL_DLL *
171 : CPLGetPath(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
172 : const char CPL_DLL *
173 : CPLGetDirname(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
174 : const char CPL_DLL *
175 : CPLGetBasename(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
176 : const char CPL_DLL *
177 : CPLGetExtension(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
178 : const char CPL_DLL *CPLFormFilename(
179 : const char *pszPath, const char *pszBasename,
180 : const char *pszExtension) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
181 : const char CPL_DLL *CPLFormCIFilename(
182 : const char *pszPath, const char *pszBasename,
183 : const char *pszExtension) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
184 : const char CPL_DLL *CPLResetExtension(const char *, const char *)
185 : CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
186 : const char CPL_DLL *CPLProjectRelativeFilename(const char *pszProjectDir,
187 : const char *pszSecondaryFilename)
188 : CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
189 : const char CPL_DLL *
190 : CPLCleanTrailingSlash(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
191 : const char CPL_DLL *CPLGenerateTempFilename(const char *pszStem)
192 : CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
193 : const char CPL_DLL *CPLExpandTilde(const char *pszFilename)
194 : CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
195 : const char CPL_DLL *
196 : CPLLaunderForFilename(const char *pszName,
197 : const char *pszOutputPath) CPL_WARN_UNUSED_RESULT;
198 : #endif
199 :
200 : char CPL_DLL *CPLGetCurrentDir(void);
201 : const char CPL_DLL *
202 : CPLGetFilename(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
203 : int CPL_DLL CPLIsFilenameRelative(const char *pszFilename);
204 : const char CPL_DLL *CPLExtractRelativePath(const char *, const char *, int *)
205 : CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
206 : char CPL_DLL **
207 : CPLCorrespondingPaths(const char *pszOldFilename, const char *pszNewFilename,
208 : char **papszFileList) CPL_WARN_UNUSED_RESULT;
209 : int CPL_DLL CPLCheckForFile(char *pszFilename, char **papszSiblingList);
210 :
211 : const char CPL_DLL *CPLGetHomeDir(void) CPL_WARN_UNUSED_RESULT;
212 :
213 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
214 :
215 : extern "C++"
216 : {
217 : std::string CPL_DLL CPLGetPathSafe(const char *) CPL_WARN_UNUSED_RESULT;
218 : std::string CPL_DLL CPLGetDirnameSafe(const char *) CPL_WARN_UNUSED_RESULT;
219 : std::string CPL_DLL CPLGetBasenameSafe(const char *) CPL_WARN_UNUSED_RESULT;
220 : std::string CPL_DLL CPLGetExtensionSafe(const char *)
221 : CPL_WARN_UNUSED_RESULT;
222 : std::string CPL_DLL CPLFormFilenameSafe(
223 : const char *pszPath, const char *pszBasename,
224 : const char *pszExtension = nullptr) CPL_WARN_UNUSED_RESULT;
225 : std::string CPL_DLL CPLFormCIFilenameSafe(
226 : const char *pszPath, const char *pszBasename,
227 : const char *pszExtension = nullptr) CPL_WARN_UNUSED_RESULT;
228 : std::string CPL_DLL CPLResetExtensionSafe(const char *, const char *)
229 : CPL_WARN_UNUSED_RESULT;
230 : std::string CPL_DLL CPLProjectRelativeFilenameSafe(
231 : const char *pszProjectDir,
232 : const char *pszSecondaryFilename) CPL_WARN_UNUSED_RESULT;
233 : std::string CPL_DLL CPLCleanTrailingSlashSafe(const char *pszPath)
234 : CPL_WARN_UNUSED_RESULT;
235 : std::string CPL_DLL CPLGenerateTempFilenameSafe(const char *pszStem)
236 : CPL_WARN_UNUSED_RESULT;
237 : std::string CPL_DLL CPLExpandTildeSafe(const char *pszFilename)
238 : CPL_WARN_UNUSED_RESULT;
239 : std::string CPL_DLL CPLLaunderForFilenameSafe(
240 : const char *pszName, const char *pszOutputPath) CPL_WARN_UNUSED_RESULT;
241 : }
242 :
243 : #endif // defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
244 :
245 : /* -------------------------------------------------------------------- */
246 : /* Find File Function */
247 : /* -------------------------------------------------------------------- */
248 :
249 : /** Callback for CPLPushFileFinder */
250 : typedef char const *(*CPLFileFinder)(const char *, const char *);
251 :
252 : const char CPL_DLL *CPLFindFile(const char *pszClass, const char *pszBasename);
253 : const char CPL_DLL *CPLDefaultFindFile(const char *pszClass,
254 : const char *pszBasename);
255 : void CPL_DLL CPLPushFileFinder(CPLFileFinder pfnFinder);
256 : CPLFileFinder CPL_DLL CPLPopFileFinder(void);
257 : void CPL_DLL CPLPushFinderLocation(const char *);
258 : void CPL_DLL CPLPopFinderLocation(void);
259 : void CPL_DLL CPLFinderClean(void);
260 :
261 : /* -------------------------------------------------------------------- */
262 : /* Safe version of stat() that works properly on stuff like "C:". */
263 : /* -------------------------------------------------------------------- */
264 : int CPL_DLL CPLStat(const char *, VSIStatBuf *) CPL_WARN_UNUSED_RESULT;
265 :
266 : /* -------------------------------------------------------------------- */
267 : /* Reference counted file handle manager. Makes sharing file */
268 : /* handles more practical. */
269 : /* -------------------------------------------------------------------- */
270 :
271 : /** Information on a shared file */
272 : typedef struct
273 : {
274 : FILE *fp; /**< File pointer */
275 : int nRefCount; /**< Reference counter */
276 : int bLarge; /**< Whether fp must be interpreted as VSIFILE* */
277 : char *pszFilename; /**< Filename */
278 : char *pszAccess; /**< Access mode */
279 : } CPLSharedFileInfo;
280 :
281 : FILE CPL_DLL *CPLOpenShared(const char *, const char *, int);
282 : void CPL_DLL CPLCloseShared(FILE *);
283 : CPLSharedFileInfo CPL_DLL *CPLGetSharedList(int *);
284 : void CPL_DLL CPLDumpSharedList(FILE *);
285 : /*! @cond Doxygen_Suppress */
286 : void CPL_DLL CPLCleanupSharedFileMutex(void);
287 : /*! @endcond */
288 :
289 : /* -------------------------------------------------------------------- */
290 : /* DMS to Dec to DMS conversion. */
291 : /* -------------------------------------------------------------------- */
292 : double CPL_DLL CPLDMSToDec(const char *is);
293 : const char CPL_DLL *CPLDecToDMS(double dfAngle, const char *pszAxis,
294 : int nPrecision);
295 : double CPL_DLL CPLPackedDMSToDec(double);
296 : double CPL_DLL CPLDecToPackedDMS(double dfDec);
297 :
298 : CPLErr CPL_DLL CPLStringToComplex(const char *pszString, double *pdfReal,
299 : double *pdfImag);
300 :
301 : /* -------------------------------------------------------------------- */
302 : /* Misc other functions. */
303 : /* -------------------------------------------------------------------- */
304 : int CPL_DLL CPLUnlinkTree(const char *);
305 : int CPL_DLL CPLCopyFile(const char *pszNewPath, const char *pszOldPath);
306 : int CPL_DLL CPLCopyTree(const char *pszNewPath, const char *pszOldPath);
307 : int CPL_DLL CPLMoveFile(const char *pszNewPath, const char *pszOldPath);
308 : int CPL_DLL CPLSymlink(const char *pszOldPath, const char *pszNewPath,
309 : CSLConstList papszOptions);
310 : int CPL_DLL CPLGetRemainingFileDescriptorCount(void);
311 :
312 : /* -------------------------------------------------------------------- */
313 : /* Lock related functions. */
314 : /* -------------------------------------------------------------------- */
315 :
316 : /** Return code of CPLLockFileEx(). */
317 : typedef enum
318 : {
319 : CLFS_OK, /**< CPLLockFileEx() succeeded. */
320 : CLFS_CANNOT_CREATE_LOCK, /**< Lock file creation failed. */
321 : CLFS_LOCK_BUSY, /**< Lock already taken (and still alive). */
322 : CLFS_API_MISUSE, /**< API misuse. */
323 : CLFS_THREAD_CREATION_FAILED, /**< Thread creation failed. */
324 : } CPLLockFileStatus;
325 :
326 : /** Handle type returned by CPLLockFileEx(). */
327 : typedef struct CPLLockFileStruct *CPLLockFileHandle;
328 :
329 : CPLLockFileStatus CPL_DLL CPLLockFileEx(const char *pszLockFileName,
330 : CPLLockFileHandle *phLockFileHandle,
331 : CSLConstList papszOptions);
332 :
333 : void CPL_DLL CPLUnlockFileEx(CPLLockFileHandle hLockFileHandle);
334 :
335 : /* -------------------------------------------------------------------- */
336 : /* ZIP Creation. */
337 : /* -------------------------------------------------------------------- */
338 :
339 : /*! @cond Doxygen_Suppress */
340 : #define CPL_ZIP_API_OFFERED
341 : /*! @endcond */
342 : void CPL_DLL *CPLCreateZip(const char *pszZipFilename, char **papszOptions);
343 : CPLErr CPL_DLL CPLCreateFileInZip(void *hZip, const char *pszFilename,
344 : char **papszOptions);
345 : CPLErr CPL_DLL CPLWriteFileInZip(void *hZip, const void *pBuffer,
346 : int nBufferSize);
347 : CPLErr CPL_DLL CPLCloseFileInZip(void *hZip);
348 : CPLErr CPL_DLL CPLAddFileInZip(void *hZip, const char *pszArchiveFilename,
349 : const char *pszInputFilename, VSILFILE *fpInput,
350 : CSLConstList papszOptions,
351 : GDALProgressFunc pProgressFunc,
352 : void *pProgressData);
353 : CPLErr CPL_DLL CPLCloseZip(void *hZip);
354 :
355 : /* -------------------------------------------------------------------- */
356 : /* ZLib compression */
357 : /* -------------------------------------------------------------------- */
358 :
359 : void CPL_DLL *CPLZLibDeflate(const void *ptr, size_t nBytes, int nLevel,
360 : void *outptr, size_t nOutAvailableBytes,
361 : size_t *pnOutBytes);
362 : void CPL_DLL *CPLZLibInflate(const void *ptr, size_t nBytes, void *outptr,
363 : size_t nOutAvailableBytes, size_t *pnOutBytes);
364 : void CPL_DLL *CPLZLibInflateEx(const void *ptr, size_t nBytes, void *outptr,
365 : size_t nOutAvailableBytes,
366 : bool bAllowResizeOutptr, size_t *pnOutBytes);
367 :
368 : /* -------------------------------------------------------------------- */
369 : /* XML validation. */
370 : /* -------------------------------------------------------------------- */
371 : int CPL_DLL CPLValidateXML(const char *pszXMLFilename,
372 : const char *pszXSDFilename,
373 : CSLConstList papszOptions);
374 :
375 : /* -------------------------------------------------------------------- */
376 : /* Locale handling. Prevents parallel executions of setlocale(). */
377 : /* -------------------------------------------------------------------- */
378 : char *CPLsetlocale(int category, const char *locale);
379 : /*! @cond Doxygen_Suppress */
380 : void CPLCleanupSetlocaleMutex(void);
381 : /*! @endcond */
382 :
383 : /*!
384 : CPLIsPowerOfTwo()
385 : @param i - tested number
386 : @return TRUE if i is power of two otherwise return FALSE
387 : */
388 : int CPL_DLL CPLIsPowerOfTwo(unsigned int i);
389 :
390 : /* -------------------------------------------------------------------- */
391 : /* Terminal related */
392 : /* -------------------------------------------------------------------- */
393 :
394 : bool CPL_DLL CPLIsInteractive(FILE *f);
395 :
396 : CPL_C_END
397 :
398 : /* -------------------------------------------------------------------- */
399 : /* C++ object for temporarily forcing a LC_NUMERIC locale to "C". */
400 : /* -------------------------------------------------------------------- */
401 :
402 : //! @cond Doxygen_Suppress
403 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
404 :
405 : extern "C++"
406 : {
407 : class CPL_DLL CPLLocaleC
408 : {
409 : CPL_DISALLOW_COPY_ASSIGN(CPLLocaleC)
410 : public:
411 : CPLLocaleC();
412 : ~CPLLocaleC();
413 :
414 : private:
415 : char *pszOldLocale;
416 : };
417 :
418 : // Does the same as CPLLocaleC except that, when available, it tries to
419 : // only affect the current thread. But code that would be dependent of
420 : // setlocale(LC_NUMERIC, NULL) returning "C", such as current proj.4
421 : // versions, will not work depending on the actual implementation
422 : class CPLThreadLocaleCPrivate;
423 :
424 : class CPL_DLL CPLThreadLocaleC
425 : {
426 : CPL_DISALLOW_COPY_ASSIGN(CPLThreadLocaleC)
427 :
428 : public:
429 : CPLThreadLocaleC();
430 : ~CPLThreadLocaleC();
431 :
432 : private:
433 : CPLThreadLocaleCPrivate *m_private;
434 : };
435 : }
436 :
437 : #endif /* def __cplusplus */
438 : //! @endcond
439 :
440 : /* -------------------------------------------------------------------- */
441 : /* C++ object for temporarily forcing a config option */
442 : /* -------------------------------------------------------------------- */
443 :
444 : //! @cond Doxygen_Suppress
445 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
446 :
447 : extern "C++"
448 : {
449 : class CPL_DLL CPLConfigOptionSetter
450 : {
451 : CPL_DISALLOW_COPY_ASSIGN(CPLConfigOptionSetter)
452 : public:
453 : CPLConfigOptionSetter(const char *pszKey, const char *pszValue,
454 : bool bSetOnlyIfUndefined);
455 : ~CPLConfigOptionSetter();
456 :
457 : private:
458 : char *m_pszKey;
459 : char *m_pszOldValue;
460 : bool m_bRestoreOldValue;
461 : };
462 : }
463 :
464 : #endif /* def __cplusplus */
465 : //! @endcond
466 :
467 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
468 :
469 : extern "C++"
470 : {
471 :
472 : #ifndef DOXYGEN_SKIP
473 : #include <type_traits> // for std::is_base_of
474 : #endif
475 :
476 : namespace cpl
477 : {
478 : /** Use cpl::down_cast<Derived*>(pointer_to_base) as equivalent of
479 : * static_cast<Derived*>(pointer_to_base) with safe checking in debug
480 : * mode.
481 : *
482 : * Only works if no virtual inheritance is involved.
483 : *
484 : * @param f pointer to a base class
485 : * @return pointer to a derived class
486 : */
487 6772738 : template <typename To, typename From> inline To down_cast(From *f)
488 : {
489 : static_assert(
490 : (std::is_base_of<From,
491 : typename std::remove_pointer<To>::type>::value),
492 : "target type not derived from source type");
493 6772738 : CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
494 6772738 : return static_cast<To>(f);
495 : }
496 :
497 : /** Computes ceil(a/b) where a and b are integers */
498 205 : template <class T, class U> inline T div_round_up(T a, U b)
499 : {
500 205 : return a / b + (((a % b) == 0) ? 0 : 1);
501 : }
502 :
503 : } // namespace cpl
504 : } // extern "C++"
505 :
506 : #endif /* def __cplusplus */
507 :
508 : #endif /* ndef CPL_CONV_H_INCLUDED */
|