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 * deprecate "send_stats" property on trackers (since lt_tracker extension has
been removed) been removed)
* remove deprecate session_settings API (use settings_pack instead) * remove deprecate session_settings API (use settings_pack instead)

View File

@ -47,7 +47,7 @@ namespace libtorrent
struct TORRENT_EXPORT announce_entry struct TORRENT_EXPORT announce_entry
{ {
// constructs a tracker announce entry with ``u`` as the URL. // 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();
announce_entry(announce_entry const&) = default; 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. // 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. // 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. // 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 // 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:// // 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/assert.hpp"
#include "libtorrent/error_code.hpp" #include "libtorrent/error_code.hpp"
#include "libtorrent/span.hpp" #include "libtorrent/span.hpp"
#include "libtorrent/string_view.hpp"
namespace libtorrent namespace libtorrent
{ {
@ -82,6 +83,21 @@ namespace libtorrent
#endif #endif
struct bdecode_node; 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 // 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 // variant type, it can be either a list, a dictionary (``std::map``), an integer
// or a string. // or a string.
@ -92,7 +108,11 @@ namespace libtorrent
// the key is always a string. If a generic entry would be allowed // 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 // 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. // to a list). The definition doesn't mention such a limit though.
#if __cplusplus <= 201103
typedef std::map<std::string, entry> dictionary_type; 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::string string_type;
typedef std::vector<entry> list_type; typedef std::vector<entry> list_type;
typedef std::int64_t integer_type; typedef std::int64_t integer_type;
@ -119,6 +139,7 @@ namespace libtorrent
entry(span<char const>); entry(span<char const>);
template <typename U, typename Cond = typename std::enable_if< template <typename U, typename Cond = typename std::enable_if<
std::is_same<U, entry::string_type>::value std::is_same<U, entry::string_type>::value
|| std::is_same<U, string_view>::value
|| std::is_same<U, char const*>::value>::type> || std::is_same<U, char const*>::value>::type>
entry(U v) entry(U v)
: m_type(undefined_t) : m_type(undefined_t)
@ -250,21 +271,17 @@ namespace libtorrent
// The const version of ``operator[]`` will only return a reference to an // 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 // existing element at the given key. If the key is not found, it will
// throw ``system_error``. // throw ``system_error``.
entry& operator[](char const* key); entry& operator[](string_view key);
entry& operator[](std::string const& key); const entry& operator[](string_view key) const;
const entry& operator[](char const* key) const;
const entry& operator[](std::string const& key) const;
// These functions requires the entry to be a dictionary, if it isn't // These functions requires the entry to be a dictionary, if it isn't
// they will throw ``system_error``. // they will throw ``system_error``.
// //
// They will look for an element at the given key in the dictionary, if // 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 element cannot be found, they will return nullptr. If an element
// the given key is found, the return a pointer to it. // with the given key is found, the return a pointer to it.
entry* find_key(char const* key); entry* find_key(string_view key);
entry const* find_key(char const* key) const; entry const* find_key(string_view key) const;
entry* find_key(std::string const& key);
entry const* find_key(std::string const& key) const;
// returns a pretty-printed string representation // returns a pretty-printed string representation
// of the bencoded structure, with JSON-style syntax // of the bencoded structure, with JSON-style syntax

View File

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

View File

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

View File

@ -705,9 +705,9 @@ namespace libtorrent
m_filehashes[index] = h; 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) 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); dictionary_type::iterator i = dict().find(key);
#endif
if (i != dict().end()) return i->second; if (i != dict().end()) return i->second;
dictionary_type::iterator ret = dict().insert( 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; return ret->second;
} }
entry& entry::operator[](std::string const& key) const entry& entry::operator[](string_view key) const
{
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
{ {
#if __cplusplus <= 201103
dictionary_type::const_iterator i = dict().find(key.to_string());
#else
dictionary_type::const_iterator i = dict().find(key); dictionary_type::const_iterator i = dict().find(key);
#endif
if (i == dict().end()) throw_error(); if (i == dict().end()) throw_error();
return i->second; 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 entry::data_type entry::type() const
{ {
#if TORRENT_USE_ASSERTS #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) put_data::put_data(node& dht_node, put_callback const& callback)
: traversal_algorithm(dht_node, (node_id::min)()) : traversal_algorithm(dht_node, (node_id::min)())
, m_put_callback(callback) , m_put_callback(callback)
, m_done(false) {}
{
}
char const* put_data::name() const { return "put_data"; } 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 // router nodes must not be added to puts
init(); init();
bool is_done = add_requests(); bool const is_done = add_requests();
if (is_done) done(); 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 #if TORRENT_USE_ASSERTS
o->m_in_constructor = false; o->m_in_constructor = false;
#endif #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 "test.hpp"
#include "libtorrent/bdecode.hpp" #include "libtorrent/bdecode.hpp"
#include "libtorrent/entry.hpp"
using namespace libtorrent; using namespace libtorrent;
@ -51,6 +52,31 @@ TORRENT_TEST(integer)
TEST_EQUAL(e.int_value(), 12453); 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 // test string
TORRENT_TEST(string) TORRENT_TEST(string)
{ {