From 2dca174785ddbb80a45c5c6e72e2e4932712fbd2 Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 27 Apr 2017 23:44:08 -0400 Subject: [PATCH] improve span container constructor --- include/libtorrent/span.hpp | 38 +++++++++++- test/Jamfile | 1 + test/Makefile.am | 4 +- test/test_span.cpp | 112 ++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 test/test_span.cpp diff --git a/include/libtorrent/span.hpp b/include/libtorrent/span.hpp index 0bfe6375b..c63094b08 100644 --- a/include/libtorrent/span.hpp +++ b/include/libtorrent/span.hpp @@ -39,12 +39,35 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { +namespace aux { + + template + struct compatible_type + { + // conversions that are OK + // int -> int + // int const -> int const + // int -> int const + // int -> int volatile + // int -> int const volatile + // int volatile -> int const volatile + // int const -> int const volatile + + static const bool value = std::is_same::value + || std::is_same::type>::value + || std::is_same::type>::value + || std::is_same::type>::value + ; + }; +} + template struct span { span() : m_ptr(nullptr), m_len(0) {} - template + template ::value>::type> span(span const& v) // NOLINT : m_ptr(v.data()), m_len(v.size()) {} @@ -60,7 +83,10 @@ namespace libtorrent { : m_ptr(&arr[0]), m_len(N) {} // anything with a .data() member function is considered a container - template ().data())> + // but only if the value type is compatible with T + template ().data())>::type + , typename = typename std::enable_if::value>::type> span(Cont& c) // NOLINT : m_ptr(c.data()), m_len(c.size()) {} @@ -114,6 +140,14 @@ namespace libtorrent { T* m_ptr; std::size_t m_len; }; + + template + inline bool operator==(span const& lhs, span const& rhs) + { + return lhs.size() == rhs.size() + && (lhs.begin() == rhs.begin() || std::equal(lhs.begin(), lhs.end(), rhs.begin())); + } + } #endif // TORRENT_SPAN_HPP_INCLUDED diff --git a/test/Jamfile b/test/Jamfile index 2b878f58f..d7cc94c3b 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -158,6 +158,7 @@ test-suite libtorrent : ] [ run test_sha1_hash.cpp ] + [ run test_span.cpp ] [ run test_bitfield.cpp ] [ run test_crc32.cpp ] [ run test_ffs.cpp ] diff --git a/test/Makefile.am b/test/Makefile.am index e2af82ad3..4863e5c34 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -47,7 +47,8 @@ test_programs = \ test_linked_list \ test_direct_dht \ test_ffs \ - test_session_params + test_session_params \ + test_span if ENABLE_TESTS check_PROGRAMS = $(test_programs) @@ -241,6 +242,7 @@ test_linked_list_SOURCES = test_linked_list.cpp test_direct_dht_SOURCES = test_direct_dht.cpp test_ffs_SOURCES = test_ffs.cpp test_session_params_SOURCES = test_session_params.cpp +test_span_SOURCES = test_span.cpp LDADD = libtest.la $(top_builddir)/src/libtorrent-rasterbar.la diff --git a/test/test_span.cpp b/test/test_span.cpp new file mode 100644 index 000000000..f3d87cfc5 --- /dev/null +++ b/test/test_span.cpp @@ -0,0 +1,112 @@ +/* + +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. + +*/ + +#include "libtorrent/config.hpp" +#include "libtorrent/span.hpp" + +#include "test.hpp" +#include "setup_transfer.hpp" + +#include +#include + +using namespace lt; + +span f(span x) { return x; } +span> g(span> x) { return x; } + +TORRENT_TEST(span_vector) +{ + std::vector v1 = {1,2,3,4}; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 4); +} + +TORRENT_TEST(span_std_array) +{ + std::array v1{{1,2,3,4}}; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 4); +} + +TORRENT_TEST(span_const_std_array) +{ + std::array v1{{1,2,3,4}}; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 4); +} + +TORRENT_TEST(span_array) +{ + char v1[] = {1,2,3,4}; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 4); +} + +TORRENT_TEST(span_string) +{ + std::string v1 = "test"; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 4); +} + +TORRENT_TEST(span_const_array) +{ + char const v1[] = {1,2,3,4}; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 4); +} + +TORRENT_TEST(span_single_element) +{ + char const v1 = 1; + span a(v1); + TEST_CHECK(a == f(v1)); + TEST_CHECK(a.size() == 1); +} + +TORRENT_TEST(span_of_spans) +{ + std::vector v1 = {1,2,3,4}; + span s1(v1); + span > a(s1); + TEST_CHECK(a == g(s1)); + TEST_CHECK(a.size() == 1); + TEST_CHECK(a[0].size() == 4); +} +