Skip to content

Commit

Permalink
Add some general std::vector utility functions
Browse files Browse the repository at this point in the history
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 Cat function in bech32.cpp
  • Loading branch information
sipa authored and furszy committed Jun 28, 2021
1 parent 7a6f029 commit dc42563
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ BITCOIN_CORE_H = \
utilstrencodings.h \
utilmoneystr.h \
utiltime.h \
util/vector.h \
validation.h \
validationinterface.h \
version.h \
Expand Down
10 changes: 3 additions & 7 deletions src/bech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bech32.h"
#include "util/vector.h"

#include <assert.h>

namespace
{
Expand All @@ -24,13 +27,6 @@ const int8_t CHARSET_REV[128] = {
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
};

/** Concatenate two byte arrays. */
data Cat(data x, const data& y)
{
x.insert(x.end(), y.begin(), y.end());
return x;
}

/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to
* make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher
* bits correspond to earlier values. */
Expand Down
3 changes: 2 additions & 1 deletion src/txdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "uint256.h"
#include "util/system.h"
#include "zpiv/zerocoin.h"
#include <"til/vector.h"
#include <stdint.h>

Expand Down Expand Up @@ -113,7 +114,7 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap& mapCoins,
// A vector is used for future extensibility, as we may want to support
// interrupting after partial writes from multiple independent reorgs.
batch.Erase(DB_BEST_BLOCK);
batch.Write(DB_HEAD_BLOCKS, std::vector<uint256>{hashBlock, old_tip});
batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip));

for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
Expand Down
51 changes: 51 additions & 0 deletions src/util/vector.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit dc42563

Please sign in to comment.