aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2019-10-18 09:56:43 -0400
committerMarcoFalke <falke.marco@gmail.com>2019-10-18 09:57:00 -0400
commit0ff7cd7d0c074448db636bcc73e7879b7e4b21ec (patch)
tree8c6513a72dbdd555ce5350036b2e26a2a2e265ae /src/util
parentf2a094884d987465437a6300daa84de6f39c2322 (diff)
parent7d8d3e6a2ad827fa916e3909a18dedb9f7fdce43 (diff)
Merge #16889: Add some general std::vector utility functions
7d8d3e6a2ad827fa916e3909a18dedb9f7fdce43 Add tests for util/vector.h's Cat and Vector (Pieter Wuille) e65e61c812df90a56e3ce4a8e76c4b746766f387 Add some general std::vector utility functions (Pieter Wuille) Pull request description: This is another general improvement extracted from #16800 . Two functions are added are: * Vector(arg1,arg2,arg3,...) constructs a vector with the specified arguments as elements. The vector's type is derived from the arguments. If some of the arguments are rvalue references, they will be moved into place rather than copied (which can't be achieved using list initialization). * Cat(vector1,vector2) returns a concatenation of the two vectors, efficiently moving elements when relevant. Vector generalizes (and replaces) the `Singleton` function in src/descriptor.cpp, and `Cat` replaces the function in bech32.cpp ACKs for top commit: laanwj: ACK 7d8d3e6a2ad827fa916e3909a18dedb9f7fdce43 MarcoFalke: ACK 7d8d3e6a2ad827fa916e3909a18dedb9f7fdce43 (enjoyed reading the tests, but did not compile) Tree-SHA512: 92325f14e90d7e7d9d920421979aec22bb0d730e0291362b4326cccc76f9c2d865bec33a797c5c0201773468c3773cb50ce52c8eee4c1ec1a4d10db5cf2b9d2a
Diffstat (limited to 'src/util')
-rw-r--r--src/util/vector.h51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/util/vector.h b/src/util/vector.h
new file mode 100644
index 0000000000..dab65ded2a
--- /dev/null
+++ b/src/util/vector.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTIL_VECTOR_H
+#define BITCOIN_UTIL_VECTOR_H
+
+#include <initializer_list>
+#include <type_traits>
+#include <vector>
+
+/** Construct a vector with the specified elements.
+ *
+ * This is preferable over the list initializing constructor of std::vector:
+ * - It automatically infers the element type from its arguments.
+ * - If any arguments are rvalue references, they will be moved into the vector
+ * (list initialization always copies).
+ */
+template<typename... Args>
+inline std::vector<typename std::common_type<Args...>::type> Vector(Args&&... args)
+{
+ std::vector<typename std::common_type<Args...>::type> ret;
+ ret.reserve(sizeof...(args));
+ // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html
+ (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...};
+ return ret;
+}
+
+/** Concatenate two vectors, moving elements. */
+template<typename V>
+inline V Cat(V v1, V&& v2)
+{
+ v1.reserve(v1.size() + v2.size());
+ for (auto& arg : v2) {
+ v1.push_back(std::move(arg));
+ }
+ return v1;
+}
+
+/** Concatenate two vectors. */
+template<typename V>
+inline V Cat(V v1, const V& v2)
+{
+ v1.reserve(v1.size() + v2.size());
+ for (const auto& arg : v2) {
+ v1.push_back(arg);
+ }
+ return v1;
+}
+
+#endif // BITCOIN_UTIL_VECTOR_H