OSDN Git Service

41e118037f7d9b1b7ea12e7aaa8971c1b15a6e82
[mutilities/MUtilities.git] / include / MUtils / Global.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2019 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
21
22 /**
23  * @file
24  * @brief This file contains miscellaneous functions that are generally useful for Qt-based applications
25  */
26
27 #pragma once
28
29 #include <QString>
30
31 //Forward Declarations
32 class QProcess;
33 class QDir;
34 template<typename K, typename V> class QHash;
35
36 ///////////////////////////////////////////////////////////////////////////////
37
38 /** \cond INTERNAL
39  */
40
41  //Interface version
42 #define MUTILS_INTERFACE 2
43
44 //MUtils API
45 #ifdef _MSC_VER
46 #       ifdef MUTILS_DLL_EXPORT
47 #               define MUTILS_API __declspec(dllexport)
48 #       else
49 #               ifndef MUTILS_STATIC_LIB
50 #                       define MUTILS_API __declspec(dllimport)
51 #               else
52 #                       define MUTILS_API /*static lib*/
53 #               endif
54 #       endif
55 #else
56 #       define MUTILS_API
57 #endif
58
59 //Check Debug Flags
60 #if defined(_DEBUG) || defined(DEBUG) || (!defined(NDEBUG))
61 #       define MUTILS_DEBUG (1)
62 #       if defined(NDEBUG) || defined(QT_NO_DEBUG) || (!defined(QT_DEBUG))
63 #               error Inconsistent DEBUG flags have been detected!
64 #       endif
65 #else
66 #       define MUTILS_DEBUG (0)
67 #       if (!defined(NDEBUG)) || (!defined(QT_NO_DEBUG)) || defined(QT_DEBUG)
68 #               error Inconsistent DEBUG flags have been detected!
69 #       endif
70 #endif
71
72 //Check CPU options
73 #if defined(_MSC_VER) && (!defined(__INTELLISENSE__)) && (!defined(_M_X64)) && defined(_M_IX86_FP)
74         #if (_M_IX86_FP != 0)
75                 #error We should not enabled SSE or SSE2 in release builds!
76         #endif
77 #endif
78
79 //Library initializer
80 #define MUTILS_GLUE_NAME_HELPER(X,Y) X##Y
81 #define MUTILS_GLUE_NAME(X,Y) MUTILS_GLUE_NAME_HELPER(X,Y)
82 #if MUTILS_DEBUG
83 #define MUTILS_INITIALIZER MUTILS_GLUE_NAME(initialize_d, MUTILS_INTERFACE)
84 #else
85 #define MUTILS_INITIALIZER MUTILS_GLUE_NAME(initialize_r, MUTILS_INTERFACE)
86 #endif
87
88 //Compiler warnings
89 #define MUTILS_MAKE_STRING_HELPER(X) #X
90 #define MUTILS_MAKE_STRING(X) MUTILS_MAKE_STRING_HELPER(X)
91 #define MUTILS_COMPILER_WARNING(TXT) __pragma(message(__FILE__ "(" MUTILS_MAKE_STRING(__LINE__) ") : warning: " TXT))
92
93 /** \endcond INTERNAL
94  */
95
96 ///////////////////////////////////////////////////////////////////////////////
97
98 /**
99 * \brief Global MUtils namespace
100 */
101 namespace MUtils
102 {
103         /**
104         * \brief This struct containes the parts (integral and fractional part) of a floating-point number
105         */
106         typedef struct _fp_parts_t { double parts[2]; } fp_parts_t;
107
108         /**
109         * \brief Rerieves the full path of the application's *Temp* folder.
110         *
111         * The application's *Temp* folder is a unique application-specific folder, intended to store any temporary files that the application may need. It will be created when this function is called for the first time (lazy initialization); subsequent calls are guaranteed to return the same path. Usually the application's *Temp* folder will be created as a sub-folder of the system's global *Temp* folder, as indicated by the `TMP` or `TEMP` environment variables. However, it may be created at a different place (e.g. in the users *Profile* directory), if those environment variables don't point to a usable directory. In any case, this function makes sure that the application's *Temp* folder exists for the whole lifetime of the application and that it is writable. When the application terminates normally, the application's *Temp* folder and all files or sub-directories thereof will be *removed* automatically!
112         *
113         * \return If the function succeeds, it returns a read-only reference to a QString holding the full path of the application's *Temp* folder; otherwise a read-only reference to a default-constructed QString is returned.
114         */
115         MUTILS_API const QString& temp_folder(void);
116
117         /**
118         * \brief Initialize a given [QProcess](http://doc.qt.io/qt-4.8/qprocess.html) object.
119         *
120         * This function prepares a given [QProcess](http://doc.qt.io/qt-4.8/qprocess.html) object for sub-process creation. It does so by setting up combined *stdout* and *stderr* redirection for the sub-process, cleaning up the sub-process' environment variables, as well as setting up the sub-process' working directory. Optionally, the *Temp* directory for the sub-process can be set to the application-specific *Temp* directory, which is achieved by overwriting the corresponding environment variables (e.g. `TMP` and `TEMP`). Furthermore, additional paths can be added to the `PATH` environment variable of the sub-process.
121         *
122         * \param process A reference to the [QProcess](http://doc.qt.io/qt-4.8/qprocess.html) object to be initialized. The [QProcess](http://doc.qt.io/qt-4.8/qprocess.html) object must be initialized *before* calling the `QProcess::start()` method.
123         *
124         * \param process A read-only reference to a QString holding the path of the working directory for the sub-process.
125         *
126         * \param bReplaceTempDir If set to `true`, the *Temp* directory for the sub-process is set to the application-specific *Temp* directory; if set to `false`, the default *Temp* directory is retained.
127         *
128         * \param extraPaths A read-only pointer to a QStringList object containing additional paths that will be added (prepended) to the sub-process' `PATH` environment variable. This parameter can be `NULL`, in which case *no* additional paths are added.
129         */
130         MUTILS_API void init_process(QProcess &process, const QString &wokringDir, const bool bReplaceTempDir = true, const QStringList *const extraPaths = NULL, const QHash<QString, QString> *const extraEnv = NULL);
131
132         /**
133         * \brief Generates a *random* unsigned 32-Bit value.
134         *
135         * The *random* value is created using a "strong" PRNG of the underlying system, if possible. Otherwise a fallback PRNG is used. It is **not** required or useful to call `srand()` or `qsrand()` prior to using this function. If necessary, the seeding of the PRNG happen *automatically* on the first call.
136         *
137         * \return The function returns a *random* unsigned 32-Bit value.
138         */
139         MUTILS_API quint32 next_rand_u32(void);
140         MUTILS_API quint32 next_rand_u32(const quint32 max);
141
142         /**
143         * \brief Generates a *random* unsigned 64-Bit value.
144         *
145         * The *random* value is created using a "strong" PRNG of the underlying system, if possible. Otherwise a fallback PRNG is used. It is **not** required or useful to call `srand()` or `qsrand()` prior to using this function. If necessary, the seeding of the PRNG happen *automatically* on the first call.
146         *
147         * \return The function returns a *random* unsigned 64-Bit value.
148         */
149         MUTILS_API quint64 next_rand_u64(void);
150         
151         /**
152         * \brief Generates a *random* string.
153         *
154         * The random string is generated using the same PRNG as the `next_rand_u64()` function. The *random* bytes are converted to a hexadecimal string and, if necessary, zero-padded to a toal length of 16 or 32 characters. There is **no** `0x`-prefix included in the result.
155         *
156         * \param bLong If set to `true`, a "long" random string (32 characters) will be generated; if set to `false`, a "short" random string (16 characters) is generated.
157         *
158         * \return The function returns a QString holding a *random* hexadecimal string
159         */
160         MUTILS_API QString next_rand_str(const bool &bLong = false);
161
162         /**
163         * \brief Generates a temporary file name.
164         *
165         * The function generates a file name that contains a *random* component and that is guaranteed to **not** exist yet. The generated file name follows a `"<basedir>/<random>.<ext>"` pattern. This is useful (not only) for creating temporary files.
166         *
167         * \param basePath Specifies the "base" directory where the temporary file is supposed to be created. This must be a valid *existing* directory.
168         *
169         * \param extension Specifies the desired file extensions of the temporary file. Do **not** include a leading dot (`.`) character.
170         *
171         * \param placeholder If set to `true`, the function creates an empty "placeholder" file under the returned file name; if set to `false`, it does *not*.
172         *
173         * \return If the function succeeds, it returns a QString holding the full path of the temporary file; otherwise it returns a default-constructed QString.
174         */
175         MUTILS_API QString make_temp_file(const QString &basePath, const QString &extension, const bool placeholder = false);
176         MUTILS_API QString make_temp_file(const QDir    &basePath, const QString &extension, const bool placeholder = false);
177
178         /**
179         * \brief Generates a unique file name.
180         *
181         * The function generates a unique file name in the specified directory. The function guarantees that the returned file name does *not* exist yet. If necessary, a *counter* will be included in the file name in order to ensure its uniqueness.
182         *
183         * \param basePath Specifies the "base" directory where the unique file is supposed to be created. This must be a valid *existing* directory.
184         *
185         * \param baseName Specifies the desired "base" file name of the unique file. Do **not** include a file extension.
186         *
187         * \param extension Specifies the desired file extensions of the unique file. Do **not** include a leading dot (`.`) character.
188         *
189         * \param fancy If set to `true`, the unique file name is generated according to the `"<basedir>/<basename> (N).<ext>"` pattern; if set to `false`, it is generated according to the `"<basedir>/<basename>.XXXX.<ext>"` pattern. Also, if set to `true`, a counter is only included in the file name, if the file name *without* counter already exists; if set to `false`, a counter is always included. Finally, if set to `true`, the counter starts at **2** and is printed in decimal format; if set to `false`, the counter starts at **0** and is printed in zero-padded hexadecimal format.
190         *
191         * \return If the function succeeds, it returns a QString holding the full path of the unique file; otherwise it returns a default-constructed QString.
192         */
193         MUTILS_API QString make_unique_file(const QString &basePath, const QString &baseName, const QString &extension, const bool fancy = false, const bool placeholder = false);
194         MUTILS_API QString make_unique_file(const QDir    &basePath, const QString &baseName, const QString &extension, const bool fancy = false, const bool placeholder = false);
195
196         /**
197         * \brief Computes the *parity* of the given unsigned 32-Bit value
198         *
199         * \param value The 32-Bit unsigned value from which the parity is to be computed.
200         *
201         * \return The function returns `true`, if the number of **1** bits in the given value is *odd*; it returns `false`, if the number of **1** bits in the given value is *even*.
202         */
203         MUTILS_API bool parity(quint32 value);
204
205         /**
206         * \brief Deletes the specified file
207         *
208         * The function deletes the specified file, even if it has the "read only" flag set. If the file is currently locked (e.g. by another process), the function retries multiple times to delete the file before it fails.
209         *
210         * \param fileName The path to the file to be deleted. This should be a full path.
211         *
212         * \return The function returns `true`, if the file was deleted successfully or if the file doesn't exist; it returns `false`, if the file could *not* be deleted.
213         */
214         MUTILS_API bool remove_file(const QString &fileName);
215
216         /**
217         * \brief Recursively deletes the specified directory
218         *
219         * The function deletes the specified directory. In *recursive* mode, the directory will be removed including all of its files and sub-directories. Files are deleted using the `remove_file()` function.
220         *
221         * \param folderPath The path to the directory to be deleted. This should be a full path.
222         *
223         * \param recursive If set to `true` the function removes all files and sub-directories in the specified directory; if set to `false`, the function will *not* try to delete any files or sub-directories, which means that it will fail on non-empty directories.
224         *
225         * \return The function returns `true`, if the directory was deleted successfully or if the directory doesn't exist; it returns `false`, if the directory could *not* be deleted.
226         */
227         MUTILS_API bool remove_directory(const QString &folderPath, const bool &recursive);
228
229         /**
230         * \brief Remove *trailing* white-space characters
231         *
232         * The function removes all *trailing* white-space characters from the specified string. Leading white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
233         *
234         * \param str A reference to the QString object to be trimmed. This QString object will be modified directly.
235         *
236         * \return A reference to the trimmed QString object. This is the same QString object that was specified in the `str` parameter.
237         */
238         MUTILS_API QString& trim_right(QString &str);
239
240         /**
241         * \brief Remove *leading* white-space characters
242         *
243         * The function removes all *leading* white-space characters from the specified string. Trailing white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
244         *
245         * \param str A reference to the QString object to be trimmed. This QString object will be modified directly.
246         *
247         * \return A reference to the trimmed QString object. This is the same QString object that was specified in the `str` parameter.
248         */
249         MUTILS_API QString& trim_left(QString &str);
250
251         /**
252         * \brief Remove *trailing* white-space characters
253         *
254         * The function removes all *trailing* white-space characters from the specified string. Leading white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
255         *
256         * \param str A read-only reference to the QString object to be trimmed. The original QString object is *not* modified.
257         *
258         * \return A new QString object that equals the original QString object, except that it has all *trailing* white-space characters removed.
259         */
260         MUTILS_API QString trim_right(const QString &str);
261
262         /**
263         * \brief Remove *trailing* white-space characters
264         *
265         * The function removes all *leading* white-space characters from the specified string. Trailing white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
266         *
267         * \param str A read-only reference to the QString object to be trimmed. The original QString object is *not* modified.
268         *
269         * \return A new QString object that equals the original QString object, except that it has all *leading* white-space characters removed.
270         */
271         MUTILS_API QString trim_left(const QString &str);
272
273         /**
274         * \brief Sort a list of strings using "natural ordering" algorithm
275         *
276         * This function implements a sort algorithm that orders alphanumeric strings in the way a human being would. See [*Natural Order String Comparison*](http://sourcefrog.net/projects/natsort/) for details!
277         *
278         * \param list A reference to the QStringList object to be sorted. The list will be sorted "in place".
279         *
280         * \param bIgnoreCase If set to `true`, the list will be sorted disregarding the character case, i.e. upper-case and lower-case characters (of the same letter) are treated the same; if set to `false`, the character case *is* taken into account.
281         */
282         MUTILS_API void natural_string_sort(QStringList &list, const bool bIgnoreCase);
283
284         /**
285         * \brief Clean up a file name string
286         *
287         * This function ensures that the given string is a valid file (or directory) name. It does so by replacing any illegal characters, i.e. any characters *not* allowed in file names (which explicitly *includes* directory separators). Furthermore, the function will trim/remove specific characters that are *not* allowed directly at the beginning or end of a file name. Finally, the function takes care of special "reserved" file names that are forbidden by the file system. You can use this function to convert user inputs into a valid file name.
288         *
289         * \param name A read-only reference to the QString holding the original, potentially invalid file name.
290         *
291         * \param pretty If set to `true`, the function tries to generate a "pretty" file name from the given file name. Otherwise, the function simply replaces each forbidden file name character by an underscore character.
292         *
293         * \return The function returns a QString holding a valid file name. If, however, the input string was empty or contained only white-space characters, the returned sting can be empty.
294         */
295         MUTILS_API QString clean_file_name(const QString &name, const bool &pretty);
296
297         /**
298         * \brief Clean up a file path string
299         *
300         * This function ensures that the given string is a valid file (or directory) path. It does so by replacing any illegal characters, i.e. any characters *not* allowed in file paths. Directory separators are preserved, but they will be "canonicalized". Furthermore, in each path component, the function will trim/remove specific characters that are *not* allowed directly at the beginning or end of a path component. Finally, the function takes care of special "reserved" file names that are forbidden by the file system. You can use this function to convert user inputs into a valid file path.
301         *
302         * \param path A read-only reference to the QString holding the original, potentially invalid file path.
303         *
304         * \param pretty If set to `true`, the function tries to generate "pretty" file names from the given file names. Otherwise, the function simply replaces each forbidden file name character by an underscore character.
305         *
306         * \return The function returns a QString holding a valid file path. If, however, the input string was empty or contained only white-space characters, the returned sting can be empty.
307         */
308         MUTILS_API QString clean_file_path(const QString &path, const bool &pretty);
309
310         /**
311         * \brief Parse regular expression results
312         *
313         * This function tries to parses the result (capture) of a regular expression as an unsigned 32-Bit value. The given regular expression must contain at least *one* capture. Only the *first* capture is considered, additional captures are ignored.
314         *
315         * \param regexp A read-only reference to the [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) object whose result (capture) will be parsed. This [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) must already have been *successfully* matched against the respective input string, e.g. via `QRegExp::indexIn()`, prior to calling this function.
316         *
317         * \param value A reference to a variable of type `quint32`, where the unsigned 32-Bit representation of the result will be stored. The contents of this variable are *undefined*, if the function failed.
318         *
319         * \return The function returns `true`, if the regular expression's capture could be parsed successfully; it returns `false`, if the capture contains an invalid string or if there are insufficient captures in given the [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) object.
320         */
321         MUTILS_API bool regexp_parse_uint32(const QRegExp &regexp, quint32 &value);
322         MUTILS_API bool regexp_parse_int32(const QRegExp &regexp, qint32 &value);
323         MUTILS_API bool regexp_parse_uint32(const QRegExp &regexp, quint32 &value, const size_t &offset);
324         MUTILS_API bool regexp_parse_int32(const QRegExp &regexp, qint32 &value, const size_t &offset);
325
326         /**
327         * \brief Parse regular expression results
328         *
329         * This function tries to parses the results (captures) of a regular expression as unsigned 32-Bit values. The given regular expression must contain at least \p count captures. Only the *first* \p count captures are considered, additional captures are ignored.
330         *
331         * \param regexp A read-only reference to the [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) object whose results (captures) will be parsed. This [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) must already have been *successfully* matched against the respective input string, e.g. via `QRegExp::indexIn()`, prior to calling this function.
332         *
333         * \param value A pointer to an array of type `quint32`, where the unsigned 32-Bit representations of the results will be stored (the `n`-th result is stored at `value[n-1]`). The array must be at least \p count elements in length. The contents of this array are *undefined*, if the function failed.
334         *
335         * \param count Specifies the number of results (captures) in the given [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) object. The function tries to parse the first \p count captures and ignores any additional captures that may exist. This parameter also determines the required (minimum) length of the \p value array.
336         *
337         * \return The function returns `true`, if all of the regular expression's captures could be parsed successfully; it returns `false`, if any of the captures contain an invalid string or if there are insufficient captures in given the [QRegExp](http://doc.qt.io/qt-4.8/qregexp.html) object.
338         */
339         MUTILS_API bool regexp_parse_uint32(const QRegExp &regexp, quint32 *values, const size_t &count);
340         MUTILS_API bool regexp_parse_int32(const QRegExp &regexp, qint32 *values, const size_t &count);
341         MUTILS_API bool regexp_parse_uint32(const QRegExp &regexp, quint32 *values, const size_t &offset, const size_t &count);
342         MUTILS_API bool regexp_parse_int32(const QRegExp &regexp, qint32 *values, const size_t &offset, const size_t &count);
343
344         /**
345         * \brief Retrieve a list of all available codepages
346         *
347         * The function generates a list of all codepages that are available on the system. Each codepage name returned by this function may be passed to the `QTextCodec::codecForName()` function in order to obtain a corresponding [QTextCodec](http://doc.qt.io/qt-4.8/qtextcodec.html) object.
348         *
349         * \param noAliases If set to `true`, only distinct codepages are returned, i.e. any codepage aliases are discarded from the list; if set to `false`, the returned list may (and usually will) also contain codepage aliases.
350         *
351         * \return If the function succeeds, it returns a QStringList holding the names of all codepages available on the system; otherwise it returns a default-constructed QStringList.
352         */
353         MUTILS_API QStringList available_codepages(const bool &noAliases = true);
354
355         /**
356         * \brief Break floating-point number into fractional and integral parts
357         *
358         * The function returns a struct containing the fractional and the integral part of a given floating-point values as two separate values. This is a convenience warapper for the `modf()` function.
359         *
360         * \param value The original floating-point value
361         *
362         * \return Returns a struct containing the fractional and integral parts.
363         */
364         MUTILS_API fp_parts_t break_fp(const double value);
365
366         //Internal (do *not* call directly!)
367         namespace Internal
368         {
369                 MUTILS_API unsigned int MUTILS_INITIALIZER(const unsigned int interfaceId);
370                 static const unsigned int init_flag = MUTILS_INITIALIZER(MUTILS_INTERFACE);
371         }
372 }
373
374 ///////////////////////////////////////////////////////////////////////////////
375
376 /** \brief Deletes the object, if and only if the given pointer is *not* NULL. Also sets pointer to NULL after object has been deleted.
377 */
378 #define MUTILS_DELETE(PTR) do { if((PTR)) { delete (PTR); (PTR) = NULL; } } while(0)
379
380 /** \brief Deletes the array, if and only if the given pointer is *not* NULL. Also sets pointer to NULL after array has been deleted.
381 */
382 #define MUTILS_DELETE_ARRAY(PTR) do { if((PTR)) { delete [] (PTR); (PTR) = NULL; } } while(0)
383
384 /** \brief Clears the specified variable or struct by setting all of its bytes to *zero* (`0x00`). Do **not** use for arrays.
385 */
386 #define MUTILS_ZERO_MEMORY(PTR) memset(&(PTR), 0, sizeof((PTR)))
387
388 /** \brief Converts a given QString object to a `wchar_t*` pointer. Does **not** copy the string data, so do **not** free the pointer! The returned pointer only remains valid until the underlying QString is modified or goes out of scope.
389 */
390 #define MUTILS_WCHR(STR) (reinterpret_cast<const wchar_t*>((STR).utf16()))
391
392 /** \brief Converts a given QString object to a `char*` pointer. The string is converted to UTF-8 encoding. The pointer is valid *only* while the expression is being evaluated, so do **not** free or store this pointer! Mainly useful for function calls that require a `char*` argument.
393 */
394 #define MUTILS_UTF8(STR) ((STR).toUtf8().constData())
395
396 /** \brief Converts a given QString object to a `char*` pointer. The string is converted to Latin-1 encoding. The pointer is valid *only* while the expression is being evaluated, so do **not** free or store this pointer! Mainly useful for function calls that require a `char*` argument.
397 */
398 #define MUTILS_L1STR(STR) ((STR).toLatin1().constData())
399
400 /** \brief Creates a QString object from a given `wchar_t*` buffer. The buffer is expected to conatin a NULL-terminated string in UTF-16 encoding. The string data is copied into the new QString object, however the original buffer will **not** be freed automatically!
401 */
402 #define MUTILS_QSTR(STR) (QString::fromUtf16(reinterpret_cast<const unsigned short*>((STR))))
403
404 /** \brief Converts a boolean expression into a string. A *true* boolean expression is converted to the string `"1"`; a *false* boolean expression is converted to the string `"0"`.
405 */
406 #define MUTILS_BOOL2STR(X) ((X) ? "1" : "0")
407
408 /** \brief Converts a given expression into a boolean expression, by application of double negation operator.
409 */
410 #define MUTILS_BOOLIFY(X) (!(!(X)))
411
412 /** \brief Get length of an array, only works with local array variables!
413 */
414 #define MUTILS_ARR2LEN(X) (sizeof((X)) / sizeof((X)[0]))
415
416 /** \brief Disables copy constructor and assignment operator in the specified class. This macro should be used in the "private" section of the class' declaration.
417 */
418 #define MUTILS_NO_COPY(CLASS) \
419         CLASS(const CLASS &) { throw "Copy constructor is disabled!"; } \
420         CLASS &operator=(const CLASS &) { throw "Assignment operator is disabled!"; }