make move constructors and move assignment operators noexcept

This commit is contained in:
arvidn 2017-05-28 07:14:58 -04:00 committed by Arvid Norberg
parent 48bb1d2c95
commit 6967d17a42
34 changed files with 400 additions and 205 deletions

View File

@ -13,8 +13,8 @@ struct bytes
bytes(std::string const& s): arr(s) {}
bytes(std::string&& s): arr(std::move(s)) {}
bytes(bytes const&) = default;
bytes(bytes&&) = default;
bytes& operator=(bytes&&) = default;
bytes(bytes&&) noexcept = default;
bytes& operator=(bytes&&) noexcept = default;
bytes() {}
std::string arr;
};

View File

@ -11,6 +11,7 @@
#include "libtorrent/units.hpp"
#include "libtorrent/sha1_hash.hpp"
#include "libtorrent/disk_interface.hpp" // for open_file_state
#include "libtorrent/aux_/noexcept_movable.hpp"
#include <vector>
using namespace boost::python;
@ -70,9 +71,10 @@ struct pair_to_tuple
}
};
template <typename Addr>
struct address_to_tuple
{
static PyObject* convert(lt::address const& addr)
static PyObject* convert(Addr const& addr)
{
lt::error_code ec;
return incref(bp::object(addr.to_string(ec)).ptr());
@ -145,7 +147,7 @@ struct dict_to_map
template<class T>
struct vector_to_list
{
static PyObject* convert(const std::vector<T>& v)
static PyObject* convert(T const& v)
{
list l;
for (int i = 0; i < int(v.size()); ++i)
@ -162,7 +164,7 @@ struct list_to_vector
list_to_vector()
{
converter::registry::push_back(
&convertible, &construct, type_id<std::vector<T>>()
&convertible, &construct, type_id<T>()
);
}
@ -174,17 +176,17 @@ struct list_to_vector
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
{
void* storage = ((converter::rvalue_from_python_storage<
std::vector<T>>*)data)->storage.bytes;
T>*)data)->storage.bytes;
std::vector<T> p;
T p;
int const size = int(PyList_Size(x));
p.reserve(size);
for (int i = 0; i < size; ++i)
{
object o(borrowed(PyList_GetItem(x, i)));
p.push_back(extract<T>(o));
p.push_back(extract<typename T::value_type>(o));
}
std::vector<T>* ptr = new (storage) std::vector<T>();
T* ptr = new (storage) T();
ptr->swap(p);
data->convertible = storage;
}
@ -234,22 +236,39 @@ void bind_converters()
to_python_converter<std::pair<lt::piece_index_t, int>, pair_to_tuple<lt::piece_index_t, int>>();
to_python_converter<lt::tcp::endpoint, endpoint_to_tuple<lt::tcp::endpoint>>();
to_python_converter<lt::udp::endpoint, endpoint_to_tuple<lt::udp::endpoint>>();
to_python_converter<lt::address, address_to_tuple>();
to_python_converter<lt::address, address_to_tuple<lt::address>>();
to_python_converter<std::pair<std::string, int>, pair_to_tuple<std::string, int>>();
to_python_converter<std::vector<lt::stats_metric>, vector_to_list<lt::stats_metric>>();
to_python_converter<std::vector<lt::open_file_state>, vector_to_list<lt::open_file_state>>();
to_python_converter<std::vector<lt::sha1_hash>, vector_to_list<lt::sha1_hash>>();
to_python_converter<std::vector<std::string>, vector_to_list<std::string>>();
to_python_converter<std::vector<int>, vector_to_list<int>>();
to_python_converter<std::vector<std::uint8_t>, vector_to_list<std::uint8_t>>();
to_python_converter<std::vector<lt::tcp::endpoint>, vector_to_list<lt::tcp::endpoint>>();
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<lt::udp::endpoint>>();
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::pair<std::string, int>>>();
to_python_converter<std::vector<lt::stats_metric>, vector_to_list<std::vector<lt::stats_metric>>>();
to_python_converter<std::vector<lt::open_file_state>, vector_to_list<std::vector<lt::open_file_state>>>();
to_python_converter<std::vector<lt::sha1_hash>, vector_to_list<std::vector<lt::sha1_hash>>>();
to_python_converter<std::vector<std::string>, vector_to_list<std::vector<std::string>>>();
to_python_converter<std::vector<int>, vector_to_list<std::vector<int>>>();
to_python_converter<std::vector<std::uint8_t>, vector_to_list<std::vector<std::uint8_t>>>();
to_python_converter<std::vector<lt::tcp::endpoint>, vector_to_list<std::vector<lt::tcp::endpoint>>>();
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<std::vector<lt::udp::endpoint>>>();
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::vector<std::pair<std::string, int>>>>();
to_python_converter<lt::piece_index_t, from_strong_typedef<lt::piece_index_t>>();
to_python_converter<lt::file_index_t, from_strong_typedef<lt::file_index_t>>();
// work-around types
to_python_converter<lt::aux::noexcept_movable<lt::address>, address_to_tuple<
lt::aux::noexcept_movable<lt::address>>>();
to_python_converter<lt::aux::noexcept_movable<lt::tcp::endpoint>, endpoint_to_tuple<
lt::aux::noexcept_movable<lt::tcp::endpoint>>>();
to_python_converter<lt::aux::noexcept_movable<lt::udp::endpoint>, endpoint_to_tuple<
lt::aux::noexcept_movable<lt::udp::endpoint>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::stats_metric>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::stats_metric>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::open_file_state>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::open_file_state>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::sha1_hash>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::sha1_hash>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<std::string>>, vector_to_list<lt::aux::noexcept_movable<std::vector<std::string>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<int>>, vector_to_list<lt::aux::noexcept_movable<std::vector<int>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<std::uint8_t>>, vector_to_list<lt::aux::noexcept_movable<std::vector<std::uint8_t>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>>();
to_python_converter<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>, vector_to_list<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>>>();
// python -> C++ conversions
tuple_to_pair<int, int>();
tuple_to_pair<std::string, int>();
@ -257,12 +276,20 @@ void bind_converters()
tuple_to_endpoint<lt::udp::endpoint>();
tuple_to_pair<lt::piece_index_t, int>();
dict_to_map<lt::file_index_t, std::string>();
list_to_vector<int>();
list_to_vector<std::uint8_t>();
list_to_vector<std::string>();
list_to_vector<lt::tcp::endpoint>();
list_to_vector<lt::udp::endpoint>();
list_to_vector<std::pair<std::string, int>>();
list_to_vector<std::vector<int>>();
list_to_vector<std::vector<std::uint8_t>>();
list_to_vector<std::vector<std::string>>();
list_to_vector<std::vector<lt::tcp::endpoint>>();
list_to_vector<std::vector<lt::udp::endpoint>>();
list_to_vector<std::vector<std::pair<std::string, int>>>();
// work-around types
list_to_vector<lt::aux::noexcept_movable<std::vector<int>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<std::uint8_t>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<std::string>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>();
list_to_vector<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>>();
to_strong_typedef<lt::piece_index_t>();
to_strong_typedef<lt::file_index_t>();

View File

@ -207,6 +207,7 @@ nobase_include_HEADERS = \
aux_/typed_span.hpp \
aux_/array.hpp \
aux_/ip_notifier.hpp \
aux_/noexcept_movable.hpp \
\
extensions/smart_ban.hpp \
extensions/ut_metadata.hpp \

View File

@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bitfield.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/units.hpp"
#include "libtorrent/aux_/noexcept_movable.hpp"
namespace libtorrent {
@ -85,9 +86,9 @@ namespace libtorrent {
// which determines the storage mechanism for the downloaded or seeding
// data for the torrent. For more information, see the ``storage`` field.
explicit add_torrent_params(storage_constructor_type sc = default_storage_constructor)
: storage(sc) {}
add_torrent_params(add_torrent_params&&) = default;
add_torrent_params& operator=(add_torrent_params&&) = default;
: storage(storage_constructor_type(sc)) {}
add_torrent_params(add_torrent_params&&) noexcept = default;
add_torrent_params& operator=(add_torrent_params&&) noexcept = default;
add_torrent_params(add_torrent_params const&) = default;
add_torrent_params& operator=(add_torrent_params const&) = default;
@ -285,18 +286,18 @@ namespace libtorrent {
// If the torrent doesn't have a tracker, but relies on the DHT to find
// peers, the ``trackers`` can specify tracker URLs for the torrent.
std::vector<std::string> trackers;
aux::noexcept_movable<std::vector<std::string>> trackers;
// the tiers the URLs in ``trackers`` belong to. Trackers belonging to
// different tiers may be treated differently, as defined by the multi
// tracker extension. This is optional, if not specified trackers are
// assumed to be part of tier 0, or whichever the last tier was as
// iterating over the trackers.
std::vector<int> tracker_tiers;
aux::noexcept_movable<std::vector<int>> tracker_tiers;
// a list of hostname and port pairs, representing DHT nodes to be added
// to the session (if DHT is enabled). The hostname may be an IP address.
std::vector<std::pair<std::string, int>> dht_nodes;
aux::noexcept_movable<std::vector<std::pair<std::string, int>>> dht_nodes;
std::string name;
@ -321,7 +322,11 @@ namespace libtorrent {
// or encrypt the content on disk for instance. For more information
// about the storage_interface that needs to be implemented for a custom
// storage, see storage_interface.
#ifdef __clang__
storage_constructor_type storage;
#else
aux::noexcept_movable<storage_constructor_type> storage;
#endif
// The ``userdata`` parameter is optional and will be passed on to the
// extension constructor functions, if any
@ -331,7 +336,7 @@ namespace libtorrent {
// can be set to control the initial file priorities when adding a
// torrent. The semantics are the same as for
// ``torrent_handle::prioritize_files()``.
std::vector<std::uint8_t> file_priorities;
aux::noexcept_movable<std::vector<std::uint8_t>> file_priorities;
// torrent extension construction functions can be added to this vector
// to have them be added immediately when the torrent is constructed.
@ -339,7 +344,7 @@ namespace libtorrent {
// to avoid race conditions. For instance it may be important to have the
// plugin catch events that happen very early on after the torrent is
// created.
std::vector<std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>>
aux::noexcept_movable<std::vector<std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>>>
extensions;
// the default tracker id to be used when announcing to trackers. By
@ -434,20 +439,20 @@ namespace libtorrent {
//
// url_seeds expects URLs to regular web servers, aka "get right" style,
// specified in `BEP 19`_.
std::vector<std::string> http_seeds;
std::vector<std::string> url_seeds;
aux::noexcept_movable<std::vector<std::string>> http_seeds;
aux::noexcept_movable<std::vector<std::string>> url_seeds;
// peers to add to the torrent, to be tried to be connected to as
// bittorrent peers.
std::vector<tcp::endpoint> peers;
aux::noexcept_movable<std::vector<tcp::endpoint>> peers;
// peers banned from this torrent. The will not be connected to
std::vector<tcp::endpoint> banned_peers;
aux::noexcept_movable<std::vector<tcp::endpoint>> banned_peers;
// this is a map of partially downloaded piece. The key is the piece index
// and the value is a bitfield where each bit represents a 16 kiB block.
// A set bit means we have that block.
std::map<piece_index_t, bitfield> unfinished_pieces;
aux::noexcept_movable<std::map<piece_index_t, bitfield>> unfinished_pieces;
// this is a bitfield indicating which pieces we already have of this
// torrent.
@ -462,16 +467,16 @@ namespace libtorrent {
// element in the vector represent the piece with the same index. If you
// set both file- and piece priorities, file priorities will take
// precedence.
std::vector<std::uint8_t> piece_priorities;
aux::noexcept_movable<std::vector<std::uint8_t>> piece_priorities;
// if this is a merkle tree torrent, and you're seeding, this field must
// be set. It is all the hashes in the binary tree, with the root as the
// first entry. See torrent_info::set_merkle_tree() for more info.
std::vector<sha1_hash> merkle_tree;
aux::noexcept_movable<std::vector<sha1_hash>> merkle_tree;
// this is a map of file indices in the torrent and new filenames to be
// applied before the torrent is added.
std::map<file_index_t, std::string> renamed_files;
aux::noexcept_movable<std::map<file_index_t, std::string>> renamed_files;
#ifndef TORRENT_NO_DEPRECATE
// deprecated in 1.2
@ -501,7 +506,7 @@ namespace libtorrent {
// torrent_handle. See fast-resume_. The ``vector`` that is passed in
// will be swapped into the running torrent instance with
// ``std::vector::swap()``.
std::vector<char> TORRENT_DEPRECATED_MEMBER resume_data;
aux::noexcept_movable<std::vector<char>> TORRENT_DEPRECATED_MEMBER resume_data;
// to support the deprecated use case of reading the resume data into
// resume_data field and getting a reject alert, any parse failure is
@ -514,11 +519,24 @@ namespace libtorrent {
std::string deprecated5;
std::string deprecated1;
std::string deprecated2;
std::vector<char> deprecated3;
aux::noexcept_movable<std::vector<char>> deprecated3;
error_code deprecated4;
#endif
};
static_assert(std::is_nothrow_move_constructible<add_torrent_params>::value
, "should be nothrow move constructible");
// TODO: pre C++17, GCC and msvc does not make std::string nothrow move
// assignable, which means no type containing a string will be nothrow move
// assignable by default either
// static_assert(std::is_nothrow_move_assignable<add_torrent_params>::value
// , "should be nothrow move assignable");
// TODO: it would be nice if this was nothrow default constructible
// static_assert(std::is_nothrow_default_constructible<add_torrent_params>::value
// , "should be nothrow default constructible");
}
#endif

View File

@ -76,7 +76,7 @@ namespace libtorrent {
alert(alert const& rhs) = delete;
alert& operator=(alert const&) = delete;
alert(alert&& rhs) = default;
alert(alert&& rhs) noexcept = default;
#ifndef TORRENT_NO_DEPRECATE
// only here for backwards compatibility

View File

@ -52,6 +52,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/escape_string.hpp" // for convert_from_native
#include "libtorrent/string_view.hpp"
#include "libtorrent/stack_allocator.hpp"
#include "libtorrent/aux_/noexcept_movable.hpp"
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/shared_array.hpp>
@ -72,7 +73,7 @@ namespace libtorrent {
{
// internal
torrent_alert(aux::stack_allocator& alloc, torrent_handle const& h);
torrent_alert(torrent_alert&&) = default;
torrent_alert(torrent_alert&&) noexcept = default;
// internal
static const int alert_type = 0;
@ -103,7 +104,7 @@ namespace libtorrent {
// internal
peer_alert(aux::stack_allocator& alloc, torrent_handle const& h,
tcp::endpoint const& i, peer_id const& pi);
peer_alert(peer_alert&&) = default;
peer_alert(peer_alert&& rhs) noexcept = default;
static const int alert_type = 1;
static const int static_category = alert::peer_notification;
@ -111,14 +112,14 @@ namespace libtorrent {
virtual std::string message() const override;
// The peer's IP address and port.
tcp::endpoint const endpoint;
aux::noexcept_movable<tcp::endpoint> endpoint;
// the peer ID, if known.
peer_id const pid;
peer_id pid;
#ifndef TORRENT_NO_DEPRECATE
// The peer's IP address and port.
tcp::endpoint const ip;
aux::noexcept_movable<tcp::endpoint> ip;
#endif
};
@ -144,11 +145,11 @@ namespace libtorrent {
std::string TORRENT_DEPRECATED_MEMBER url;
#endif
private:
aux::allocation_slot const m_url_idx;
aux::allocation_slot m_url_idx;
};
#define TORRENT_DEFINE_ALERT_IMPL(name, seq, prio) \
name(name&&) = default; \
name(name&&) noexcept = default; \
static const int priority = prio; \
static const int alert_type = seq; \
virtual int type() const override { return alert_type; } \
@ -200,7 +201,7 @@ namespace libtorrent {
TORRENT_DEFINE_ALERT_PRIO(torrent_removed_alert, 4)
static const int static_category = alert::status_notification;
virtual std::string message() const override;
sha1_hash const info_hash;
sha1_hash info_hash;
};
// This alert is posted when the asynchronous read operation initiated by
@ -272,7 +273,7 @@ namespace libtorrent {
// refers to the index of the file that was renamed,
file_index_t const index;
private:
aux::allocation_slot const m_name_idx;
aux::allocation_slot m_name_idx;
};
// This is posted as a response to a torrent_handle::rename_file() call, if the rename
@ -446,7 +447,7 @@ namespace libtorrent {
char const* error_message() const;
private:
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_msg_idx;
};
// This alert is triggered if the tracker reply contains a warning field.
@ -472,7 +473,7 @@ namespace libtorrent {
char const* warning_message() const;
private:
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_msg_idx;
};
// This alert is generated when a scrape request succeeds.
@ -523,7 +524,7 @@ namespace libtorrent {
char const* error_message() const;
private:
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_msg_idx;
};
// This alert is only for informational purpose. It is generated when a tracker announce
@ -891,7 +892,7 @@ namespace libtorrent {
char const* storage_path() const;
private:
aux::allocation_slot const m_path_idx;
aux::allocation_slot m_path_idx;
};
// The ``storage_moved_failed_alert`` is generated when an attempt to move the storage,
@ -922,7 +923,7 @@ namespace libtorrent {
// terminated string naming which one, otherwise it's nullptr.
char const* operation;
private:
aux::allocation_slot const m_file_idx;
aux::allocation_slot m_file_idx;
};
// This alert is generated when a request to delete the files of a torrent complete.
@ -945,7 +946,7 @@ namespace libtorrent {
static const int static_category = alert::storage_notification;
virtual std::string message() const override;
sha1_hash const info_hash;
sha1_hash info_hash;
};
// This alert is generated when a request to delete the files of a torrent fails.
@ -966,7 +967,7 @@ namespace libtorrent {
error_code const error;
// the info hash of the torrent whose files failed to be deleted
sha1_hash const info_hash;
sha1_hash info_hash;
#ifndef TORRENT_NO_DEPRECATE
std::string TORRENT_DEPRECATED_MEMBER msg;
@ -1094,8 +1095,8 @@ namespace libtorrent {
char const* error_message() const;
private:
aux::allocation_slot const m_url_idx;
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_url_idx;
aux::allocation_slot m_msg_idx;
};
// If the storage fails to read or write files that it needs access to, this alert is
@ -1129,7 +1130,7 @@ namespace libtorrent {
std::string TORRENT_DEPRECATED_MEMBER msg;
#endif
private:
aux::allocation_slot const m_file_idx;
aux::allocation_slot m_file_idx;
};
// This alert is generated when the metadata has been completely received and the info-hash
@ -1205,7 +1206,7 @@ namespace libtorrent {
virtual std::string message() const override;
// the source address associated with the error (if any)
udp::endpoint const endpoint;
aux::noexcept_movable<udp::endpoint> endpoint;
// the error code describing the error
error_code const error;
@ -1226,7 +1227,7 @@ namespace libtorrent {
virtual std::string message() const override;
// the IP address that is believed to be our external IP
address const external_address;
aux::noexcept_movable<address> external_address;
};
enum class socket_type_t : std::uint8_t
@ -1295,7 +1296,7 @@ namespace libtorrent {
// the address libtorrent attempted to listen on
// see alert's documentation for validity of this value
libtorrent::address const address;
aux::noexcept_movable<libtorrent::address> address;
// the port libtorrent attempted to listen on
// see alert's documentation for validity of this value
@ -1303,7 +1304,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
// the address and port libtorrent attempted to listen on
tcp::endpoint endpoint;
aux::noexcept_movable<tcp::endpoint> endpoint;
// the type of listen socket this alert refers to.
socket_type_t sock_type;
@ -1311,7 +1312,7 @@ namespace libtorrent {
private:
std::reference_wrapper<aux::stack_allocator const> m_alloc;
aux::allocation_slot const m_interface_idx;
aux::allocation_slot m_interface_idx;
};
// This alert is posted when the listen port succeeds to be opened on a
@ -1344,7 +1345,7 @@ namespace libtorrent {
// the address libtorrent ended up listening on. This address
// refers to the local interface.
libtorrent::address const address;
aux::noexcept_movable<libtorrent::address> address;
// the port libtorrent ended up listening on.
int const port;
@ -1355,7 +1356,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
// the endpoint libtorrent ended up listening on. The address
// refers to the local interface and the port is the listen port.
tcp::endpoint endpoint;
aux::noexcept_movable<tcp::endpoint> endpoint;
// the type of listen socket this alert refers to.
socket_type_t sock_type;
@ -1458,7 +1459,7 @@ namespace libtorrent {
// TODO: 2 should the alert baseclass have this object instead?
std::reference_wrapper<aux::stack_allocator const> m_alloc;
aux::allocation_slot const m_log_idx;
aux::allocation_slot m_log_idx;
};
// This alert is generated when a fastresume file has been passed to
@ -1477,7 +1478,7 @@ namespace libtorrent {
| alert::error_notification;
virtual std::string message() const override;
error_code const error;
error_code error;
#ifndef TORRENT_NO_DEPRECATE
// If the error happened to a specific file, ``file`` is the path to it.
@ -1495,7 +1496,7 @@ namespace libtorrent {
std::string TORRENT_DEPRECATED_MEMBER msg;
#endif
private:
aux::allocation_slot const m_path_idx;
aux::allocation_slot m_path_idx;
};
// This alert is posted when an incoming peer connection, or a peer that's about to be added
@ -1546,9 +1547,9 @@ namespace libtorrent {
static const int static_category = alert::dht_notification;
virtual std::string message() const override;
address const ip;
int const port;
sha1_hash const info_hash;
aux::noexcept_movable<address> ip;
int port;
sha1_hash info_hash;
};
// This alert is generated when a DHT node sends a ``get_peers`` message to
@ -1563,7 +1564,7 @@ namespace libtorrent {
static const int static_category = alert::dht_notification;
virtual std::string message() const override;
sha1_hash const info_hash;
sha1_hash info_hash;
};
// This alert is posted approximately once every second, and it contains
@ -1657,8 +1658,8 @@ namespace libtorrent {
};
// specifies what error this is, see kind_t.
int const kind;
std::string const str;
int kind;
std::string str;
};
// This alert is generated when we receive a local service discovery message
@ -1698,7 +1699,7 @@ namespace libtorrent {
char const* tracker_id() const;
private:
aux::allocation_slot const m_tracker_idx;
aux::allocation_slot m_tracker_idx;
};
// This alert is posted when the initial DHT bootstrap is done.
@ -1737,7 +1738,7 @@ namespace libtorrent {
char const* filename() const;
private:
aux::allocation_slot const m_file_idx;
aux::allocation_slot m_file_idx;
};
// This is always posted for SSL torrents. This is a reminder to the client that
@ -1792,11 +1793,11 @@ namespace libtorrent {
int const socket_type;
// is the IP address and port the connection came from.
tcp::endpoint const endpoint;
aux::noexcept_movable<tcp::endpoint> endpoint;
#ifndef TORRENT_NO_DEPRECATE
// is the IP address and port the connection came from.
tcp::endpoint const ip;
aux::noexcept_movable<tcp::endpoint> TORRENT_DEPRECATED_MEMBER ip;
#endif
};
@ -1817,10 +1818,10 @@ namespace libtorrent {
// a copy of the parameters used when adding the torrent, it can be used
// to identify which invocation to ``async_add_torrent()`` caused this alert.
add_torrent_params const params;
add_torrent_params params;
// set to the error, if one occurred while adding the torrent.
error_code const error;
error_code error;
};
// This alert is only posted when requested by the user, by calling
@ -1843,7 +1844,7 @@ namespace libtorrent {
// to a specific torrent via its ``handle`` member. The receiving end is
// suggested to have all torrents sorted by the torrent_handle or hashed
// by it, for efficient updates.
std::vector<torrent_status> const status;
std::vector<torrent_status> status;
};
#ifndef TORRENT_NO_DEPRECATE
@ -1943,7 +1944,7 @@ namespace libtorrent {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
struct TORRENT_DEPRECATED TORRENT_EXPORT torrent_update_alert final : torrent_alert
struct TORRENT_DEPRECATED_EXPORT torrent_update_alert final : torrent_alert
{
// internal
torrent_update_alert(aux::stack_allocator& alloc, torrent_handle h
@ -1979,7 +1980,7 @@ namespace libtorrent {
virtual std::string message() const override;
// the error code
error_code const error;
error_code error;
enum op_t
{
@ -2006,10 +2007,10 @@ namespace libtorrent {
// the target hash of the immutable item. This must
// match the sha-1 hash of the bencoded form of ``item``.
sha1_hash const target;
sha1_hash target;
// the data for this item
entry const item;
entry item;
};
// this alert is posted as a response to a call to session::get_item(),
@ -2026,27 +2027,27 @@ namespace libtorrent {
virtual std::string message() const override;
// the public key that was looked up
std::array<char, 32> const key;
std::array<char, 32> key;
// the signature of the data. This is not the signature of the
// plain encoded form of the item, but it includes the sequence number
// and possibly the hash as well. See the dht_store document for more
// information. This is primarily useful for echoing back in a store
// request.
std::array<char, 64> const signature;
std::array<char, 64> signature;
// the sequence number of this item
std::int64_t const seq;
std::int64_t seq;
// the salt, if any, used to lookup and store this item. If no
// salt was used, this is an empty string
std::string const salt;
std::string salt;
// the data for this item
entry const item;
entry item;
// the last response for mutable data is authoritative.
bool const authoritative;
bool authoritative;
};
// this is posted when a DHT put operation completes. This is useful if the
@ -2068,20 +2069,20 @@ namespace libtorrent {
// the target hash the item was stored under if this was an *immutable*
// item.
sha1_hash const target;
sha1_hash target;
// if a mutable item was stored, these are the public key, signature,
// salt and sequence number the item was stored under.
std::array<char, 32> const public_key;
std::array<char, 64> const signature;
std::string const salt;
std::int64_t const seq;
std::array<char, 32> public_key;
std::array<char, 64> signature;
std::string salt;
std::int64_t seq;
// DHT put operation usually writes item to k nodes, maybe the node
// is stale so no response, or the node doesn't support 'put', or the
// token for write is out of date, etc. num_success is the number of
// successful responses we got from the puts.
int const num_success;
int num_success;
};
// this alert is used to report errors in the i2p SAM connection
@ -2095,7 +2096,7 @@ namespace libtorrent {
virtual std::string message() const override;
// the error that occurred in the i2p SAM connection
error_code const error;
error_code error;
};
// This alert is generated when we send a get_peers request
@ -2113,18 +2114,18 @@ namespace libtorrent {
virtual std::string message() const override;
// the info_hash of the torrent we're looking for peers for.
sha1_hash const info_hash;
sha1_hash info_hash;
// if this was an obfuscated lookup, this is the info-hash target
// actually sent to the node.
sha1_hash const obfuscated_info_hash;
sha1_hash obfuscated_info_hash;
// the endpoint we're sending this query to
udp::endpoint const endpoint;
aux::noexcept_movable<udp::endpoint> endpoint;
#ifndef TORRENT_NO_DEPRECATE
// the endpoint we're sending this query to
udp::endpoint ip;
aux::noexcept_movable<udp::endpoint> TORRENT_DEPRECATED_MEMBER ip;
#endif
};
@ -2154,7 +2155,7 @@ namespace libtorrent {
private:
std::reference_wrapper<aux::stack_allocator const> m_alloc;
aux::allocation_slot const m_str_idx;
aux::allocation_slot m_str_idx;
};
// This alert is posted by torrent wide events. It's meant to be used for
@ -2182,7 +2183,7 @@ namespace libtorrent {
#endif
private:
aux::allocation_slot const m_str_idx;
aux::allocation_slot m_str_idx;
};
// This alert is posted by events specific to a peer. It's meant to be used
@ -2217,7 +2218,7 @@ namespace libtorrent {
// message name.
char const* event_type;
direction_t const direction;
direction_t direction;
// returns the log message
char const* log_message() const;
@ -2229,7 +2230,7 @@ namespace libtorrent {
#endif
private:
aux::allocation_slot const m_str_idx;
aux::allocation_slot m_str_idx;
};
// posted if the local service discovery socket fails to start properly.
@ -2245,7 +2246,7 @@ namespace libtorrent {
virtual std::string message() const override;
// The error code
error_code const error;
error_code error;
};
// holds statistics about a current dht_lookup operation.
@ -2322,11 +2323,11 @@ namespace libtorrent {
virtual std::string message() const override;
// a vector of the currently running DHT lookups.
std::vector<dht_lookup> const active_requests;
std::vector<dht_lookup> active_requests;
// contains information about every bucket in the DHT routing
// table.
std::vector<dht_routing_bucket> const routing_table;
std::vector<dht_routing_bucket> routing_table;
};
// posted every time an incoming request from a peer is accepted and queued
@ -2346,7 +2347,7 @@ namespace libtorrent {
virtual std::string message() const override;
// the request this peer sent to us
peer_request const req;
peer_request req;
};
struct TORRENT_EXPORT dht_log_alert final : alert
@ -2372,11 +2373,11 @@ namespace libtorrent {
char const* log_message() const;
// the module, or part, of the DHT that produced this log message.
dht_module_t const module;
dht_module_t module;
private:
std::reference_wrapper<aux::stack_allocator const> m_alloc;
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_msg_idx;
};
// This alert is posted every time a DHT message is sent or received. It is
@ -2402,19 +2403,19 @@ namespace libtorrent {
span<char const> pkt_buf() const;
// whether this is an incoming or outgoing packet.
direction_t const direction;
direction_t direction;
// the DHT node we received this packet from, or sent this packet to
// (depending on ``direction``).
udp::endpoint const node;
aux::noexcept_movable<udp::endpoint> node;
#ifndef TORRENT_NO_DEPRECATE
direction_t const dir;
direction_t TORRENT_DEPRECATED_MEMBER dir;
#endif
private:
std::reference_wrapper<aux::stack_allocator> m_alloc;
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_msg_idx;
int const m_size;
};
@ -2429,7 +2430,7 @@ namespace libtorrent {
virtual std::string message() const override;
sha1_hash const info_hash;
sha1_hash info_hash;
int num_peers() const;
@ -2464,17 +2465,17 @@ namespace libtorrent {
virtual std::string message() const override;
void const* userdata;
udp::endpoint const endpoint;
aux::noexcept_movable<udp::endpoint> endpoint;
bdecode_node response() const;
#ifndef TORRENT_NO_DEPRECATE
udp::endpoint const addr;
aux::noexcept_movable<udp::endpoint> TORRENT_DEPRECATED_MEMBER addr;
#endif
private:
std::reference_wrapper<aux::stack_allocator> m_alloc;
aux::allocation_slot const m_response_idx;
aux::allocation_slot m_response_idx;
int const m_response_size;
};
@ -2522,7 +2523,7 @@ namespace libtorrent {
std::vector<piece_block> blocks() const;
private:
aux::allocation_slot const m_array_idx;
aux::allocation_slot m_array_idx;
int const m_num_blocks;
};
@ -2544,7 +2545,7 @@ namespace libtorrent {
private:
std::reference_wrapper<aux::stack_allocator> m_alloc;
aux::allocation_slot const m_msg_idx;
aux::allocation_slot m_msg_idx;
};
struct TORRENT_EXPORT dht_live_nodes_alert final : alert
@ -2558,7 +2559,7 @@ namespace libtorrent {
static const int static_category = alert::dht_notification;
virtual std::string message() const override;
sha1_hash const node_id;
sha1_hash node_id;
int num_nodes() const;
std::vector<std::pair<sha1_hash, udp::endpoint>> nodes() const;

View File

@ -0,0 +1,72 @@
/*
Copyright (c) 2017, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_NOEXCEPT_MOVABLE_HPP_INCLUDED
#define TORRENT_NOEXCEPT_MOVABLE_HPP_INCLUDED
namespace libtorrent {
namespace aux {
// this is a silly wrapper for address and endpoint to make their move
// constructors be noexcept (because boost.asio is incorrectly making them
// potentially throwing). This can be removed once libtorrent uses the
// networking TS.
template <typename T>
struct noexcept_movable : T
{
noexcept_movable() noexcept {}
noexcept_movable(noexcept_movable<T>&& rhs) noexcept
: T(std::forward<T>(rhs))
{}
noexcept_movable(noexcept_movable<T> const& rhs)
: T(static_cast<T const&>(rhs))
{}
noexcept_movable(T&& rhs) noexcept : T(std::forward<T>(rhs)) {} // NOLINT
noexcept_movable(T const& rhs) : T(rhs) {} // NOLINT
noexcept_movable& operator=(noexcept_movable&& rhs) noexcept
{
this->T::operator=(std::forward<T>(rhs));
return *this;
}
noexcept_movable& operator=(noexcept_movable const& rhs)
{
this->T::operator=(rhs);
return *this;
}
using T::T;
using T::operator=;
};
}
}
#endif

View File

@ -44,8 +44,8 @@ namespace libtorrent { namespace aux {
~scope_end_impl() { if (m_armed) m_fun(); }
// movable
scope_end_impl(scope_end_impl&&) = default;
scope_end_impl& operator=(scope_end_impl&&) = default;
scope_end_impl(scope_end_impl&&) noexcept = default;
scope_end_impl& operator=(scope_end_impl&&) noexcept = default;
// non-copyable
scope_end_impl(scope_end_impl const&) = delete;

View File

@ -50,6 +50,15 @@ namespace libtorrent { namespace aux {
// pull in constructors from base class
using base::base;
vector() noexcept {}
vector(vector const&) = default;
vector& operator=(vector const&) = default;
// the move constructor of std::vector isn't noexcept until C++17
vector(vector&& rhs) noexcept : base(std::forward<base>(rhs)) {}
vector& operator=(vector&& rhs) noexcept
{ this->base::operator=(std::forward<base>(rhs)); return *this; }
auto operator[](IndexType idx) const ->
#if TORRENT_AUTO_RETURN_TYPES
decltype(auto)

View File

@ -262,8 +262,8 @@ struct TORRENT_EXPORT bdecode_node
// underlying buffer remains the same.
bdecode_node(bdecode_node const&);
bdecode_node& operator=(bdecode_node const&);
bdecode_node(bdecode_node&&);
bdecode_node& operator=(bdecode_node&&);
bdecode_node(bdecode_node&&) noexcept;
bdecode_node& operator=(bdecode_node&&) noexcept;
// the types of bdecoded nodes
enum type_t

View File

@ -56,12 +56,12 @@ namespace libtorrent {
// The constructor taking a pointer ``b`` and ``bits`` copies a bitfield
// from the specified buffer, and ``bits`` number of bits (rounded up to
// the nearest byte boundary).
bitfield() = default;
bitfield() noexcept = default;
explicit bitfield(int bits) { resize(bits); }
bitfield(int bits, bool val) { resize(bits, val); }
bitfield(char const* b, int bits) { assign(b, bits); }
bitfield(bitfield const& rhs) { assign(rhs.data(), rhs.size()); }
bitfield(bitfield&& rhs) = default;
bitfield(bitfield&& rhs) noexcept = default;
// copy bitfield from buffer ``b`` of ``bits`` number of bits, rounded up to
// the nearest byte boundary.
@ -146,7 +146,7 @@ namespace libtorrent {
return *this;
}
bitfield& operator=(bitfield&& rhs) = default;
bitfield& operator=(bitfield&& rhs) noexcept = default;
void swap(bitfield& rhs)
{
@ -256,9 +256,35 @@ namespace libtorrent {
aux::unique_ptr<std::uint32_t[]> m_buf;
};
static_assert(std::is_nothrow_move_constructible<bitfield>::value
, "should be nothrow move constructible");
static_assert(std::is_nothrow_move_assignable<bitfield>::value
, "should be nothrow move assignable");
static_assert(std::is_nothrow_default_constructible<bitfield>::value
, "should be nothrow default constructible");
template <typename IndexType>
struct typed_bitfield : bitfield
{
typed_bitfield() noexcept {}
typed_bitfield(typed_bitfield&& rhs) noexcept
: bitfield(std::forward<bitfield>(rhs))
{}
typed_bitfield(typed_bitfield const& rhs)
: bitfield(static_cast<bitfield const&>(rhs))
{}
typed_bitfield(bitfield&& rhs) noexcept : bitfield(std::forward<bitfield>(rhs)) {} // NOLINT
typed_bitfield(bitfield const& rhs) : bitfield(rhs) {} // NOLINT
typed_bitfield& operator=(typed_bitfield&& rhs) noexcept
{
this->bitfield::operator=(std::forward<bitfield>(rhs));
return *this;
}
typed_bitfield& operator=(typed_bitfield const& rhs)
{
this->bitfield::operator=(rhs);
return *this;
}
using bitfield::bitfield;
bool operator[](IndexType const index) const
@ -276,6 +302,13 @@ namespace libtorrent {
IndexType end_index() const { return IndexType(this->size()); }
};
static_assert(std::is_nothrow_move_constructible<typed_bitfield<int>>::value
, "should be nothrow move constructible");
static_assert(std::is_nothrow_move_assignable<typed_bitfield<int>>::value
, "should be nothrow move assignable");
static_assert(std::is_nothrow_default_constructible<typed_bitfield<int>>::value
, "should be nothrow default constructible");
}
#endif // TORRENT_BITFIELD_HPP_INCLUDED

View File

@ -166,8 +166,8 @@ namespace aux {
{
cached_piece_entry();
~cached_piece_entry();
cached_piece_entry(cached_piece_entry&&) = default;
cached_piece_entry& operator=(cached_piece_entry&&) = default;
cached_piece_entry(cached_piece_entry&&) noexcept = default;
cached_piece_entry& operator=(cached_piece_entry&&) noexcept = default;
bool ok_to_evict(bool ignore_hash = false) const
{

View File

@ -212,14 +212,14 @@ namespace libtorrent {
storage_holder(storage_holder const&) = delete;
storage_holder& operator=(storage_holder const&) = delete;
storage_holder(storage_holder&& rhs)
storage_holder(storage_holder&& rhs) noexcept
: m_disk_io(rhs.m_disk_io)
, m_idx(rhs.m_idx)
{
rhs.m_disk_io = nullptr;
}
storage_holder& operator=(storage_holder&& rhs)
storage_holder& operator=(storage_holder&& rhs) noexcept
{
if (m_disk_io) m_disk_io->remove_torrent(m_idx);
m_disk_io = rhs.m_disk_io;

View File

@ -176,7 +176,7 @@ namespace aux {
// hidden
entry(entry const& e);
entry(entry&& e);
entry(entry&& e) noexcept;
// hidden
entry();
@ -195,7 +195,7 @@ namespace aux {
#endif
entry& operator=(bdecode_node const&);
entry& operator=(entry const&);
entry& operator=(entry&&);
entry& operator=(entry&&) noexcept;
entry& operator=(dictionary_type);
entry& operator=(span<char const>);
template <typename U, typename Cond = typename std::enable_if<
@ -274,7 +274,7 @@ namespace aux {
const preformatted_type& preformatted() const;
// swaps the content of *this* with ``e``.
void swap(entry& e);
void swap(entry& e) noexcept;
// All of these functions requires the entry to be a dictionary, if it
// isn't they will throw ``system_error``.

View File

@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/sha1_hash.hpp"
#include "libtorrent/string_view.hpp"
#include "libtorrent/aux_/vector.hpp"
#include "libtorrent/aux_/noexcept_movable.hpp"
namespace libtorrent {
@ -58,6 +59,8 @@ namespace libtorrent {
~file_entry();
file_entry(file_entry const&) = default;
file_entry& operator=(file_entry const&) = default;
file_entry(file_entry&&) noexcept = default;
file_entry& operator=(file_entry&&) noexcept = default;
// the full path of this file. The paths are unicode strings
// encoded in UTF-8.
@ -114,8 +117,8 @@ namespace libtorrent {
internal_file_entry();
internal_file_entry(internal_file_entry const& fe);
internal_file_entry& operator=(internal_file_entry const& fe);
internal_file_entry(internal_file_entry&& fe);
internal_file_entry& operator=(internal_file_entry&& fe);
internal_file_entry(internal_file_entry&& fe) noexcept;
internal_file_entry& operator=(internal_file_entry&& fe) noexcept;
~internal_file_entry();
void set_name(char const* n, bool borrow_string = false, int string_len = 0);
@ -202,8 +205,8 @@ namespace libtorrent {
~file_storage();
file_storage(file_storage const&);
file_storage& operator=(file_storage const&);
file_storage(file_storage&&);
file_storage& operator=(file_storage&&);
file_storage(file_storage&&) noexcept;
file_storage& operator=(file_storage&&) noexcept;
// returns true if the piece length has been initialized
// on the file_storage. This is typically taken as a proxy
@ -329,8 +332,8 @@ namespace libtorrent {
// all functions depending on internal_file_entry
// were deprecated in 1.0. Use the variants that take an
// index instead
typedef std::vector<internal_file_entry>::const_iterator iterator;
typedef std::vector<internal_file_entry>::const_reverse_iterator reverse_iterator;
using iterator = std::vector<internal_file_entry>::const_iterator;
using reverse_iterator = std::vector<internal_file_entry>::const_reverse_iterator;
TORRENT_DEPRECATED
iterator file_at_offset(std::int64_t offset) const;
@ -405,7 +408,7 @@ namespace libtorrent {
std::string const& name() const { return m_name; }
// swap all content of *this* with *ti*.
void swap(file_storage& ti)
void swap(file_storage& ti) noexcept
{
using std::swap;
swap(ti.m_files, m_files);
@ -598,7 +601,7 @@ namespace libtorrent {
// name of torrent. For multi-file torrents
// this is always the root directory
std::string m_name;
aux::noexcept_movable<std::string> m_name;
// the sum of all file sizes
std::int64_t m_total_size;

View File

@ -221,9 +221,7 @@ namespace libtorrent {
dst += sizeof(header_t) + src_hdr->pad_bytes;
int const len = src_hdr->len;
TORRENT_ASSERT(src + len <= end);
// TODO: if this throws, we should technically destruct the elements
// we've constructed so far, but maybe we should just disallow
// throwing move instead.
// this is no-throw
src_hdr->move(dst, src);
src_hdr->~header_t();
src += len ;
@ -235,8 +233,12 @@ namespace libtorrent {
}
template <class U>
static void move(char* dst, char* src)
static void move(char* dst, char* src) noexcept
{
static_assert(std::is_nothrow_move_constructible<U>::value
, "heterogeneous queue only supports noexcept move constructible types");
static_assert(std::is_nothrow_destructible<U>::value
, "heterogeneous queue only supports noexcept destructible types");
U& rhs = *reinterpret_cast<U*>(src);
TORRENT_ASSERT((reinterpret_cast<std::uintptr_t>(dst) & (alignof(U) - 1)) == 0);

View File

@ -55,7 +55,7 @@ namespace libtorrent {
using protocol_type = Protocol;
using data_type = boost::asio::detail::socket_addr_type;
basic_nl_endpoint() : basic_nl_endpoint(protocol_type(), 0, 0) {}
basic_nl_endpoint() noexcept : basic_nl_endpoint(protocol_type(), 0, 0) {}
basic_nl_endpoint(protocol_type netlink_family, std::uint32_t group, std::uint32_t pid = 0)
: m_proto(netlink_family)
@ -66,18 +66,16 @@ namespace libtorrent {
m_sockaddr.nl_pid = pid;
}
basic_nl_endpoint(basic_nl_endpoint const& other)
{
m_sockaddr = other.m_sockaddr;
}
basic_nl_endpoint(basic_nl_endpoint const& other) = default;
basic_nl_endpoint(basic_nl_endpoint&& other) noexcept = default;
basic_nl_endpoint& operator=(const basic_nl_endpoint& other)
basic_nl_endpoint& operator=(basic_nl_endpoint const& other)
{
m_sockaddr = other.m_sockaddr;
return *this;
}
basic_nl_endpoint& operator=(const basic_nl_endpoint&& other)
basic_nl_endpoint& operator=(basic_nl_endpoint&& other) noexcept
{
m_sockaddr = other.m_sockaddr;
return *this;

View File

@ -117,6 +117,8 @@ namespace aux {
~session_proxy();
session_proxy(session_proxy const&);
session_proxy& operator=(session_proxy const&);
session_proxy(session_proxy&&) noexcept;
session_proxy& operator=(session_proxy&&) noexcept;
private:
session_proxy(
std::shared_ptr<io_service> ios

View File

@ -75,9 +75,9 @@ namespace libtorrent {
session_handle() {}
session_handle(session_handle const& t) = default;
session_handle(session_handle&& t) = default;
session_handle(session_handle&& t) noexcept = default;
session_handle& operator=(session_handle const&) = default;
session_handle& operator=(session_handle&&) = default;
session_handle& operator=(session_handle&&) noexcept = default;
bool is_valid() const { return !m_impl.expired(); }

View File

@ -86,9 +86,9 @@ namespace libtorrent {
settings_pack() = default;
settings_pack(settings_pack const&) = default;
settings_pack(settings_pack&&) = default;
settings_pack(settings_pack&&) noexcept = default;
settings_pack& operator=(settings_pack const&) = default;
settings_pack& operator=(settings_pack&&) = default;
settings_pack& operator=(settings_pack&&) noexcept = default;
void set_str(int name, std::string val);
void set_int(int name, int val);

View File

@ -74,12 +74,10 @@ namespace aux {
static constexpr std::size_t size() { return N / 8; }
// constructs an all-zero digest
digest32() { clear(); }
digest32() noexcept { clear(); }
digest32(digest32 const&) = default;
digest32(digest32&&) = default;
digest32& operator=(digest32 const&) = default;
digest32& operator=(digest32&&) = default;
digest32(digest32 const&) noexcept = default;
digest32& operator=(digest32 const&) noexcept = default;
// returns an all-F digest. i.e. the maximum value
// representable by an N bit number (N/8 bytes). This is
@ -132,7 +130,7 @@ namespace aux {
char* data() { return reinterpret_cast<char*>(&m_number[0]); }
// set the digest to all zeroes.
void clear() { std::memset(m_number, 0, size()); }
void clear() noexcept { std::memset(m_number, 0, size()); }
// return true if the digest is all zero.
bool is_all_zeros() const
@ -278,6 +276,13 @@ namespace aux {
// peer IDs, node IDs etc.
using sha1_hash = digest32<160>;
static_assert(std::is_nothrow_move_constructible<sha1_hash>::value
, "should be nothrow move constructible");
static_assert(std::is_nothrow_move_assignable<sha1_hash>::value
, "should be nothrow move assignable");
static_assert(std::is_nothrow_default_constructible<sha1_hash>::value
, "should be nothrow default constructible");
#if TORRENT_USE_IOSTREAM
// print a sha1_hash object to an ostream as 40 hexadecimal digits

View File

@ -46,16 +46,16 @@ namespace libtorrent { namespace aux {
struct allocation_slot
{
allocation_slot() : m_idx(-1) {}
allocation_slot(allocation_slot const&) = default;
allocation_slot(allocation_slot&&) = default;
allocation_slot() noexcept : m_idx(-1) {}
allocation_slot(allocation_slot const&) noexcept = default;
allocation_slot(allocation_slot&&) noexcept = default;
allocation_slot& operator=(allocation_slot const&) = default;
allocation_slot& operator=(allocation_slot&&) = default;
allocation_slot& operator=(allocation_slot&&) noexcept = default;
bool operator==(allocation_slot const& s) const { return m_idx == s.m_idx; }
bool operator!=(allocation_slot const& s) const { return m_idx != s.m_idx; }
friend struct stack_allocator;
private:
explicit allocation_slot(int idx) : m_idx(idx) {}
explicit allocation_slot(int idx) noexcept : m_idx(idx) {}
int val() const { return m_idx; }
int m_idx;
};

View File

@ -186,7 +186,7 @@ namespace libtorrent {
#if defined __GNUC__ && defined _GLIBCXX_DEBUG
// this works around a bug in libstdc++'s checked iterators
// http://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle
web_seed_t& operator=(web_seed_t&& rhs)
web_seed_t& operator=(web_seed_t&& rhs) noexcept
{
if (&rhs == this) return *this;

View File

@ -155,10 +155,10 @@ namespace libtorrent { namespace aux {
#ifndef TORRENT_NO_DEPRECATE
#include "libtorrent/aux_/disable_warnings_push.hpp"
partial_piece_info() = default;
partial_piece_info(partial_piece_info&&) = default;
partial_piece_info(partial_piece_info&&) noexcept = default;
partial_piece_info(partial_piece_info const&) = default;
partial_piece_info& operator=(partial_piece_info const&) = default;
partial_piece_info& operator=(partial_piece_info&&) = default;
partial_piece_info& operator=(partial_piece_info&&) noexcept = default;
#include "libtorrent/aux_/disable_warnings_pop.hpp"
#endif
// the index of the piece in question. ``blocks_in_piece`` is the number
@ -258,12 +258,12 @@ namespace libtorrent { namespace aux {
// constructs a torrent handle that does not refer to a torrent.
// i.e. is_valid() will return false.
torrent_handle() {}
torrent_handle() noexcept {}
torrent_handle(torrent_handle const& t) = default;
torrent_handle(torrent_handle&& t) = default;
torrent_handle(torrent_handle&& t) noexcept = default;
torrent_handle& operator=(torrent_handle const&) = default;
torrent_handle& operator=(torrent_handle&&) = default;
torrent_handle& operator=(torrent_handle&&) noexcept = default;
// flags for add_piece().
enum flags_t { overwrite_existing = 1 };
@ -1311,9 +1311,14 @@ namespace libtorrent { namespace aux {
{ if (!t.expired()) m_torrent = t; }
std::weak_ptr<torrent> m_torrent;
};
static_assert(std::is_nothrow_move_constructible<torrent_handle>::value
, "should be nothrow move constructible");
static_assert(std::is_nothrow_move_assignable<torrent_handle>::value
, "should be nothrow move assignable");
static_assert(std::is_nothrow_default_constructible<torrent_handle>::value
, "should be nothrow default constructible");
}
namespace std

View File

@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/time.hpp" // for time_duration
#include "libtorrent/storage_defs.hpp" // for storage_mode_t
#include "libtorrent/error_code.hpp"
#include "libtorrent/aux_/noexcept_movable.hpp"
#include <cstdint>
#include <string>
@ -52,11 +53,13 @@ namespace libtorrent {
struct TORRENT_EXPORT torrent_status
{
// hidden
torrent_status();
torrent_status() noexcept;
~torrent_status();
torrent_status(torrent_status const&);
torrent_status& operator=(torrent_status const&);
torrent_status(torrent_status&&);
torrent_status(torrent_status&&) noexcept;
// TODO: 2 msvc and GCC did not make std::string nothrow move-assignable
// until C++17
torrent_status& operator=(torrent_status&&);
// compares if the torrent status objects come from the same torrent. i.e.
@ -557,6 +560,13 @@ namespace libtorrent {
seconds finished_duration;
seconds seeding_duration;
};
static_assert(std::is_nothrow_move_constructible<torrent_status>::value
, "should be nothrow move constructible");
// static_assert(std::is_nothrow_move_assignable<torrent_status>::value
// , "should be nothrow move assignable");
static_assert(std::is_nothrow_default_constructible<torrent_status>::value
, "should be nothrow default constructible");
}
namespace std

View File

@ -52,8 +52,9 @@ namespace libtorrent { namespace aux {
using underlying_type = UnderlyingType;
using diff_type = strong_typedef<UnderlyingType, difference_tag<Tag>>;
constexpr strong_typedef(strong_typedef const& rhs) : m_val(rhs.m_val) {}
strong_typedef() = default;
constexpr strong_typedef(strong_typedef const& rhs) noexcept = default;
constexpr strong_typedef(strong_typedef&& rhs) noexcept = default;
strong_typedef() noexcept = default;
#ifndef TORRENT_NO_DEPRECATE
constexpr strong_typedef(UnderlyingType val) : m_val(val) {}
constexpr operator UnderlyingType() const { return m_val; }
@ -87,7 +88,8 @@ namespace libtorrent { namespace aux {
strong_typedef& operator-=(diff_type rhs)
{ m_val -= static_cast<UnderlyingType>(rhs); return *this; }
strong_typedef& operator=(strong_typedef rhs) { m_val = rhs.m_val; return *this; }
strong_typedef& operator=(strong_typedef const& rhs) noexcept = default;
strong_typedef& operator=(strong_typedef&& rhs) noexcept = default;
private:
UnderlyingType m_val;
};

View File

@ -191,8 +191,8 @@ struct TORRENT_EXTRA_EXPORT utp_stream
~utp_stream();
utp_stream& operator=(utp_stream const&) = delete;
utp_stream(utp_stream const&) = delete;
utp_stream& operator=(utp_stream&&) = default;
utp_stream(utp_stream&&) = default;
utp_stream& operator=(utp_stream&&) noexcept = default;
utp_stream(utp_stream&&) noexcept = default;
lowest_layer_type& lowest_layer() { return *this; }

View File

@ -244,8 +244,8 @@ namespace {
return *this;
}
bdecode_node::bdecode_node(bdecode_node&&) = default;
bdecode_node& bdecode_node::operator=(bdecode_node&&) = default;
bdecode_node::bdecode_node(bdecode_node&&) noexcept = default;
bdecode_node& bdecode_node::operator=(bdecode_node&&) noexcept = default;
bdecode_node::bdecode_node(bdecode_token const* tokens, char const* buf
, int len, int idx)

View File

@ -132,7 +132,7 @@ namespace {
return *this;
}
entry& entry::operator=(entry&& e)
entry& entry::operator=(entry&& e) noexcept
{
swap(e);
return *this;
@ -269,7 +269,7 @@ namespace {
#endif
}
entry::entry(entry&& e)
entry::entry(entry&& e) noexcept
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
@ -572,7 +572,7 @@ namespace {
#endif
}
void entry::swap(entry& e)
void entry::swap(entry& e) noexcept
{
bool clear_this = false;
bool clear_that = false;

View File

@ -70,6 +70,8 @@ namespace libtorrent {
// of libtorrent and properly exported by the .dll.
file_storage::file_storage(file_storage const&) = default;
file_storage& file_storage::operator=(file_storage const&) = default;
file_storage::file_storage(file_storage&&) noexcept = default;
file_storage& file_storage::operator=(file_storage&&) noexcept = default;
void file_storage::reserve(int num_files)
{
@ -242,7 +244,7 @@ namespace {
return *this;
}
internal_file_entry::internal_file_entry(internal_file_entry&& fe)
internal_file_entry::internal_file_entry(internal_file_entry&& fe) noexcept
: offset(fe.offset)
, symlink_index(fe.symlink_index)
, no_root_dir(fe.no_root_dir)
@ -259,7 +261,7 @@ namespace {
fe.name = nullptr;
}
internal_file_entry& internal_file_entry::operator=(internal_file_entry&& fe)
internal_file_entry& internal_file_entry::operator=(internal_file_entry&& fe) noexcept
{
offset = fe.offset;
size = fe.size;
@ -278,9 +280,6 @@ namespace {
return *this;
}
file_storage::file_storage(file_storage&&) = default;
file_storage& file_storage::operator=(file_storage&&) = default;
// if borrow_chars >= 0, don't take ownership over n, just
// point to it. It points to borrow_chars number of characters.
// if borrow_chars == -1, n is a 0-terminated string that

View File

@ -404,6 +404,8 @@ namespace {
{}
session_proxy::session_proxy(session_proxy const&) = default;
session_proxy& session_proxy::operator=(session_proxy const&) = default;
session_proxy::session_proxy(session_proxy&&) noexcept = default;
session_proxy& session_proxy::operator=(session_proxy&&) noexcept = default;
session_proxy::~session_proxy()
{
if (m_thread && m_thread.unique())

View File

@ -39,10 +39,10 @@ namespace libtorrent {
file_index_t constexpr torrent_status::error_file_ssl_ctx;
file_index_t constexpr torrent_status::error_file_metadata;
file_index_t constexpr torrent_status::error_file_exception;
torrent_status::torrent_status() = default;
torrent_status::torrent_status() noexcept {}
torrent_status::~torrent_status() = default;
torrent_status::torrent_status(torrent_status const&) = default;
torrent_status& torrent_status::operator=(torrent_status const&) = default;
torrent_status::torrent_status(torrent_status&&) = default;
torrent_status::torrent_status(torrent_status&&) noexcept = default;
torrent_status& torrent_status::operator=(torrent_status&&) = default;
}

View File

@ -186,8 +186,8 @@ struct holder
~holder() { if (m_buf) free_buffer(m_buf); }
holder(holder const&) = delete;
holder& operator=(holder const&) = delete;
holder(holder&& rhs) : m_buf(rhs.m_buf) { rhs.m_buf = nullptr; }
holder& operator=(holder&& rhs)
holder(holder&& rhs) noexcept : m_buf(rhs.m_buf) { rhs.m_buf = nullptr; }
holder& operator=(holder&& rhs) noexcept
{
if (m_buf) free_buffer(m_buf);
m_buf = rhs.m_buf;

View File

@ -39,6 +39,7 @@ struct A
{
int a;
explicit A(int a_) : a(a_) {}
A(A&&) noexcept = default;
virtual int type() = 0;
virtual ~A() = default;
};
@ -47,6 +48,7 @@ struct B : A
{
int b;
explicit B(int a_, int b_) : A(a_), b(b_) {}
B(B&&) noexcept = default;
int type() override { return 1; }
};
@ -57,6 +59,7 @@ struct C : A
{
memset(c, c_, sizeof(c));
}
C(C&&) noexcept = default;
int type() override { return 2; }
};
@ -65,6 +68,7 @@ struct D
static int instances;
D() { ++instances; }
D(D const& d) { ++instances; }
D(D&&) noexcept { ++instances; }
~D() { --instances; }
};
@ -72,6 +76,7 @@ struct D
struct E
{
explicit E(char const* msg) : string_member(msg) {}
E(E&&) noexcept = default;
std::string string_member;
};
@ -98,7 +103,7 @@ struct F
TEST_EQUAL(f_.gutted, false);
}
F(F&& f_)
F(F&& f_) noexcept
: self(this)
, f(f_.f)
, constructed(f_.constructed)
@ -141,6 +146,7 @@ private:
struct G : A
{
G(int base, int v) : A(base), g(v) {}
G(G&&) noexcept = default;
int type() override { return 3; }
std::int64_t g;
};