[beast: 10/12] SFI: add vector_erase_element() and copy_reordered()
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 10/12] SFI: add vector_erase_element() and copy_reordered()
- Date: Sat, 30 Sep 2017 11:49:11 +0000 (UTC)
commit aed78b7a72ddfd71dbcd0104b9dc0ea28e12e678
Author: Tim Janik <timj gnu org>
Date: Mon Sep 25 23:24:35 2017 +0200
SFI: add vector_erase_element() and copy_reordered()
Signed-off-by: Tim Janik <timj gnu org>
sfi/bcore.hh | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
---
diff --git a/sfi/bcore.hh b/sfi/bcore.hh
index 9885070..51bc939 100644
--- a/sfi/bcore.hh
+++ b/sfi/bcore.hh
@@ -6,6 +6,7 @@
#include <sfi/platform.hh>
#include <sfi/strings.hh>
#include <sfi/glib-extra.hh>
+#include <algorithm>
namespace Bse {
@@ -45,6 +46,50 @@ inline bool debug_enabled (const char *conditiona
String feature_toggle_find (const String &config, const String &feature, const
String &fallback = "0");
bool feature_toggle_bool (const char *config, const char *feature);
+// == Small Utilities ==
+/// Erase element @a value from std::vector @a v if it's present.
+template<class V> bool
+vector_erase_element (V &v, const typename V::value_type &value)
+{
+ typename V::iterator it = std::find (v.begin(), v.end(), value);
+ if (it != v.end())
+ {
+ v.erase (it);
+ return true;
+ }
+ return false;
+}
+
+/// Copy @a unordered_first .. @a unordered_end into @a output_iterator in the order given by @a
ordered_first .. @a ordered_end.
+template<class InputIterator, class OutputIterator> OutputIterator
+copy_reordered (InputIterator const unordered_first, InputIterator const unordered_end,
+ InputIterator const ordered_first, InputIterator const ordered_end,
+ OutputIterator output_iterator)
+{
+ static_assert (std::is_same<std::random_access_iterator_tag,
+ typename std::iterator_traits<InputIterator>::iterator_category>::value,
+ "vector_copy_reordered() requires random access iterator as input");
+ std::vector<bool> taken;
+ taken.resize (unordered_end - unordered_first, false);
+ // insert all ordered_first.. elements if present in unordered_first..
+ for (InputIterator it = ordered_first; it != ordered_end; ++it)
+ {
+ InputIterator pos = std::find (unordered_first, unordered_end, *it);
+ while (pos != unordered_end && taken[pos - unordered_first])
+ pos = std::find (++pos, unordered_end, *it); // keep searching for dups
+ if (pos != unordered_end) // && !taken
+ {
+ taken[pos - unordered_first] = true;
+ *output_iterator++ = *it;
+ }
+ }
+ // insert all unordered_first.. elements not previously encountered
+ for (ssize_t i = 0; i < unordered_end - unordered_first; i++)
+ if (taken[i] == false)
+ *output_iterator++ = *(unordered_first + i);
+ return output_iterator;
+}
+
// == Binary Lookups ==
template<typename RandIter, class Cmp, typename Arg, int case_lookup_or_sibling_or_insertion>
extern inline std::pair<RandIter,bool>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]