The Battle for Wesnoth  1.17.23+dev
general.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2023
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include <algorithm>
18 #include <cctype>
19 #include <functional>
20 #include <string>
21 
22 namespace utils
23 {
24 inline bool chars_equal_insensitive(char a, char b) { return tolower(a) == tolower(b); }
25 inline bool chars_less_insensitive(char a, char b) { return tolower(a) < tolower(b); }
26 
27 /**
28  * Equivalent to as @c std::is_same_v except both types are passed through std::decay first.
29  *
30  * @tparam T1 The first type to compare.
31  * @tparam T2 The second type to compare.
32  */
33 template<typename T1, typename T2>
34 inline constexpr bool decayed_is_same = std::is_same_v<std::decay_t<T1>, std::decay_t<T2>>;
35 
36 /**
37  * Workaround for the fact that static_assert(false) is invalid.
38  * See https://devblogs.microsoft.com/oldnewthing/20200311-00/?p=103553
39  */
40 template<typename>
41 inline constexpr bool dependent_false_v = false;
42 
43 namespace detail
44 {
45 /**
46  * A struct that exists to implement a generic wrapper for std::find.
47  * Container should "look like" an STL container of Values.
48  */
49 template<typename Container, typename Value>
51 {
52  static bool eval(const Container& container, const Value& value)
53  {
54  typename Container::const_iterator end = container.end();
55  return std::find(container.begin(), end, value) != end;
56  }
57 };
58 
59 /**
60  * A struct that exists to implement a generic wrapper for the find()
61  * member of associative containers.
62  * Container should "look like" an STL associative container.
63  */
64 template<typename Container>
65 struct contains_impl<Container, typename Container::key_type>
66 {
67  static bool eval(const Container& container, const typename Container::key_type& value)
68  {
69  return container.find(value) != container.end();
70  }
71 };
72 
73 } // namespace detail
74 
75 /**
76  * Returns true iff @a value is found in @a container.
77  *
78  * This should work whenever Container "looks like" an STL container of Values.
79  * Normally this uses std::find(), but a simulated partial template specialization
80  * exists when Value is Container::key_type. In this case, Container is assumed
81  * an associative container, and the member function find() is used.
82  */
83 template<typename Container, typename Value>
84 inline bool contains(const Container& container, const Value& value)
85 {
86  return detail::contains_impl<Container, Value>::eval(container, value);
87 }
88 
89 /**
90  * Utility function for finding the type of thing caught with `catch(...)`.
91  * Not implemented for other compilers at this time.
92  *
93  * @return For the GCC/clang compilers, the unmangled name of an unknown exception that was caught.
94  */
95 std::string get_unknown_exception_type();
96 
97 /**
98  * Convenience wrapper for using std::remove_if on a container.
99  *
100  * todoc++20 use C++20's std::erase_if instead. The C++20 function returns the number of elements
101  * removed; this one could do that but it seems unnecessary to add it unless something is using it.
102  */
103 template<typename Container, typename Predicate>
104 void erase_if(Container& container, const Predicate& predicate)
105 {
106  container.erase(std::remove_if(container.begin(), container.end(), predicate), container.end());
107 }
108 
109 /**
110  * Convenience wrapper for using std::sort on a container.
111  *
112  */
113 template<typename Container, typename Predicate>
114 void sort_if(Container& container, const Predicate& predicate)
115 {
116  std::sort(container.begin(), container.end(), predicate);
117 }
118 
119 } // namespace utils
constexpr bool decayed_is_same
Equivalent to as std::is_same_v except both types are passed through std::decay first.
Definition: general.hpp:34
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:84
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
bool chars_equal_insensitive(char a, char b)
Definition: general.hpp:24
void erase_if(Container &container, const Predicate &predicate)
Convenience wrapper for using std::remove_if on a container.
Definition: general.hpp:104
constexpr bool dependent_false_v
Workaround for the fact that static_assert(false) is invalid.
Definition: general.hpp:41
bool chars_less_insensitive(char a, char b)
Definition: general.hpp:25
void sort_if(Container &container, const Predicate &predicate)
Convenience wrapper for using std::sort on a container.
Definition: general.hpp:114
static bool eval(const Container &container, const typename Container::key_type &value)
Definition: general.hpp:67
A struct that exists to implement a generic wrapper for std::find.
Definition: general.hpp:51
static bool eval(const Container &container, const Value &value)
Definition: general.hpp:52
#define a
#define b