]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/stdalgo.h
Merge the latest changes from insp20 into master.
[user/henk/code/inspircd.git] / include / stdalgo.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #pragma once
21
22 namespace stdalgo
23 {
24         namespace vector
25         {
26                 /**
27                  * Erase a single element from a vector by overwriting it with a copy of the last element,
28                  * which is then removed. This, in contrast to vector::erase(), does not result in all
29                  * elements after the erased element being moved.
30                  * @param vect Vector to remove the element from
31                  * @param it Iterator to the element to remove
32                  * @return Nothing, but all iterators, references and pointers to the erased element and the
33                  * last element are invalidated
34                  */
35                 template <typename T>
36                 inline void swaperase(typename std::vector<T>& vect, const typename std::vector<T>::iterator& it)
37                 {
38                         *it = vect.back();
39                         vect.pop_back();
40                 }
41
42                 /**
43                  * Find and if exists, erase a single element from a vector by overwriting it with a
44                  * copy of the last element, which is then removed. This, in contrast to vector::erase(),
45                  * does not result in all elements after the erased element being moved.
46                  * If the given value occurs multiple times, the one with the lowest index is removed.
47                  * Individual elements are compared to the given value using operator==().
48                  * @param vect Vector to remove the element from
49                  * @param val Value of the element to look for and remove
50                  * @return True if the element was found and removed, false if it wasn't found.
51                  * If true, all iterators, references and pointers pointing to either the first element that
52                  * is equal to val or to the last element are invalidated.
53                  */
54                 template <typename T>
55                 inline bool swaperase(typename std::vector<T>& vect, const T& val)
56                 {
57                         const typename std::vector<T>::iterator it = std::find(vect.begin(), vect.end(), val);
58                         if (it != vect.end())
59                         {
60                                 swaperase(vect, it);
61                                 return true;
62                         }
63                         return false;
64                 }
65         }
66
67         namespace string
68         {
69                 /** Get underlying C string of the string passed as parameter. Useful in template functions.
70                  * @param str C string
71                  * @return Same as input
72                  */
73                 inline const char* tocstr(const char* str)
74                 {
75                         return str;
76                 }
77
78                 /** Get underlying C string of the string passed as parameter. Useful in template functions.
79                  * @param str std::string object
80                  * @return str.c_str()
81                  */
82                 inline const char* tocstr(const std::string& str)
83                 {
84                         return str.c_str();
85                 }
86
87                 /** Check if two strings are equal case insensitively.
88                  * @param str1 First string to compare.
89                  * @param str2 Second string to compare.
90                  * @return True if the strings are equal case-insensitively, false otherwise.
91                  */
92                 template <typename S1, typename S2>
93                 inline bool equalsci(const S1& str1, const S2& str2)
94                 {
95                         return (!strcasecmp(tocstr(str1), tocstr(str2)));
96                 }
97
98                 /** Replace first occurrence of a substring ('target') in a string ('str') with another string ('replacement').
99                  * @param str String to perform replacement in
100                  * @param target String to replace
101                  * @param replacement String to put in place of 'target'
102                  * @return True if 'target' was replaced with 'replacement', false if it was not found in 'str'.
103                  */
104                 template<typename CharT, typename Traits, typename Alloc>
105                 inline bool replace(std::basic_string<CharT, Traits, Alloc>& str, const std::basic_string<CharT, Traits, Alloc>& target, const std::basic_string<CharT, Traits, Alloc>& replacement)
106                 {
107                         const typename std::basic_string<CharT, Traits, Alloc>::size_type p = str.find(target);
108                         if (p == std::basic_string<CharT, Traits, Alloc>::npos)
109                                 return false;
110                         str.replace(p, target.size(), replacement);
111                         return true;
112                 }
113
114                 /** Replace all occurrences of a string ('target') in a string ('str') with another string ('replacement').
115                  * @param str String to perform replacement in
116                  * @param target String to replace
117                  * @param replacement String to put in place of 'target'
118                  */
119                 template<typename CharT, typename Traits, typename Alloc>
120                 inline void replace_all(std::basic_string<CharT, Traits, Alloc>& str, const std::basic_string<CharT, Traits, Alloc>& target, const std::basic_string<CharT, Traits, Alloc>& replacement)
121                 {
122                         if (target.empty())
123                                 return;
124
125                         typename std::basic_string<CharT, Traits, Alloc>::size_type p = 0;
126                         while ((p = str.find(target, p)) != std::basic_string<CharT, Traits, Alloc>::npos)
127                         {
128                                 str.replace(p, target.size(), replacement);
129                                 p += replacement.size();
130                         }
131                 }
132         }
133
134         /**
135          * Deleter that uses operator delete to delete the item
136          */
137         template <typename T>
138         struct defaultdeleter
139         {
140                 void operator()(T* o)
141                 {
142                         delete o;
143                 }
144         };
145
146         /**
147          * Deleter that adds the item to the cull list, that is, queues it for
148          * deletion at the end of the current mainloop iteration
149          */
150         struct culldeleter
151         {
152                 void operator()(classbase* item);
153         };
154
155         /**
156          * Deletes all elements in a container using operator delete
157          * @param cont The container containing the elements to delete
158          */
159         template <template<typename, typename> class Cont, typename T, typename Alloc>
160         inline void delete_all(const Cont<T*, Alloc>& cont)
161         {
162                 std::for_each(cont.begin(), cont.end(), defaultdeleter<T>());
163         }
164
165         /**
166          * Remove an element from a container
167          * @param cont Container to remove the element from
168          * @param val Value of the element to look for and remove
169          * @return True if the element was found and removed, false otherwise
170          */
171         template <template<typename, typename> class Cont, typename T, typename Alloc>
172         inline bool erase(Cont<T, Alloc>& cont, const T& val)
173         {
174                 const typename Cont<T, Alloc>::iterator it = std::find(cont.begin(), cont.end(), val);
175                 if (it != cont.end())
176                 {
177                         cont.erase(it);
178                         return true;
179                 }
180                 return false;
181         }
182
183         /**
184          * Check if an element with the given value is in a container. Equivalent to (std::find(cont.begin(), cont.end(), val) != cont.end()).
185          * @param cont Container to find the element in
186          * @param val Value of the element to look for
187          * @return True if the element was found in the container, false otherwise
188          */
189         template <template<typename, typename> class Cont, typename T, typename Alloc>
190         inline bool isin(const Cont<T, Alloc>& cont, const T& val)
191         {
192                 return (std::find(cont.begin(), cont.end(), val) != cont.end());
193         }
194 }