diff options
Diffstat (limited to 'butl/utility')
-rw-r--r-- | butl/utility | 264 |
1 files changed, 0 insertions, 264 deletions
diff --git a/butl/utility b/butl/utility deleted file mode 100644 index 673b715..0000000 --- a/butl/utility +++ /dev/null @@ -1,264 +0,0 @@ -// file : butl/utility -*- C++ -*- -// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUTL_UTILITY -#define BUTL_UTILITY - -#include <string> -#include <iosfwd> // ostream -#include <cstddef> // size_t -#include <utility> // move(), forward() -#include <cstring> // strcmp(), strlen() -#include <butl/ft/exception> // uncaught_exceptions -#include <exception> // exception, uncaught_exception(s)() -#include <butl/ft/lang> // thread_local - -//#include <functional> // hash - -#include <butl/export> - -namespace butl -{ - // Throw std::system_error with generic_category or system_category, - // respectively. - // - // The generic version should be used for portable errno codes (those that - // are mapped to std::errc). The system version should be used for platform- - // specific codes, for example, additional errno codes on POSIX systems or - // the result of GetLastError() on Windows. - // - // See also the exception sanitization below. - // - [[noreturn]] LIBBUTL_EXPORT void - throw_generic_error (int errno_code, const char* what = nullptr); - - [[noreturn]] LIBBUTL_EXPORT void - throw_system_error (int system_code, int fallback_errno_code = 0); - - // Convert ASCII character/string case. If there is no upper/lower case - // counterpart, leave the character unchanged. The POSIX locale (also known - // as C locale) must be the current application locale. Otherwise the - // behavior is undefined. - // - // Note that the POSIX locale specifies behaviour on data consisting - // entirely of characters from the portable character set (subset of ASCII - // including 103 non-negative characters and English alphabet letters in - // particular) and the control character set (more about them at - // http://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap06.html). - // - // Also note that according to the POSIX locale definition the case - // conversion can be applied only to [A-Z] and [a-z] character ranges being - // translated to each other (more about that at - // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap07.html#tag_07_02) - // - char ucase (char); - std::string ucase (const char*, std::size_t = std::string::npos); - std::string ucase (const std::string&); - std::string& ucase (std::string&); - void ucase (char*, std::size_t); - - char lcase (char); - std::string lcase (const char*, std::size_t = std::string::npos); - std::string lcase (const std::string&); - std::string& lcase (std::string&); - void lcase (char*, std::size_t); - - // Compare ASCII characters/strings ignoring case. Behave as if characters - // had been converted to the lower case and then byte-compared. Return a - // negative, zero or positive value if the left hand side is less, equal or - // greater than the right hand side, respectivelly. The POSIX locale (also - // known as C locale) must be the current application locale. Otherwise the - // behavior is undefined. - // - // The optional size argument specifies the maximum number of characters - // to compare. - // - int casecmp (char, char); - - int casecmp (const std::string&, const std::string&, - std::size_t = std::string::npos); - - int casecmp (const std::string&, const char*, - std::size_t = std::string::npos); - - int casecmp (const char*, const char*, std::size_t = std::string::npos); - - // Case-insensitive key comparators (i.e., to be used in sets, maps, etc). - // - struct case_compare_string - { - bool operator() (const std::string& x, const std::string& y) const - { - return casecmp (x, y) < 0; - } - }; - - struct case_compare_c_string - { - bool operator() (const char* x, const char* y) const - { - return casecmp (x, y) < 0; - } - }; - - bool - alpha (char); - - bool - digit (char); - - bool - alnum (char); - - // Key comparators (i.e., to be used in sets, maps, etc). - // - struct compare_c_string - { - bool operator() (const char* x, const char* y) const noexcept - { - return std::strcmp (x, y) < 0; - } - }; - - struct compare_pointer_target - { - template <typename P> - bool operator() (const P& x, const P& y) const {return *x < *y;} - }; - - //struct hash_pointer_target - //{ - // template <typename P> - // std::size_t operator() (const P& x) const {return std::hash (*x);} - //}; - - // Combine one or more hash values. - // - inline std::size_t - combine_hash (std::size_t s, std::size_t h) - { - // Magic formula from boost::hash_combine(). - // - return s ^ (h + 0x9e3779b9 + (s << 6) + (s >> 2)); - } - - template <typename... S> - inline std::size_t - combine_hash (std::size_t s, std::size_t h, S... hs) - { - return combine_hash (combine_hash (s, h), hs...); - } - - // Support for reverse iteration using range-based for-loop: - // - // for (... : reverse_iterate (x)) ... - // - template <typename T> - class reverse_range - { - T x_; - - public: - reverse_range (T&& x): x_ (std::forward<T> (x)) {} - - auto begin () const -> decltype (this->x_.rbegin ()) {return x_.rbegin ();} - auto end () const -> decltype (this->x_.rend ()) {return x_.rend ();} - }; - - template <typename T> - inline reverse_range<T> - reverse_iterate (T&& x) {return reverse_range<T> (std::forward<T> (x));} - - // Call a function if there is an exception. - // - - template <typename F> - struct exception_guard; - - template <typename F> - inline exception_guard<F> - make_exception_guard (F f) - { - return exception_guard<F> (std::move (f)); - } - -#ifdef __cpp_lib_uncaught_exceptions - template <typename F> - struct exception_guard - { - exception_guard (F f) - : f_ (std::move (f)), - u_ (std::uncaught_exceptions ()) {} - - ~exception_guard () - { - if (u_ != std::uncaught_exceptions ()) - f_ (); - } - - private: - F f_; - int u_; - }; -#else - // Fallback implementation using a TLS flag. - // - // True means we are in the body of a destructor that is being called as - // part of the exception stack unwindining. - // - extern -#ifdef __cpp_thread_local - thread_local -#else - __thread -#endif - bool exception_unwinding_dtor_; - - // On Windows one cannot export a thread-local variable so we have to - // use a wrapper functions. - // -#ifdef _WIN32 - LIBBUTL_EXPORT bool& - exception_unwinding_dtor (); -#else - inline bool& - exception_unwinding_dtor () {return exception_unwinding_dtor_;} -#endif - - template <typename F> - struct exception_guard - { - exception_guard (F f): f_ (std::move (f)) {} - ~exception_guard () - { - if (std::uncaught_exception ()) - { - exception_unwinding_dtor () = true; - f_ (); - exception_unwinding_dtor () = false; - } - } - - private: - F f_; - }; -#endif -} - -namespace std -{ - // Sanitize the exception description before printing. This includes: - // - // - stripping leading colons and spaces (see fdstream.cxx) - // - stripping trailing newlines, periods, and spaces - // - stripping system error redundant suffix (see utility.cxx) - // - lower-case the first letter if the beginning looks like a word - // - LIBBUTL_EXPORT ostream& - operator<< (ostream&, const exception&); -} - -#include <butl/utility.ixx> - -#endif // BUTL_UTILITY |