String view entry (#1147)

make entry support string_view in its interface, and make it efficient when in in C++14
This commit is contained in:
Arvid Norberg 2016-09-24 06:10:54 -07:00 committed by GitHub
parent b1b74657f6
commit 48a647a169
10 changed files with 97 additions and 67 deletions

View File

@ -1,3 +1,4 @@
* use string_view in entry interface
* deprecate "send_stats" property on trackers (since lt_tracker extension has
been removed)
* remove deprecate session_settings API (use settings_pack instead)

View File

@ -47,7 +47,7 @@ namespace libtorrent
struct TORRENT_EXPORT announce_entry
{
// constructs a tracker announce entry with ``u`` as the URL.
announce_entry(std::string const& u);
announce_entry(std::string u);
announce_entry();
~announce_entry();
announce_entry(announce_entry const&) = default;

View File

@ -240,7 +240,7 @@ namespace libtorrent
// tracker less torrent. It can be used by clients to bootstrap their DHT node from.
// The node is a hostname and a port number where there is a DHT node running.
// You can have any number of DHT nodes in a torrent.
void add_node(std::pair<std::string, int> const& node);
void add_node(std::pair<std::string, int> node);
// Adds a tracker to the torrent. This is not strictly required, but most torrents
// use a tracker as their main source of peers. The url should be an http:// or udp://

View File

@ -72,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/assert.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/span.hpp"
#include "libtorrent/string_view.hpp"
namespace libtorrent
{
@ -82,6 +83,21 @@ namespace libtorrent
#endif
struct bdecode_node;
#if __cplusplus > 201103
namespace aux
{
// this enables us to compare a string_view against the std::string that's
// held by the std::map
struct strview_less
{
using is_transparent = std::true_type;
template <typename T1, typename T2>
bool operator()(T1 const& rhs, T2 const& lhs) const
{ return rhs < lhs; }
};
};
#endif
// The ``entry`` class represents one node in a bencoded hierarchy. It works as a
// variant type, it can be either a list, a dictionary (``std::map``), an integer
// or a string.
@ -92,7 +108,11 @@ namespace libtorrent
// the key is always a string. If a generic entry would be allowed
// as a key, sorting would become a problem (e.g. to compare a string
// to a list). The definition doesn't mention such a limit though.
#if __cplusplus <= 201103
typedef std::map<std::string, entry> dictionary_type;
#else
typedef std::map<std::string, entry, aux::strview_less> dictionary_type;
#endif
typedef std::string string_type;
typedef std::vector<entry> list_type;
typedef std::int64_t integer_type;
@ -119,6 +139,7 @@ namespace libtorrent
entry(span<char const>);
template <typename U, typename Cond = typename std::enable_if<
std::is_same<U, entry::string_type>::value
|| std::is_same<U, string_view>::value
|| std::is_same<U, char const*>::value>::type>
entry(U v)
: m_type(undefined_t)
@ -250,21 +271,17 @@ namespace libtorrent
// The const version of ``operator[]`` will only return a reference to an
// existing element at the given key. If the key is not found, it will
// throw ``system_error``.
entry& operator[](char const* key);
entry& operator[](std::string const& key);
const entry& operator[](char const* key) const;
const entry& operator[](std::string const& key) const;
entry& operator[](string_view key);
const entry& operator[](string_view key) const;
// These functions requires the entry to be a dictionary, if it isn't
// they will throw ``system_error``.
//
// They will look for an element at the given key in the dictionary, if
// the element cannot be found, they will return 0. If an element with
// the given key is found, the return a pointer to it.
entry* find_key(char const* key);
entry const* find_key(char const* key) const;
entry* find_key(std::string const& key);
entry const* find_key(std::string const& key) const;
// the element cannot be found, they will return nullptr. If an element
// with the given key is found, the return a pointer to it.
entry* find_key(string_view key);
entry const* find_key(string_view key) const;
// returns a pretty-printed string representation
// of the bencoded structure, with JSON-style syntax

View File

@ -65,7 +65,7 @@ protected:
put_callback m_put_callback;
item m_data;
bool m_done;
bool m_done = false;
};
struct put_data_observer : traversal_observer

View File

@ -47,8 +47,8 @@ namespace libtorrent
tracker_retry_delay_max = 60 * 60
};
announce_entry::announce_entry(std::string const& u)
: url(u)
announce_entry::announce_entry(std::string u)
: url(std::move(u))
, fails(0)
, updating(false)
, source(0)

View File

@ -705,9 +705,9 @@ namespace libtorrent
m_filehashes[index] = h;
}
void create_torrent::add_node(std::pair<std::string, int> const& node)
void create_torrent::add_node(std::pair<std::string, int> node)
{
m_nodes.push_back(node);
m_nodes.emplace_back(std::move(node));
}
void create_torrent::add_url_seed(string_view url)

