Skip to content

Commit 6967d17

Browse files
committed
make move constructors and move assignment operators noexcept
1 parent 48bb1d2 commit 6967d17

34 files changed

+400
-205
lines changed

bindings/python/src/bytes.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ struct bytes
1313
bytes(std::string const& s): arr(s) {}
1414
bytes(std::string&& s): arr(std::move(s)) {}
1515
bytes(bytes const&) = default;
16-
bytes(bytes&&) = default;
17-
bytes& operator=(bytes&&) = default;
16+
bytes(bytes&&) noexcept = default;
17+
bytes& operator=(bytes&&) noexcept = default;
1818
bytes() {}
1919
std::string arr;
2020
};

bindings/python/src/converters.cpp

+50-23
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "libtorrent/units.hpp"
1212
#include "libtorrent/sha1_hash.hpp"
1313
#include "libtorrent/disk_interface.hpp" // for open_file_state
14+
#include "libtorrent/aux_/noexcept_movable.hpp"
1415
#include <vector>
1516

1617
using namespace boost::python;
@@ -70,9 +71,10 @@ struct pair_to_tuple
7071
}
7172
};
7273

74+
template <typename Addr>
7375
struct address_to_tuple
7476
{
75-
static PyObject* convert(lt::address const& addr)
77+
static PyObject* convert(Addr const& addr)
7678
{
7779
lt::error_code ec;
7880
return incref(bp::object(addr.to_string(ec)).ptr());
@@ -145,7 +147,7 @@ struct dict_to_map
145147
template<class T>
146148
struct vector_to_list
147149
{
148-
static PyObject* convert(const std::vector<T>& v)
150+
static PyObject* convert(T const& v)
149151
{
150152
list l;
151153
for (int i = 0; i < int(v.size()); ++i)
@@ -162,7 +164,7 @@ struct list_to_vector
162164
list_to_vector()
163165
{
164166
converter::registry::push_back(
165-
&convertible, &construct, type_id<std::vector<T>>()
167+
&convertible, &construct, type_id<T>()
166168
);
167169
}
168170

@@ -174,17 +176,17 @@ struct list_to_vector
174176
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
175177
{
176178
void* storage = ((converter::rvalue_from_python_storage<
177-
std::vector<T>>*)data)->storage.bytes;
179+
T>*)data)->storage.bytes;
178180

179-
std::vector<T> p;
181+
T p;
180182
int const size = int(PyList_Size(x));
181183
p.reserve(size);
182184
for (int i = 0; i < size; ++i)
183185
{
184186
object o(borrowed(PyList_GetItem(x, i)));
185-
p.push_back(extract<T>(o));
187+
p.push_back(extract<typename T::value_type>(o));
186188
}
187-
std::vector<T>* ptr = new (storage) std::vector<T>();
189+
T* ptr = new (storage) T();
188190
ptr->swap(p);
189191
data->convertible = storage;
190192
}
@@ -234,35 +236,60 @@ void bind_converters()
234236
to_python_converter<std::pair<lt::piece_index_t, int>, pair_to_tuple<lt::piece_index_t, int>>();
235237
to_python_converter<lt::tcp::endpoint, endpoint_to_tuple<lt::tcp::endpoint>>();
236238
to_python_converter<lt::udp::endpoint, endpoint_to_tuple<lt::udp::endpoint>>();
237-
to_python_converter<lt::address, address_to_tuple>();
239+
to_python_converter<lt::address, address_to_tuple<lt::address>>();
238240
to_python_converter<std::pair<std::string, int>, pair_to_tuple<std::string, int>>();
239241

240-
to_python_converter<std::vector<lt::stats_metric>, vector_to_list<lt::stats_metric>>();
241-
to_python_converter<std::vector<lt::open_file_state>, vector_to_list<lt::open_file_state>>();
242-
to_python_converter<std::vector<lt::sha1_hash>, vector_to_list<lt::sha1_hash>>();
243-
to_python_converter<std::vector<std::string>, vector_to_list<std::string>>();
244-
to_python_converter<std::vector<int>, vector_to_list<int>>();
245-
to_python_converter<std::vector<std::uint8_t>, vector_to_list<std::uint8_t>>();
246-
to_python_converter<std::vector<lt::tcp::endpoint>, vector_to_list<lt::tcp::endpoint>>();
247-
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<lt::udp::endpoint>>();
248-
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::pair<std::string, int>>>();
242+
to_python_converter<std::vector<lt::stats_metric>, vector_to_list<std::vector<lt::stats_metric>>>();
243+
to_python_converter<std::vector<lt::open_file_state>, vector_to_list<std::vector<lt::open_file_state>>>();
244+
to_python_converter<std::vector<lt::sha1_hash>, vector_to_list<std::vector<lt::sha1_hash>>>();
245+
to_python_converter<std::vector<std::string>, vector_to_list<std::vector<std::string>>>();
246+
to_python_converter<std::vector<int>, vector_to_list<std::vector<int>>>();
247+
to_python_converter<std::vector<std::uint8_t>, vector_to_list<std::vector<std::uint8_t>>>();
248+
to_python_converter<std::vector<lt::tcp::endpoint>, vector_to_list<std::vector<lt::tcp::endpoint>>>();
249+
to_python_converter<std::vector<lt::udp::endpoint>, vector_to_list<std::vector<lt::udp::endpoint>>>();
250+
to_python_converter<std::vector<std::pair<std::string, int>>, vector_to_list<std::vector<std::pair<std::string, int>>>>();
249251

250252
to_python_converter<lt::piece_index_t, from_strong_typedef<lt::piece_index_t>>();
251253
to_python_converter<lt::file_index_t, from_strong_typedef<lt::file_index_t>>();
252254

255+
// work-around types
256+
to_python_converter<lt::aux::noexcept_movable<lt::address>, address_to_tuple<
257+
lt::aux::noexcept_movable<lt::address>>>();
258+
to_python_converter<lt::aux::noexcept_movable<lt::tcp::endpoint>, endpoint_to_tuple<
259+
lt::aux::noexcept_movable<lt::tcp::endpoint>>>();
260+
to_python_converter<lt::aux::noexcept_movable<lt::udp::endpoint>, endpoint_to_tuple<
261+
lt::aux::noexcept_movable<lt::udp::endpoint>>>();
262+
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::stats_metric>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::stats_metric>>>>();
263+
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>>>>();
264+
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::sha1_hash>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::sha1_hash>>>>();
265+
to_python_converter<lt::aux::noexcept_movable<std::vector<std::string>>, vector_to_list<lt::aux::noexcept_movable<std::vector<std::string>>>>();
266+
to_python_converter<lt::aux::noexcept_movable<std::vector<int>>, vector_to_list<lt::aux::noexcept_movable<std::vector<int>>>>();
267+
to_python_converter<lt::aux::noexcept_movable<std::vector<std::uint8_t>>, vector_to_list<lt::aux::noexcept_movable<std::vector<std::uint8_t>>>>();
268+
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>>>();
269+
to_python_converter<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>, vector_to_list<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>>();
270+
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>>>>>();
271+
253272
// python -> C++ conversions
254273
tuple_to_pair<int, int>();
255274
tuple_to_pair<std::string, int>();
256275
tuple_to_endpoint<lt::tcp::endpoint>();
257276
tuple_to_endpoint<lt::udp::endpoint>();
258277
tuple_to_pair<lt::piece_index_t, int>();
259278
dict_to_map<lt::file_index_t, std::string>();
260-
list_to_vector<int>();
261-
list_to_vector<std::uint8_t>();
262-
list_to_vector<std::string>();
263-
list_to_vector<lt::tcp::endpoint>();
264-
list_to_vector<lt::udp::endpoint>();
265-
list_to_vector<std::pair<std::string, int>>();
279+
list_to_vector<std::vector<int>>();
280+
list_to_vector<std::vector<std::uint8_t>>();
281+
list_to_vector<std::vector<std::string>>();
282+
list_to_vector<std::vector<lt::tcp::endpoint>>();
283+
list_to_vector<std::vector<lt::udp::endpoint>>();
284+
list_to_vector<std::vector<std::pair<std::string, int>>>();
285+
286+
// work-around types
287+
list_to_vector<lt::aux::noexcept_movable<std::vector<int>>>();
288+
list_to_vector<lt::aux::noexcept_movable<std::vector<std::uint8_t>>>();
289+
list_to_vector<lt::aux::noexcept_movable<std::vector<std::string>>>();
290+
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::tcp::endpoint>>>();
291+
list_to_vector<lt::aux::noexcept_movable<std::vector<lt::udp::endpoint>>>();
292+
list_to_vector<lt::aux::noexcept_movable<std::vector<std::pair<std::string, int>>>>();
266293

267294
to_strong_typedef<lt::piece_index_t>();
268295
to_strong_typedef<lt::file_index_t>();

include/libtorrent/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ nobase_include_HEADERS = \
207207
aux_/typed_span.hpp \
208208
aux_/array.hpp \
209209
aux_/ip_notifier.hpp \
210+
aux_/noexcept_movable.hpp \
210211
\
211212
extensions/smart_ban.hpp \
212213
extensions/ut_metadata.hpp \

include/libtorrent/add_torrent_params.hpp

+36-18
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
4646
#include "libtorrent/bitfield.hpp"
4747
#include "libtorrent/error_code.hpp"
4848
#include "libtorrent/units.hpp"
49+
#include "libtorrent/aux_/noexcept_movable.hpp"
4950

5051
namespace libtorrent {
5152

@@ -85,9 +86,9 @@ namespace libtorrent {
8586
// which determines the storage mechanism for the downloaded or seeding
8687
// data for the torrent. For more information, see the ``storage`` field.
8788
explicit add_torrent_params(storage_constructor_type sc = default_storage_constructor)
88-
: storage(sc) {}
89-
add_torrent_params(add_torrent_params&&) = default;
90-
add_torrent_params& operator=(add_torrent_params&&) = default;
89+
: storage(storage_constructor_type(sc)) {}
90+
add_torrent_params(add_torrent_params&&) noexcept = default;
91+
add_torrent_params& operator=(add_torrent_params&&) noexcept = default;
9192
add_torrent_params(add_torrent_params const&) = default;
9293
add_torrent_params& operator=(add_torrent_params const&) = default;
9394

@@ -285,18 +286,18 @@ namespace libtorrent {
285286

286287
// If the torrent doesn't have a tracker, but relies on the DHT to find
287288
// peers, the ``trackers`` can specify tracker URLs for the torrent.
288-
std::vector<std::string> trackers;
289+
aux::noexcept_movable<std::vector<std::string>> trackers;
289290

290291
// the tiers the URLs in ``trackers`` belong to. Trackers belonging to
291292
// different tiers may be treated differently, as defined by the multi
292293
// tracker extension. This is optional, if not specified trackers are
293294
// assumed to be part of tier 0, or whichever the last tier was as
294295
// iterating over the trackers.
295-
std::vector<int> tracker_tiers;
296+
aux::noexcept_movable<std::vector<int>> tracker_tiers;
296297

297298
// a list of hostname and port pairs, representing DHT nodes to be added
298299
// to the session (if DHT is enabled). The hostname may be an IP address.
299-
std::vector<std::pair<std::string, int>> dht_nodes;
300+
aux::noexcept_movable<std::vector<std::pair<std::string, int>>> dht_nodes;
300301

301302
std::string name;
302303

@@ -321,7 +322,11 @@ namespace libtorrent {
321322
// or encrypt the content on disk for instance. For more information
322323
// about the storage_interface that needs to be implemented for a custom
323324
// storage, see storage_interface.
325+
#ifdef __clang__
324326
storage_constructor_type storage;
327+
#else
328+
aux::noexcept_movable<storage_constructor_type> storage;
329+
#endif
325330

326331
// The ``userdata`` parameter is optional and will be passed on to the
327332
// extension constructor functions, if any
@@ -331,15 +336,15 @@ namespace libtorrent {
331336
// can be set to control the initial file priorities when adding a
332337
// torrent. The semantics are the same as for
333338
// ``torrent_handle::prioritize_files()``.
334-
std::vector<std::uint8_t> file_priorities;
339+
aux::noexcept_movable<std::vector<std::uint8_t>> file_priorities;
335340

336341
// torrent extension construction functions can be added to this vector
337342
// to have them be added immediately when the torrent is constructed.
338343
// This may be desired over the torrent_handle::add_extension() in order
339344
// to avoid race conditions. For instance it may be important to have the
340345
// plugin catch events that happen very early on after the torrent is
341346
// created.
342-
std::vector<std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>>
347+
aux::noexcept_movable<std::vector<std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>>>
343348
extensions;
344349

345350
// the default tracker id to be used when announcing to trackers. By
@@ -434,20 +439,20 @@ namespace libtorrent {
434439
//
435440
// url_seeds expects URLs to regular web servers, aka "get right" style,
436441
// specified in `BEP 19`_.
437-
std::vector<std::string> http_seeds;
438-
std::vector<std::string> url_seeds;
442+
aux::noexcept_movable<std::vector<std::string>> http_seeds;
443+
aux::noexcept_movable<std::vector<std::string>> url_seeds;
439444

440445
// peers to add to the torrent, to be tried to be connected to as
441446
// bittorrent peers.
442-
std::vector<tcp::endpoint> peers;
447+
aux::noexcept_movable<std::vector<tcp::endpoint>> peers;
443448

444449
// peers banned from this torrent. The will not be connected to
445-
std::vector<tcp::endpoint> banned_peers;
450+
aux::noexcept_movable<std::vector<tcp::endpoint>> banned_peers;
446451

447452
// this is a map of partially downloaded piece. The key is the piece index
448453
// and the value is a bitfield where each bit represents a 16 kiB block.
449454
// A set bit means we have that block.
450-
std::map<piece_index_t, bitfield> unfinished_pieces;
455+
aux::noexcept_movable<std::map<piece_index_t, bitfield>> unfinished_pieces;
451456

452457
// this is a bitfield indicating which pieces we already have of this
453458
// torrent.
@@ -462,16 +467,16 @@ namespace libtorrent {
462467
// element in the vector represent the piece with the same index. If you
463468
// set both file- and piece priorities, file priorities will take
464469
// precedence.
465-
std::vector<std::uint8_t> piece_priorities;
470+
aux::noexcept_movable<std::vector<std::uint8_t>> piece_priorities;
466471

467472
// if this is a merkle tree torrent, and you're seeding, this field must
468473
// be set. It is all the hashes in the binary tree, with the root as the
469474
// first entry. See torrent_info::set_merkle_tree() for more info.
470-
std::vector<sha1_hash> merkle_tree;
475+
aux::noexcept_movable<std::vector<sha1_hash>> merkle_tree;
471476

472477
// this is a map of file indices in the torrent and new filenames to be
473478
// applied before the torrent is added.
474-
std::map<file_index_t, std::string> renamed_files;
479+
aux::noexcept_movable<std::map<file_index_t, std::string>> renamed_files;
475480

476481
#ifndef TORRENT_NO_DEPRECATE
477482
// deprecated in 1.2
@@ -501,7 +506,7 @@ namespace libtorrent {
501506
// torrent_handle. See fast-resume_. The ``vector`` that is passed in
502507
// will be swapped into the running torrent instance with
503508
// ``std::vector::swap()``.
504-
std::vector<char> TORRENT_DEPRECATED_MEMBER resume_data;
509+
aux::noexcept_movable<std::vector<char>> TORRENT_DEPRECATED_MEMBER resume_data;
505510

506511
// to support the deprecated use case of reading the resume data into
507512
// resume_data field and getting a reject alert, any parse failure is
@@ -514,11 +519,24 @@ namespace libtorrent {
514519
std::string deprecated5;
515520
std::string deprecated1;
516521
std::string deprecated2;
517-
std::vector<char> deprecated3;
522+
aux::noexcept_movable<std::vector<char>> deprecated3;
518523
error_code deprecated4;
519524
#endif
520525

521526
};
527+
528+
static_assert(std::is_nothrow_move_constructible<add_torrent_params>::value
529+
, "should be nothrow move constructible");
530+
531+
// TODO: pre C++17, GCC and msvc does not make std::string nothrow move
532+
// assignable, which means no type containing a string will be nothrow move
533+
// assignable by default either
534+
// static_assert(std::is_nothrow_move_assignable<add_torrent_params>::value
535+
// , "should be nothrow move assignable");
536+
537+
// TODO: it would be nice if this was nothrow default constructible
538+
// static_assert(std::is_nothrow_default_constructible<add_torrent_params>::value
539+
// , "should be nothrow default constructible");
522540
}
523541

524542
#endif

include/libtorrent/alert.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace libtorrent {
7676

7777
alert(alert const& rhs) = delete;
7878
alert& operator=(alert const&) = delete;
79-
alert(alert&& rhs) = default;
79+
alert(alert&& rhs) noexcept = default;
8080

8181
#ifndef TORRENT_NO_DEPRECATE
8282
// only here for backwards compatibility

0 commit comments

Comments
 (0)