]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/stl_interfaces/test/array.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / stl_interfaces / test / array.cpp
diff --git a/ceph/src/boost/libs/stl_interfaces/test/array.cpp b/ceph/src/boost/libs/stl_interfaces/test/array.cpp
new file mode 100644 (file)
index 0000000..66b34d5
--- /dev/null
@@ -0,0 +1,589 @@
+// Copyright (C) 2019 T. Zachary Laine
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/stl_interfaces/sequence_container_interface.hpp>
+
+#include "ill_formed.hpp"
+
+#include <boost/core/lightweight_test.hpp>
+
+#include <array>
+#include <deque>
+#include <vector>
+
+
+// Just like std::array, except for the 0-size specialization, and the fact
+// that the base class makes brace-initialization wonky.
+template<typename T, std::size_t N>
+struct array : boost::stl_interfaces::sequence_container_interface<
+                   array<T, N>,
+                   boost::stl_interfaces::v1::element_layout::contiguous>
+{
+    using value_type = T;
+    using pointer = T *;
+    using const_pointer = T const *;
+    using reference = value_type &;
+    using const_reference = value_type const &;
+    using size_type = std::size_t;
+    using difference_type = std::ptrdiff_t;
+    using iterator = T *;
+    using const_iterator = T const *;
+    using reverse_iterator = boost::stl_interfaces::reverse_iterator<iterator>;
+    using const_reverse_iterator =
+        boost::stl_interfaces::reverse_iterator<const_iterator>;
+
+    void fill(T const & x) { std::fill(begin(), end(), x); }
+
+    iterator begin() noexcept { return elements_; }
+    iterator end() noexcept { return elements_ + N; }
+
+    size_type max_size() const noexcept { return N; }
+
+    void swap(array & other)
+    {
+        using std::swap;
+        T * element = elements_;
+        for (auto & x : other) {
+            swap(*element++, x);
+        }
+    }
+
+    using base_type = boost::stl_interfaces::sequence_container_interface<
+        array<T, N>,
+        boost::stl_interfaces::v1::element_layout::contiguous>;
+    using base_type::begin;
+    using base_type::end;
+
+    T elements_[N];
+};
+
+using arr_type = array<int, 5>;
+
+
+void test_comparisons()
+{
+    arr_type sm;
+    sm[0] = 1;
+    sm[1] = 2;
+    sm[2] = 3;
+    sm[3] = 0;
+    sm[4] = 0;
+    arr_type md;
+    md[0] = 1;
+    md[1] = 2;
+    md[2] = 3;
+    md[3] = 4;
+    md[4] = 0;
+    arr_type lg;
+    lg[0] = 1;
+    lg[1] = 2;
+    lg[2] = 3;
+    lg[3] = 4;
+    lg[4] = 5;
+
+    BOOST_TEST(sm == sm);
+    BOOST_TEST(!(sm == md));
+    BOOST_TEST(!(sm == lg));
+
+    BOOST_TEST(!(sm != sm));
+    BOOST_TEST(sm != md);
+    BOOST_TEST(sm != lg);
+
+    BOOST_TEST(!(sm < sm));
+    BOOST_TEST(sm < md);
+    BOOST_TEST(sm < lg);
+
+    BOOST_TEST(sm <= sm);
+    BOOST_TEST(sm <= md);
+    BOOST_TEST(sm <= lg);
+
+    BOOST_TEST(!(sm > sm));
+    BOOST_TEST(!(sm > md));
+    BOOST_TEST(!(sm > lg));
+
+    BOOST_TEST(sm >= sm);
+    BOOST_TEST(!(sm >= md));
+    BOOST_TEST(!(sm >= lg));
+
+
+    BOOST_TEST(!(md == sm));
+    BOOST_TEST(md == md);
+    BOOST_TEST(!(md == lg));
+
+    BOOST_TEST(!(md < sm));
+    BOOST_TEST(!(md < md));
+    BOOST_TEST(md < lg);
+
+    BOOST_TEST(!(md <= sm));
+    BOOST_TEST(md <= md);
+    BOOST_TEST(md <= lg);
+
+    BOOST_TEST(md > sm);
+    BOOST_TEST(!(md > md));
+    BOOST_TEST(!(md > lg));
+
+    BOOST_TEST(md >= sm);
+    BOOST_TEST(md >= md);
+    BOOST_TEST(!(md >= lg));
+
+
+    BOOST_TEST(!(lg == sm));
+    BOOST_TEST(!(lg == md));
+    BOOST_TEST(lg == lg);
+
+    BOOST_TEST(!(lg < sm));
+    BOOST_TEST(!(lg < md));
+    BOOST_TEST(!(lg < lg));
+
+    BOOST_TEST(!(lg <= sm));
+    BOOST_TEST(!(lg <= md));
+    BOOST_TEST(lg <= lg);
+
+    BOOST_TEST(lg > sm);
+    BOOST_TEST(lg > md);
+    BOOST_TEST(!(lg > lg));
+
+    BOOST_TEST(lg >= sm);
+    BOOST_TEST(lg >= md);
+    BOOST_TEST(lg >= lg);
+}
+
+
+void test_swap()
+{
+    {
+        arr_type v1;
+        v1[0] = 3;
+        v1[1] = 4;
+        v1[2] = 0;
+        v1[3] = 0;
+        v1[4] = 0;
+        arr_type v2;
+        v2[0] = 4;
+        v2[1] = 3;
+        v2[2] = 0;
+        v2[3] = 0;
+        v2[4] = 0;
+
+        arr_type const v1_copy = v1;
+        arr_type const v2_copy = v2;
+
+        static_assert(std::is_same<decltype(v1.swap(v2)), void>::value, "");
+        static_assert(std::is_same<decltype(swap(v1, v2)), void>::value, "");
+
+        v1.swap(v2);
+
+        BOOST_TEST(v1 == v2_copy);
+        BOOST_TEST(v2 == v1_copy);
+    }
+
+    {
+        arr_type v1;
+        v1[0] = 3;
+        v1[1] = 4;
+        v1[2] = 0;
+        v1[3] = 0;
+        v1[4] = 0;
+        arr_type v2;
+        v2[0] = 4;
+        v2[1] = 3;
+        v2[2] = 0;
+        v2[3] = 0;
+        v2[4] = 0;
+
+        arr_type const v1_copy = v1;
+        arr_type const v2_copy = v2;
+
+        swap(v1, v2);
+
+        BOOST_TEST(v1 == v2_copy);
+        BOOST_TEST(v2 == v1_copy);
+    }
+}
+
+template<typename Iter>
+using writable_iter_t = decltype(
+    *std::declval<Iter>() =
+        std::declval<typename std::iterator_traits<Iter>::value_type>());
+
+static_assert(
+    !ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().begin())>::
+        value,
+    "");
+static_assert(
+    !ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().end())>::
+        value,
+    "");
+
+static_assert(
+    ill_formed<
+        writable_iter_t,
+        decltype(std::declval<arr_type const &>().begin())>::value,
+    "");
+static_assert(
+    ill_formed<
+        writable_iter_t,
+        decltype(std::declval<arr_type const &>().end())>::value,
+    "");
+static_assert(
+    ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().cbegin())>::
+        value,
+    "");
+static_assert(
+    ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().cend())>::
+        value,
+    "");
+
+static_assert(
+    ill_formed<
+        writable_iter_t,
+        decltype(std::declval<arr_type const &>().rbegin())>::value,
+    "");
+static_assert(
+    ill_formed<
+        writable_iter_t,
+        decltype(std::declval<arr_type const &>().rend())>::value,
+    "");
+static_assert(
+    ill_formed<
+        writable_iter_t,
+        decltype(std::declval<arr_type &>().crbegin())>::value,
+    "");
+static_assert(
+    ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().crend())>::
+        value,
+    "");
+
+void test_iterators()
+{
+    arr_type v0;
+    v0[0] = 3;
+    v0[1] = 2;
+    v0[2] = 1;
+    v0[3] = 0;
+    v0[4] = 0;
+
+    {
+        arr_type v = v0;
+
+        static_assert(
+            std::is_same<decltype(v.begin()), arr_type::iterator>::value, "");
+        static_assert(
+            std::is_same<decltype(v.end()), arr_type::iterator>::value, "");
+        static_assert(
+            std::is_same<decltype(v.cbegin()), arr_type::const_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<decltype(v.cend()), arr_type::const_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<decltype(v.rbegin()), arr_type::reverse_iterator>::
+                value,
+            "");
+        static_assert(
+            std::is_same<decltype(v.rbegin()), arr_type::reverse_iterator>::
+                value,
+            "");
+        static_assert(
+            std::is_same<
+                decltype(v.crbegin()),
+                arr_type::const_reverse_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<
+                decltype(v.crbegin()),
+                arr_type::const_reverse_iterator>::value,
+            "");
+
+        std::array<int, 5> const a = {{3, 2, 1, 0, 0}};
+        std::array<int, 5> const ra = {{0, 0, 1, 2, 3}};
+
+        BOOST_TEST(std::equal(v.begin(), v.end(), a.begin(), a.end()));
+        BOOST_TEST(std::equal(v.cbegin(), v.cend(), a.begin(), a.end()));
+
+        BOOST_TEST(std::equal(v.rbegin(), v.rend(), ra.begin(), ra.end()));
+        BOOST_TEST(std::equal(v.crbegin(), v.crend(), ra.begin(), ra.end()));
+
+        arr_type v2;
+        v2[0] = 8;
+        v2[1] = 2;
+        v2[2] = 1;
+        v2[3] = 0;
+        v2[4] = 9;
+
+        *v.begin() = 8;
+        *v.rbegin() = 9;
+        BOOST_TEST(v == v2);
+    }
+
+    {
+        arr_type const v = v0;
+
+        static_assert(
+            std::is_same<decltype(v.begin()), arr_type::const_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<decltype(v.end()), arr_type::const_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<decltype(v.cbegin()), arr_type::const_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<decltype(v.cend()), arr_type::const_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<
+                decltype(v.rbegin()),
+                arr_type::const_reverse_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<
+                decltype(v.rbegin()),
+                arr_type::const_reverse_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<
+                decltype(v.crbegin()),
+                arr_type::const_reverse_iterator>::value,
+            "");
+        static_assert(
+            std::is_same<
+                decltype(v.crbegin()),
+                arr_type::const_reverse_iterator>::value,
+            "");
+
+        std::array<int, 5> const a = {{3, 2, 1, 0, 0}};
+        std::array<int, 5> const ra = {{0, 0, 1, 2, 3}};
+
+        BOOST_TEST(std::equal(v.begin(), v.end(), a.begin(), a.end()));
+        BOOST_TEST(std::equal(v.cbegin(), v.cend(), a.begin(), a.end()));
+
+        BOOST_TEST(std::equal(v.rbegin(), v.rend(), ra.begin(), ra.end()));
+        BOOST_TEST(std::equal(v.crbegin(), v.crend(), ra.begin(), ra.end()));
+    }
+}
+
+
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using lvalue_push_front_t = decltype(
+    std::declval<Container &>().push_front(std::declval<ValueType const &>()));
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using rvalue_push_front_t = decltype(std::declval<Container &>().push_front(0));
+template<typename Container>
+using pop_front_t = decltype(std::declval<Container &>().pop_front());
+
+static_assert(ill_formed<lvalue_push_front_t, arr_type>::value, "");
+static_assert(ill_formed<rvalue_push_front_t, arr_type>::value, "");
+static_assert(ill_formed<pop_front_t, arr_type>::value, "");
+
+using std_deq_int = std::deque<int>;
+
+static_assert(!ill_formed<lvalue_push_front_t, std_deq_int>::value, "");
+static_assert(!ill_formed<rvalue_push_front_t, std_deq_int>::value, "");
+static_assert(!ill_formed<pop_front_t, std_deq_int>::value, "");
+
+
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using lvalue_push_back_t = decltype(
+    std::declval<Container &>().push_back(std::declval<ValueType const &>()));
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using rvalue_push_back_t = decltype(std::declval<Container &>().push_back(0));
+template<typename Container>
+using pop_back_t = decltype(std::declval<Container &>().pop_back());
+
+static_assert(ill_formed<lvalue_push_back_t, arr_type>::value, "");
+static_assert(ill_formed<rvalue_push_back_t, arr_type>::value, "");
+static_assert(ill_formed<pop_back_t, arr_type>::value, "");
+
+using std_vec_int = std::vector<int>;
+
+static_assert(!ill_formed<lvalue_push_back_t, std_vec_int>::value, "");
+static_assert(!ill_formed<rvalue_push_back_t, std_vec_int>::value, "");
+static_assert(!ill_formed<pop_back_t, std_vec_int>::value, "");
+
+
+void test_front_back()
+{
+    {
+        arr_type v;
+        v[0] = 0;
+        v[1] = 0;
+        v[2] = 0;
+        v[3] = 0;
+        v[4] = 0;
+
+        static_assert(std::is_same<decltype(v.front()), int &>::value, "");
+        static_assert(std::is_same<decltype(v.back()), int &>::value, "");
+
+        v.front() = 9;
+        v.back() = 8;
+        BOOST_TEST(v[0] == v.front());
+        BOOST_TEST(v[4] == v.back());
+    }
+
+    {
+        arr_type v0;
+        v0[0] = 3;
+        v0[1] = 0;
+        v0[2] = 2;
+        v0[3] = 0;
+        v0[4] = 1;
+
+        arr_type const v = v0;
+        BOOST_TEST(v.front() == 3);
+        BOOST_TEST(v.back() == 1);
+
+        static_assert(
+            std::is_same<decltype(v.front()), int const &>::value, "");
+        static_assert(std::is_same<decltype(v.back()), int const &>::value, "");
+    }
+}
+
+
+void test_cindex_at()
+{
+    arr_type v0;
+    v0[0] = 3;
+    v0[1] = 2;
+    v0[2] = 1;
+    v0[3] = 0;
+    v0[4] = 0;
+
+    {
+        arr_type v = v0;
+        BOOST_TEST(v[0] == 3);
+        BOOST_TEST(v[1] == 2);
+        BOOST_TEST(v[2] == 1);
+        BOOST_TEST_NO_THROW(v.at(0));
+        BOOST_TEST_NO_THROW(v.at(1));
+        BOOST_TEST_NO_THROW(v.at(2));
+        BOOST_TEST_THROWS(v.at(5), std::out_of_range);
+
+        static_assert(std::is_same<decltype(v[0]), int &>::value, "");
+        static_assert(std::is_same<decltype(v.at(0)), int &>::value, "");
+
+        v[0] = 8;
+        v.at(1) = 9;
+        BOOST_TEST(v[0] == 8);
+        BOOST_TEST(v[1] == 9);
+    }
+
+    {
+        arr_type const v = v0;
+        BOOST_TEST(v[0] == 3);
+        BOOST_TEST(v[1] == 2);
+        BOOST_TEST(v[2] == 1);
+        BOOST_TEST_NO_THROW(v.at(0));
+        BOOST_TEST_NO_THROW(v.at(1));
+        BOOST_TEST_NO_THROW(v.at(2));
+        BOOST_TEST_THROWS(v.at(5), std::out_of_range);
+
+        static_assert(std::is_same<decltype(v[0]), int const &>::value, "");
+        static_assert(std::is_same<decltype(v.at(0)), int const &>::value, "");
+    }
+}
+
+
+template<typename Container>
+using resize_t = decltype(std::declval<Container &>().resize(0));
+
+static_assert(ill_formed<resize_t, arr_type>::value, "");
+
+static_assert(!ill_formed<resize_t, std_vec_int>::value, "");
+
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using lvalue_insert_t = decltype(std::declval<Container &>().insert(
+    std::declval<Container &>().begin(), std::declval<ValueType const &>()));
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using rvalue_insert_t = decltype(std::declval<Container &>().insert(
+    std::declval<Container &>().begin(), std::declval<ValueType &&>()));
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using insert_n_t = decltype(std::declval<Container &>().insert(
+    std::declval<Container &>().begin(), 2, std::declval<ValueType const &>()));
+template<
+    typename Container,
+    typename ValueType = typename Container::value_type>
+using insert_il_t = decltype(std::declval<Container &>().insert(
+    std::declval<Container &>().begin(), std::initializer_list<int>{}));
+
+static_assert(ill_formed<lvalue_insert_t, arr_type>::value, "");
+static_assert(ill_formed<rvalue_insert_t, arr_type>::value, "");
+
+// TODO: Broken in v1.  Adding the proper constraint ICE's GCC 8, or
+// infinitely recurses within the compiler for GCC and Clang, depending on the
+// constraint technique used.
+#if 0
+static_assert(ill_formed<insert_n_t, arr_type>::value, "");
+#endif
+
+static_assert(ill_formed<insert_il_t, arr_type>::value, "");
+
+static_assert(!ill_formed<lvalue_insert_t, std_vec_int>::value, "");
+static_assert(!ill_formed<rvalue_insert_t, std_vec_int>::value, "");
+static_assert(!ill_formed<insert_n_t, std_vec_int>::value, "");
+static_assert(!ill_formed<insert_il_t, std_vec_int>::value, "");
+
+
+template<typename Container>
+using erase_t = decltype(
+    std::declval<Container &>().erase(std::declval<Container &>().begin()));
+
+static_assert(ill_formed<erase_t, arr_type>::value, "");
+
+static_assert(!ill_formed<erase_t, std_vec_int>::value, "");
+
+
+template<typename Container>
+using assign_t = decltype(std::declval<Container &>().assign(
+    std::declval<int *>(), std::declval<int *>()));
+template<typename Container>
+using assign_n_t = decltype(std::declval<Container &>().assign(5, 5));
+template<typename Container>
+using assign_il_t =
+    decltype(std::declval<Container &>().assign(std::initializer_list<int>{}));
+template<typename Container>
+using assignment_operator_il_t =
+    decltype(std::declval<Container &>() = std::initializer_list<int>{});
+
+static_assert(ill_formed<assign_t, arr_type>::value, "");
+static_assert(ill_formed<assign_n_t, arr_type>::value, "");
+static_assert(ill_formed<assign_il_t, arr_type>::value, "");
+static_assert(ill_formed<assignment_operator_il_t, arr_type>::value, "");
+
+static_assert(!ill_formed<assign_t, std_vec_int>::value, "");
+static_assert(!ill_formed<assign_n_t, std_vec_int>::value, "");
+static_assert(!ill_formed<assign_il_t, std_vec_int>::value, "");
+static_assert(!ill_formed<assignment_operator_il_t, std_vec_int>::value, "");
+
+template<typename Container>
+using clear_t = decltype(std::declval<Container &>().clear());
+
+static_assert(ill_formed<clear_t, arr_type>::value, "");
+
+static_assert(!ill_formed<clear_t, std_vec_int>::value, "");
+
+int main()
+{
+    test_comparisons();
+    test_swap();
+    test_iterators();
+    test_front_back();
+    test_cindex_at();
+    return boost::report_errors();
+}