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, CSLConstList 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 : bool CPL_DLL CPLHasPathTraversal(const char *pszFilename);
246 : bool CPL_DLL CPLHasUnbalancedPathTraversal(const char *pszFilename);
247 :
248 : /* -------------------------------------------------------------------- */
249 : /* Find File Function */
250 : /* -------------------------------------------------------------------- */
251 :
252 : /** Callback for CPLPushFileFinder */
253 : typedef char const *(*CPLFileFinder)(const char *, const char *);
254 :
255 : const char CPL_DLL *CPLFindFile(const char *pszClass, const char *pszBasename);
256 : const char CPL_DLL *CPLDefaultFindFile(const char *pszClass,
257 : const char *pszBasename);
258 : void CPL_DLL CPLPushFileFinder(CPLFileFinder pfnFinder);
259 : CPLFileFinder CPL_DLL CPLPopFileFinder(void);
260 : void CPL_DLL CPLPushFinderLocation(const char *);
261 : void CPL_DLL CPLPopFinderLocation(void);
262 : void CPL_DLL CPLFinderClean(void);
263 :
264 : /* -------------------------------------------------------------------- */
265 : /* Safe version of stat() that works properly on stuff like "C:". */
266 : /* -------------------------------------------------------------------- */
267 : int CPL_DLL CPLStat(const char *, VSIStatBuf *) CPL_WARN_UNUSED_RESULT;
268 :
269 : /* -------------------------------------------------------------------- */
270 : /* Reference counted file handle manager. Makes sharing file */
271 : /* handles more practical. */
272 : /* -------------------------------------------------------------------- */
273 :
274 : /** Information on a shared file */
275 : typedef struct
276 : {
277 : FILE *fp; /**< File pointer */
278 : int nRefCount; /**< Reference counter */
279 : int bLarge; /**< Whether fp must be interpreted as VSIFILE* */
280 : char *pszFilename; /**< Filename */
281 : char *pszAccess; /**< Access mode */
282 : } CPLSharedFileInfo;
283 :
284 : FILE CPL_DLL *CPLOpenShared(const char *, const char *, int);
285 : void CPL_DLL CPLCloseShared(FILE *);
286 : CPLSharedFileInfo CPL_DLL *CPLGetSharedList(int *);
287 : void CPL_DLL CPLDumpSharedList(FILE *);
288 : /*! @cond Doxygen_Suppress */
289 : void CPL_DLL CPLCleanupSharedFileMutex(void);
290 : /*! @endcond */
291 :
292 : /* -------------------------------------------------------------------- */
293 : /* DMS to Dec to DMS conversion. */
294 : /* -------------------------------------------------------------------- */
295 : double CPL_DLL CPLDMSToDec(const char *is);
296 : const char CPL_DLL *CPLDecToDMS(double dfAngle, const char *pszAxis,
297 : int nPrecision);
298 : double CPL_DLL CPLPackedDMSToDec(double);
299 : double CPL_DLL CPLDecToPackedDMS(double dfDec);
300 :
301 : CPLErr CPL_DLL CPLStringToComplex(const char *pszString, double *pdfReal,
302 : double *pdfImag);
303 :
304 : /* -------------------------------------------------------------------- */
305 : /* Misc other functions. */
306 : /* -------------------------------------------------------------------- */
307 : int CPL_DLL CPLUnlinkTree(const char *);
308 : int CPL_DLL CPLCopyFile(const char *pszNewPath, const char *pszOldPath);
309 : int CPL_DLL CPLCopyTree(const char *pszNewPath, const char *pszOldPath);
310 : int CPL_DLL CPLMoveFile(const char *pszNewPath, const char *pszOldPath);
311 : int CPL_DLL CPLSymlink(const char *pszOldPath, const char *pszNewPath,
312 : CSLConstList papszOptions);
313 : int CPL_DLL CPLGetRemainingFileDescriptorCount(void);
314 :
315 : /* -------------------------------------------------------------------- */
316 : /* Lock related functions. */
317 : /* -------------------------------------------------------------------- */
318 :
319 : /** Return code of CPLLockFileEx(). */
320 : typedef enum
321 : {
322 : CLFS_OK, /**< CPLLockFileEx() succeeded. */
323 : CLFS_CANNOT_CREATE_LOCK, /**< Lock file creation failed. */
324 : CLFS_LOCK_BUSY, /**< Lock already taken (and still alive). */
325 : CLFS_API_MISUSE, /**< API misuse. */
326 : CLFS_THREAD_CREATION_FAILED, /**< Thread creation failed. */
327 : } CPLLockFileStatus;
328 :
329 : /** Handle type returned by CPLLockFileEx(). */
330 : typedef struct CPLLockFileStruct *CPLLockFileHandle;
331 :
332 : CPLLockFileStatus CPL_DLL CPLLockFileEx(const char *pszLockFileName,
333 : CPLLockFileHandle *phLockFileHandle,
334 : CSLConstList papszOptions);
335 :
336 : void CPL_DLL CPLUnlockFileEx(CPLLockFileHandle hLockFileHandle);
337 :
338 : /* -------------------------------------------------------------------- */
339 : /* ZIP Creation. */
340 : /* -------------------------------------------------------------------- */
341 :
342 : /*! @cond Doxygen_Suppress */
343 : #define CPL_ZIP_API_OFFERED
344 : /*! @endcond */
345 : void CPL_DLL *CPLCreateZip(const char *pszZipFilename, char **papszOptions);
346 : CPLErr CPL_DLL CPLCreateFileInZip(void *hZip, const char *pszFilename,
347 : char **papszOptions);
348 : CPLErr CPL_DLL CPLWriteFileInZip(void *hZip, const void *pBuffer,
349 : int nBufferSize);
350 : CPLErr CPL_DLL CPLCloseFileInZip(void *hZip);
351 : CPLErr CPL_DLL CPLAddFileInZip(void *hZip, const char *pszArchiveFilename,
352 : const char *pszInputFilename, VSILFILE *fpInput,
353 : CSLConstList papszOptions,
354 : GDALProgressFunc pProgressFunc,
355 : void *pProgressData);
356 : CPLErr CPL_DLL CPLCloseZip(void *hZip);
357 :
358 : /* -------------------------------------------------------------------- */
359 : /* ZLib compression */
360 : /* -------------------------------------------------------------------- */
361 :
362 : void CPL_DLL *CPLZLibDeflate(const void *ptr, size_t nBytes, int nLevel,
363 : void *outptr, size_t nOutAvailableBytes,
364 : size_t *pnOutBytes);
365 : void CPL_DLL *CPLZLibInflate(const void *ptr, size_t nBytes, void *outptr,
366 : size_t nOutAvailableBytes, size_t *pnOutBytes);
367 : void CPL_DLL *CPLZLibInflateEx(const void *ptr, size_t nBytes, void *outptr,
368 : size_t nOutAvailableBytes,
369 : bool bAllowResizeOutptr, size_t *pnOutBytes);
370 :
371 : /* -------------------------------------------------------------------- */
372 : /* XML validation. */
373 : /* -------------------------------------------------------------------- */
374 : int CPL_DLL CPLValidateXML(const char *pszXMLFilename,
375 : const char *pszXSDFilename,
376 : CSLConstList papszOptions);
377 :
378 : /* -------------------------------------------------------------------- */
379 : /* Locale handling. Prevents parallel executions of setlocale(). */
380 : /* -------------------------------------------------------------------- */
381 : char *CPLsetlocale(int category, const char *locale);
382 : /*! @cond Doxygen_Suppress */
383 : void CPLCleanupSetlocaleMutex(void);
384 : /*! @endcond */
385 :
386 : /*!
387 : CPLIsPowerOfTwo()
388 : @param i - tested number
389 : @return TRUE if i is power of two otherwise return FALSE
390 : */
391 : int CPL_DLL CPLIsPowerOfTwo(unsigned int i);
392 :
393 : /* -------------------------------------------------------------------- */
394 : /* Terminal related */
395 : /* -------------------------------------------------------------------- */
396 :
397 : bool CPL_DLL CPLIsInteractive(FILE *f);
398 :
399 : CPL_C_END
400 :
401 : /* -------------------------------------------------------------------- */
402 : /* C++ object for temporarily forcing a LC_NUMERIC locale to "C". */
403 : /* -------------------------------------------------------------------- */
404 :
405 : //! @cond Doxygen_Suppress
406 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
407 :
408 : extern "C++"
409 : {
410 : class CPL_DLL CPLLocaleC
411 : {
412 : CPL_DISALLOW_COPY_ASSIGN(CPLLocaleC)
413 : public:
414 : CPLLocaleC();
415 : ~CPLLocaleC();
416 :
417 : private:
418 : char *pszOldLocale;
419 : };
420 :
421 : // Does the same as CPLLocaleC except that, when available, it tries to
422 : // only affect the current thread. But code that would be dependent of
423 : // setlocale(LC_NUMERIC, NULL) returning "C", such as current proj.4
424 : // versions, will not work depending on the actual implementation
425 : class CPLThreadLocaleCPrivate;
426 :
427 : class CPL_DLL CPLThreadLocaleC
428 : {
429 : CPL_DISALLOW_COPY_ASSIGN(CPLThreadLocaleC)
430 :
431 : public:
432 : CPLThreadLocaleC();
433 : ~CPLThreadLocaleC();
434 :
435 : private:
436 : CPLThreadLocaleCPrivate *m_private;
437 : };
438 : }
439 :
440 : #endif /* def __cplusplus */
441 : //! @endcond
442 :
443 : /* -------------------------------------------------------------------- */
444 : /* C++ object for temporarily forcing a config option */
445 : /* -------------------------------------------------------------------- */
446 :
447 : //! @cond Doxygen_Suppress
448 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
449 :
450 : extern "C++"
451 : {
452 : class CPL_DLL CPLConfigOptionSetter
453 : {
454 : CPL_DISALLOW_COPY_ASSIGN(CPLConfigOptionSetter)
455 : public:
456 : CPLConfigOptionSetter(const char *pszKey, const char *pszValue,
457 : bool bSetOnlyIfUndefined);
458 : ~CPLConfigOptionSetter();
459 :
460 : private:
461 : char *m_pszKey;
462 : char *m_pszOldValue;
463 : bool m_bRestoreOldValue;
464 : };
465 : }
466 :
467 : #endif /* def __cplusplus */
468 : //! @endcond
469 :
470 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
471 :
472 : extern "C++"
473 : {
474 :
475 : #ifndef DOXYGEN_SKIP
476 : #include <type_traits> // for std::is_base_of
477 : #endif
478 :
479 : namespace cpl
480 : {
481 : /** Use cpl::down_cast<Derived*>(pointer_to_base) as equivalent of
482 : * static_cast<Derived*>(pointer_to_base) with safe checking in debug
483 : * mode.
484 : *
485 : * Only works if no virtual inheritance is involved.
486 : *
487 : * @param f pointer to a base class
488 : * @return pointer to a derived class
489 : */
490 6862710 : template <typename To, typename From> inline To down_cast(From *f)
491 : {
492 : static_assert(
493 : (std::is_base_of<From,
494 : typename std::remove_pointer<To>::type>::value),
495 : "target type not derived from source type");
496 6862710 : CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
497 6862710 : return static_cast<To>(f);
498 : }
499 :
500 : /** Computes ceil(a/b) where a and b are integers */
501 208 : template <class T, class U> inline T div_round_up(T a, U b)
502 : {
503 208 : return a / b + (((a % b) == 0) ? 0 : 1);
504 : }
505 :
506 : } // namespace cpl
507 : } // extern "C++"
508 :
509 : #endif /* def __cplusplus */
510 :
511 : #endif /* ndef CPL_CONV_H_INCLUDED */
|