View File

@ -89,64 +89,52 @@ namespace libtorrent
}
}
entry& entry::operator[](char const* key)
entry& entry::operator[](string_view key)
{
#if __cplusplus <= 201103
dictionary_type::iterator i = dict().find(key.to_string());
#else
dictionary_type::iterator i = dict().find(key);
#endif
if (i != dict().end()) return i->second;
dictionary_type::iterator ret = dict().insert(
std::pair<const std::string, entry>(key, entry())).first;
std::make_pair(key.to_string(), entry())).first;
return ret->second;
}
entry& entry::operator[](std::string const& key)
{
dictionary_type::iterator i = dict().find(key);
if (i != dict().end()) return i->second;
dictionary_type::iterator ret = dict().insert(
std::make_pair(key, entry())).first;
return ret->second;
}
entry* entry::find_key(char const* key)
{
dictionary_type::iterator i = dict().find(key);
if (i == dict().end()) return nullptr;
return &i->second;
}
entry const* entry::find_key(char const* key) const
{
dictionary_type::const_iterator i = dict().find(key);
if (i == dict().end()) return nullptr;
return &i->second;
}
entry* entry::find_key(std::string const& key)
{
dictionary_type::iterator i = dict().find(key);
if (i == dict().end()) return nullptr;
return &i->second;
}
entry const* entry::find_key(std::string const& key) const
{
dictionary_type::const_iterator i = dict().find(key);
if (i == dict().end()) return nullptr;
return &i->second;
}
const entry& entry::operator[](char const* key) const
{
return (*this)[std::string(key)];
}
const entry& entry::operator[](std::string const& key) const
const entry& entry::operator[](string_view key) const
{
#if __cplusplus <= 201103
dictionary_type::const_iterator i = dict().find(key.to_string());
#else
dictionary_type::const_iterator i = dict().find(key);
#endif
if (i == dict().end()) throw_error();
return i->second;
}
entry* entry::find_key(string_view key)
{
#if __cplusplus <= 201103
dictionary_type::iterator i = dict().find(key.to_string());
#else
dictionary_type::iterator i = dict().find(key);
#endif
if (i == dict().end()) return nullptr;
return &i->second;
}
entry const* entry::find_key(string_view key) const
{
#if __cplusplus <= 201103
dictionary_type::const_iterator i = dict().find(key.to_string());
#else
dictionary_type::const_iterator i = dict().find(key);
#endif
if (i == dict().end()) return nullptr;
return &i->second;
}
entry::data_type entry::type() const
{
#if TORRENT_USE_ASSERTS

View File

@ -41,9 +41,7 @@ namespace libtorrent { namespace dht
put_data::put_data(node& dht_node, put_callback const& callback)
: traversal_algorithm(dht_node, (node_id::min)())
, m_put_callback(callback)
, m_done(false)
{
}
{}
char const* put_data::name() const { return "put_data"; }
@ -51,7 +49,7 @@ void put_data::start()
{
// router nodes must not be added to puts
init();
bool is_done = add_requests();
bool const is_done = add_requests();
if (is_done) done();
}
@ -66,7 +64,7 @@ void put_data::set_targets(std::vector<std::pair<node_entry, std::string>> const
#if TORRENT_USE_ASSERTS
o->m_in_constructor = false;
#endif
m_results.push_back(o);
m_results.push_back(std::move(o));
}
}

View File

@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "test.hpp"
#include "libtorrent/bdecode.hpp"
#include "libtorrent/entry.hpp"
using namespace libtorrent;
@ -51,6 +52,31 @@ TORRENT_TEST(integer)
TEST_EQUAL(e.int_value(), 12453);
}
TORRENT_TEST(construct_string)
{
entry e(std::string("abc123"));
TEST_EQUAL(e.string(), "abc123");
}
TORRENT_TEST(construct_string_literal)
{
entry e("abc123");
TEST_EQUAL(e.string(), "abc123");
}
TORRENT_TEST(construct_string_view)
{
entry e(string_view("abc123"));
TEST_EQUAL(e.string(), "abc123");
}
TORRENT_TEST(construct_integer)
{
entry e(4);
TEST_EQUAL(e.integer(), 4);
}
// test string
TORRENT_TEST(string)
{