PLaSK library

Loading...
Searching...
No Matches
stl.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
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, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK__UTILS_STL_H
15#define PLASK__UTILS_STL_H
16
21#include <algorithm>
22#include <cstddef> // for std::size_t
23
24 namespace plask {
25
33 template <typename map_t>
34 inline typename map_t::mapped_type map_find(map_t& map, const typename map_t::key_type& to_find, typename map_t::mapped_type&& if_not_found = nullptr) {
35 auto f = map.find(to_find);
36 return f == map.end() ? std::forward<typename map_t::mapped_type>(if_not_found) : f->second;
37}
38
39/*
40 * Try find value in (const) map by key and return @a if_not_found value if object was not found.
41 * @param map map to find in it
42 * @param to_find key to find
43 * @param if_not_found value to return when there is no object with @a to_find key in @a map
44 * @return founded object or @a if_not_found value
45 */
46/*template <typename map_t>
47 inline const typename map_t::mapped_type map_find(const map_t& map, const typename map_t::key_type& to_find, const typename map_t::mapped_type&& if_not_found = nullptr) {
48 auto f = map.find(to_find);
49 return f == map.end() ? std::forward<const typename map_t::mapped_type>(if_not_found) : f->second;
50}*/
51
59 template <typename Iter, typename Val>
60 inline Iter find_nearest_using_lower_bound(Iter begin, Iter end, const Val& to_find, Iter lower_bound) {
61 if (lower_bound == begin) return lower_bound; //before first
62 if (lower_bound == end) return lower_bound-1; //after last
63 Iter lo_candidate = lower_bound - 1;
64 //now: *lo_candidate <= to_find < *lower_bound
65 if (to_find - *lo_candidate <= *lower_bound - to_find) //nearest to *lo_candidate?
66 return lo_candidate;
67 else
68 return lower_bound;
69}
70
77 template <typename Iter, typename Val>
78 inline Iter find_nearest_binary(Iter begin, Iter end, const Val& to_find) {
79 return find_nearest_using_lower_bound(begin, end, to_find, std::lower_bound(begin, end, to_find));
80}
81
82 template <typename... Types>
83 struct VariadicTemplateTypesHolder {};
84
92 template <typename ForwadIterator>
93std::ostream& printRange(std::ostream& out, ForwadIterator begin, ForwadIterator end, const char* separator = ", ") {
94 if (begin != end) {
95 out << *begin;
96 for (++begin ; begin != end; ++begin)
97 out << separator << *begin;
98 }
99 return out;
100}
101
110 template <typename T>
111 struct AssignWithBackup {
112 T& original;
113 T store;
114
115 template <typename... ConstructorArgsT>
116 AssignWithBackup(T& varible_to_back, ConstructorArgsT&&... newValueCtrArgs)
117 : original(varible_to_back), store(std::forward<ConstructorArgsT>(newValueCtrArgs)...) {
118 std::swap(varible_to_back, store);
119 }
120
121 ~AssignWithBackup() { std::swap(original, store); }
122};
123
125
126
127#include <cstddef>
128#include <tuple>
129#include <type_traits>
130
131//===================================================================
132
133 template <std::size_t...>
134 struct indices { };
135
136//===================================================================
137
138 template <
139 std::size_t Begin,
140 std::size_t End,
141 typename Indices
142>
143 struct make_seq_indices_impl;
144
145 template <
146 std::size_t Begin,
147 std::size_t End,
148 std::size_t... Indices
149>
150 struct make_seq_indices_impl<Begin, End, indices<Indices...>>
151{
152 using type =
153 typename
154 make_seq_indices_impl<Begin+1, End,indices<Indices..., Begin>
155 >::type
156 ;
157};
158
159 template <std::size_t End, std::size_t... Indices>
160 struct make_seq_indices_impl<End, End, indices<Indices...>>
161{
162 using type = indices<Indices...>;
163};
164
165 template <std::size_t Begin, std::size_t End>
166 using make_seq_indices =
167 typename make_seq_indices_impl<Begin, End, indices<>>::type;
168
169//===================================================================
170
171 template <typename F>
172 using return_type = typename std::result_of<F>::type;
173
174 template <typename Tuple>
175 constexpr std::size_t tuple_size()
176{
177 return std::tuple_size<typename std::decay<Tuple>::type>::value;
178}
179
180// No definition exists for the next prototype...
181 template <
182 typename Op,
183 typename T,
184 template <std::size_t...> class I, std::size_t... Indices
185>
186 constexpr auto apply_tuple_return_type_impl(
187 Op&& op,
188 T&& t,
189 I<Indices...>
190) ->
191 return_type<Op(
192 decltype(std::get<Indices>(std::forward<T>(t)))...
193 )>
194;
195
196// No definition exists for the next prototype...
197 template <typename Op, typename T>
198 constexpr auto apply_tuple_return_type(Op&& op, T&& t) ->
199 decltype(apply_tuple_return_type_impl(
200 op, t, make_seq_indices<0,tuple_size<T>()>{}
201 ));
202
203 template <
204 typename Ret, typename Op, typename T,
205 template <std::size_t...> class I, std::size_t... Indices
206>
207 inline Ret apply_tuple(Op&& op, T&& t, I<Indices...>)
208{
209 return op(std::get<Indices>(std::forward<T>(t))...);
210}
211
218 template <typename Op, typename Tuple>
219 inline auto apply_tuple(Op&& op, Tuple&& t)
220 -> decltype(apply_tuple_return_type(
221 std::forward<Op>(op), std::forward<Tuple>(t)
222 ))
223{
224 return
225 apply_tuple<
226 decltype(apply_tuple_return_type(
227 std::forward<Op>(op), std::forward<Tuple>(t)
228 ))
229 >(
230 std::forward<Op>(op), std::forward<Tuple>(t),
231 make_seq_indices<0,tuple_size<Tuple>()>{}
232 );
233 ;
234} //http://preney.ca/paul/archives/934
235
236
240 template <typename T>
241 struct DontCopyThisField: public T {
242
243 /*template <typename... Args>
244 DontCopyThisField(Args&&... args) noexcept(noexcept(T(::std::forward<Args>(args)...)))
245 : T(::std::forward<Args>(args)...)
246 {}*/
247
248 DontCopyThisField() = default;
249
250 DontCopyThisField(const DontCopyThisField<T>&) noexcept: T() {}
251
252 DontCopyThisField(const T&) noexcept {}
253
254 DontCopyThisField(DontCopyThisField&& from) = default;
255
256 DontCopyThisField(T&& from) noexcept(noexcept(T(::std::move(from))))
257 : T(::std::move(from))
258 {}
259
260 DontCopyThisField& operator=(const T&) noexcept {
261 return *this;
262 }
263
264 DontCopyThisField& operator=(const DontCopyThisField&) noexcept {
265 return *this;
266 }
267
268 DontCopyThisField& operator=(T&& from) noexcept(noexcept(T::operator=(::std::move(from)))) {
269 T::operator=(::std::move(from));
270 return *this;
271 }
272
273 DontCopyThisField& operator=(DontCopyThisField&& from) = default;
274};
275
276
277} // namespace plask
278
279#endif // PLASK__STL_H