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 const& s): arr(s) {}
bytes(std::string&& s): arr(std::move(s)) {} bytes(std::string&& s): arr(std::move(s)) {}
bytes(bytes const&) = default; bytes(bytes const&) = default;
bytes(bytes&&) = default; bytes(bytes&&) noexcept = default;
bytes& operator=(bytes&&) = default; bytes& operator=(bytes&&) noexcept = default;
bytes() {} bytes() {}
std::string arr; std::string arr;
}; };

View File

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

View File

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

View File

@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bitfield.hpp" #include "libtorrent/bitfield.hpp"
#include "libtorrent/error_code.hpp" #include "libtorrent/error_code.hpp"
#include "libtorrent/units.hpp" #include "libtorrent/units.hpp"
#include "libtorrent/aux_/noexcept_movable.hpp"
namespace libtorrent { namespace libtorrent {
@ -85,9 +86,9 @@ namespace libtorrent {
// which determines the storage mechanism for the downloaded or seeding // which determines the storage mechanism for the downloaded or seeding
// data for the torrent. For more information, see the ``storage`` field. // data for the torrent. For more information, see the ``storage`` field.
explicit add_torrent_params(storage_constructor_type sc = default_storage_constructor) explicit add_torrent_params(storage_constructor_type sc = default_storage_constructor)
: storage(sc) {} : storage(storage_constructor_type(sc)) {}
add_torrent_params(add_torrent_params&&) = default; add_torrent_params(add_torrent_params&&) noexcept = default;
add_torrent_params& operator=(add_torrent_params&&) = default; add_torrent_params& operator=(add_torrent_params&&) noexcept = default;
add_torrent_params(add_torrent_params const&) = default; add_torrent_params(add_torrent_params const&) = default;
add_torrent_params& operator=(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 // 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. // 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 // the tiers the URLs in ``trackers`` belong to. Trackers belonging to
// different tiers may be treated differently, as defined by the multi // different tiers may be treated differently, as defined by the multi
// tracker extension. This is optional, if not specified trackers are // tracker extension. This is optional, if not specified trackers are
// assumed to be part of tier 0, or whichever the last tier was as // assumed to be part of tier 0, or whichever the last tier was as
// iterating over the trackers. // 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 // 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. // 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; std::string name;
@ -321,7 +322,11 @@ namespace libtorrent {
// or encrypt the content on disk for instance. For more information // or encrypt the content on disk for instance. For more information
// about the storage_interface that needs to be implemented for a custom // about the storage_interface that needs to be implemented for a custom
// storage, see storage_interface. // storage, see storage_interface.
#ifdef __clang__
storage_constructor_type storage; 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 // The ``userdata`` parameter is optional and will be passed on to the
// extension constructor functions, if any // extension constructor functions, if any
@ -331,7 +336,7 @@ namespace libtorrent {
// can be set to control the initial file priorities when adding a // can be set to control the initial file priorities when adding a
// torrent. The semantics are the same as for // torrent. The semantics are the same as for
// ``torrent_handle::prioritize_files()``. // ``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 // torrent extension construction functions can be added to this vector
// to have them be added immediately when the torrent is constructed. // 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 // 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 // plugin catch events that happen very early on after the torrent is
// created. // 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; extensions;
// the default tracker id to be used when announcing to trackers. By // 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, // url_seeds expects URLs to regular web servers, aka "get right" style,
// specified in `BEP 19`_. // specified in `BEP 19`_.
std::vector<std::string> http_seeds; aux::noexcept_movable<std::vector<std::string>> http_seeds;
std::vector<std::string> url_seeds; aux::noexcept_movable<std::vector<std::string>> url_seeds;
// peers to add to the torrent, to be tried to be connected to as // peers to add to the torrent, to be tried to be connected to as
// bittorrent peers. // 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 // 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 // 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. // and the value is a bitfield where each bit represents a 16 kiB block.
// A set bit means we have that 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 // this is a bitfield indicating which pieces we already have of this
// torrent. // torrent.
@ -462,16 +467,16 @@ namespace libtorrent {
// element in the vector represent the piece with the same index. If you // element in the vector represent the piece with the same index. If you
// set both file- and piece priorities, file priorities will take // set both file- and piece priorities, file priorities will take
// precedence. // 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 // 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 // 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. // 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 // this is a map of file indices in the torrent and new filenames to be
// applied before the torrent is added. // 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 #ifndef TORRENT_NO_DEPRECATE
// deprecated in 1.2 // deprecated in 1.2
@ -501,7 +506,7 @@ namespace libtorrent {
// torrent_handle. See fast-resume_. The ``vector`` that is passed in // torrent_handle. See fast-resume_. The ``vector`` that is passed in
// will be swapped into the running torrent instance with // will be swapped into the running torrent instance with
// ``std::vector::swap()``. // ``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 // to support the deprecated use case of reading the resume data into
// resume_data field and getting a reject alert, any parse failure is // resume_data field and getting a reject alert, any parse failure is
@ -514,11 +519,24 @@ namespace libtorrent {
std::string deprecated5; std::string deprecated5;
std::string deprecated1; std::string deprecated1;
std::string deprecated2; std::string deprecated2;
std::vector<char> deprecated3; aux::noexcept_movable<std::vector<char>> deprecated3;
error_code deprecated4; error_code deprecated4;
#endif #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 #endif

View File

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

View File

@ -50,6 +50,15 @@ namespace libtorrent { namespace aux {
// pull in constructors from base class // pull in constructors from base class
using base::base; 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 -> auto operator[](IndexType idx) const ->
#if TORRENT_AUTO_RETURN_TYPES #if TORRENT_AUTO_RETURN_TYPES
decltype(auto) decltype(auto)

View File

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

View File

@ -56,12 +56,12 @@ namespace libtorrent {
// The constructor taking a pointer ``b`` and ``bits`` copies a bitfield // The constructor taking a pointer ``b`` and ``bits`` copies a bitfield
// from the specified buffer, and ``bits`` number of bits (rounded up to // from the specified buffer, and ``bits`` number of bits (rounded up to
// the nearest byte boundary). // the nearest byte boundary).
bitfield() = default; bitfield() noexcept = default;
explicit bitfield(int bits) { resize(bits); } explicit bitfield(int bits) { resize(bits); }
bitfield(int bits, bool val) { resize(bits, val); } bitfield(int bits, bool val) { resize(bits, val); }
bitfield(char const* b, int bits) { assign(b, bits); } bitfield(char const* b, int bits) { assign(b, bits); }
bitfield(bitfield const& rhs) { assign(rhs.data(), rhs.size()); } 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 // copy bitfield from buffer ``b`` of ``bits`` number of bits, rounded up to
// the nearest byte boundary. // the nearest byte boundary.
@ -146,7 +146,7 @@ namespace libtorrent {
return *this; return *this;
} }
bitfield& operator=(bitfield&& rhs) = default; bitfield& operator=(bitfield&& rhs) noexcept = default;
void swap(bitfield& rhs) void swap(bitfield& rhs)
{ {
@ -256,9 +256,35 @@ namespace libtorrent {
aux::unique_ptr<std::uint32_t[]> m_buf; 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> template <typename IndexType>
struct typed_bitfield : bitfield 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; using bitfield::bitfield;
bool operator[](IndexType const index) const bool operator[](IndexType const index) const
@ -276,6 +302,13 @@ namespace libtorrent {
IndexType end_index() const { return IndexType(this->size()); } 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 #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();
cached_piece_entry(cached_piece_entry&&) = default; cached_piece_entry(cached_piece_entry&&) noexcept = default;
cached_piece_entry& operator=(cached_piece_entry&&) = default; cached_piece_entry& operator=(cached_piece_entry&&) noexcept = default;
bool ok_to_evict(bool ignore_hash = false) const 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(storage_holder const&) = delete;
storage_holder& operator=(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_disk_io(rhs.m_disk_io)
, m_idx(rhs.m_idx) , m_idx(rhs.m_idx)
{ {
rhs.m_disk_io = nullptr; 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); if (m_disk_io) m_disk_io->remove_torrent(m_idx);
m_disk_io = rhs.m_disk_io; m_disk_io = rhs.m_disk_io;

View File

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

View File

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

View File

@ -221,9 +221,7 @@ namespace libtorrent {
dst += sizeof(header_t) + src_hdr->pad_bytes; dst += sizeof(header_t) + src_hdr->pad_bytes;
int const len = src_hdr->len; int const len = src_hdr->len;
TORRENT_ASSERT(src + len <= end); TORRENT_ASSERT(src + len <= end);
// TODO: if this throws, we should technically destruct the elements // this is no-throw
// we've constructed so far, but maybe we should just disallow
// throwing move instead.
src_hdr->move(dst, src); src_hdr->move(dst, src);
src_hdr->~header_t(); src_hdr->~header_t();
src += len ; src += len ;
@ -235,8 +233,12 @@ namespace libtorrent {
} }
template <class U> 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); U& rhs = *reinterpret_cast<U*>(src);
TORRENT_ASSERT((reinterpret_cast<std::uintptr_t>(dst) & (alignof(U) - 1)) == 0); 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 protocol_type = Protocol;
using data_type = boost::asio::detail::socket_addr_type; 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) basic_nl_endpoint(protocol_type netlink_family, std::uint32_t group, std::uint32_t pid = 0)
: m_proto(netlink_family) : m_proto(netlink_family)
@ -66,18 +66,16 @@ namespace libtorrent {
m_sockaddr.nl_pid = pid; m_sockaddr.nl_pid = pid;
} }
basic_nl_endpoint(basic_nl_endpoint const& other) basic_nl_endpoint(basic_nl_endpoint const& other) = default;
{ basic_nl_endpoint(basic_nl_endpoint&& other) noexcept = default;
m_sockaddr = other.m_sockaddr;
}
basic_nl_endpoint& operator=(const basic_nl_endpoint& other) basic_nl_endpoint& operator=(basic_nl_endpoint const& other)
{ {
m_sockaddr = other.m_sockaddr; m_sockaddr = other.m_sockaddr;
return *this; 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; m_sockaddr = other.m_sockaddr;
return *this; return *this;

View File

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

View File

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

View File

@ -86,9 +86,9 @@ namespace libtorrent {
settings_pack() = default; settings_pack() = default;
settings_pack(settings_pack const&) = 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 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_str(int name, std::string val);
void set_int(int name, int 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; } static constexpr std::size_t size() { return N / 8; }
// constructs an all-zero digest // constructs an all-zero digest
digest32() { clear(); } digest32() noexcept { clear(); }
digest32(digest32 const&) = default; digest32(digest32 const&) noexcept = default;
digest32(digest32&&) = default; digest32& operator=(digest32 const&) noexcept = default;
digest32& operator=(digest32 const&) = default;
digest32& operator=(digest32&&) = default;
// returns an all-F digest. i.e. the maximum value // returns an all-F digest. i.e. the maximum value
// representable by an N bit number (N/8 bytes). This is // 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]); } char* data() { return reinterpret_cast<char*>(&m_number[0]); }
// set the digest to all zeroes. // 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. // return true if the digest is all zero.
bool is_all_zeros() const bool is_all_zeros() const
@ -278,6 +276,13 @@ namespace aux {
// peer IDs, node IDs etc. // peer IDs, node IDs etc.
using sha1_hash = digest32<160>; 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 #if TORRENT_USE_IOSTREAM
// print a sha1_hash object to an ostream as 40 hexadecimal digits // 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 struct allocation_slot
{ {
allocation_slot() : m_idx(-1) {} allocation_slot() noexcept : m_idx(-1) {}
allocation_slot(allocation_slot const&) = default; allocation_slot(allocation_slot const&) noexcept = default;
allocation_slot(allocation_slot&&) = default; allocation_slot(allocation_slot&&) noexcept = default;
allocation_slot& operator=(allocation_slot const&) = 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; }
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; friend struct stack_allocator;
private: 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 val() const { return m_idx; }
int m_idx; int m_idx;
}; };

View File

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

View File

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

View File

@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/time.hpp" // for time_duration #include "libtorrent/time.hpp" // for time_duration
#include "libtorrent/storage_defs.hpp" // for storage_mode_t #include "libtorrent/storage_defs.hpp" // for storage_mode_t
#include "libtorrent/error_code.hpp" #include "libtorrent/error_code.hpp"
#include "libtorrent/aux_/noexcept_movable.hpp"
#include <cstdint> #include <cstdint>
#include <string> #include <string>
@ -52,11 +53,13 @@ namespace libtorrent {
struct TORRENT_EXPORT torrent_status struct TORRENT_EXPORT torrent_status
{ {
// hidden // hidden
torrent_status(); torrent_status() noexcept;
~torrent_status(); ~torrent_status();
torrent_status(torrent_status const&); torrent_status(torrent_status const&);
torrent_status& operator=(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&&); torrent_status& operator=(torrent_status&&);
// compares if the torrent status objects come from the same torrent. i.e. // compares if the torrent status objects come from the same torrent. i.e.
@ -557,6 +560,13 @@ namespace libtorrent {
seconds finished_duration; seconds finished_duration;
seconds seeding_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 namespace std

View File

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

View File

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

View File

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

View File

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

View File

@ -70,6 +70,8 @@ namespace libtorrent {
// of libtorrent and properly exported by the .dll. // of libtorrent and properly exported by the .dll.
file_storage::file_storage(file_storage const&) = default; file_storage::file_storage(file_storage const&) = default;
file_storage& file_storage::operator=(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) void file_storage::reserve(int num_files)
{ {
@ -242,7 +244,7 @@ namespace {
return *this; 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) : offset(fe.offset)
, symlink_index(fe.symlink_index) , symlink_index(fe.symlink_index)
, no_root_dir(fe.no_root_dir) , no_root_dir(fe.no_root_dir)
@ -259,7 +261,7 @@ namespace {
fe.name = nullptr; 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; offset = fe.offset;
size = fe.size; size = fe.size;
@ -278,9 +280,6 @@ namespace {
return *this; 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 // if borrow_chars >= 0, don't take ownership over n, just
// point to it. It points to borrow_chars number of characters. // point to it. It points to borrow_chars number of characters.
// if borrow_chars == -1, n is a 0-terminated string that // 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(session_proxy const&) = default;
session_proxy& session_proxy::operator=(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() session_proxy::~session_proxy()
{ {
if (m_thread && m_thread.unique()) 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_ssl_ctx;
file_index_t constexpr torrent_status::error_file_metadata; file_index_t constexpr torrent_status::error_file_metadata;
file_index_t constexpr torrent_status::error_file_exception; 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() = default;
torrent_status::torrent_status(torrent_status const&) = default; torrent_status::torrent_status(torrent_status const&) = default;
torrent_status& torrent_status::operator=(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; 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() { if (m_buf) free_buffer(m_buf); }
holder(holder const&) = delete; holder(holder const&) = delete;
holder& operator=(holder const&) = delete; holder& operator=(holder const&) = delete;
holder(holder&& rhs) : m_buf(rhs.m_buf) { rhs.m_buf = nullptr; } holder(holder&& rhs) noexcept : m_buf(rhs.m_buf) { rhs.m_buf = nullptr; }
holder& operator=(holder&& rhs) holder& operator=(holder&& rhs) noexcept
{ {
if (m_buf) free_buffer(m_buf); if (m_buf) free_buffer(m_buf);
m_buf = rhs.m_buf; m_buf = rhs.m_buf;

View File

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