1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <memory>
11
12// template <class T> struct owner_less;
13//
14// template <class T>
15// struct owner_less<shared_ptr<T> >
16//     : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
17// {
18//     typedef bool result_type;
19//     bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
20//     bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
21//     bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
22// };
23//
24// template <class T>
25// struct owner_less<weak_ptr<T> >
26//     : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
27// {
28//     typedef bool result_type;
29//     bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
30//     bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
31//     bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
32// };
33//
34// Added in C++17
35// template<> struct owner_less<void>
36// {
37//     template<class T, class U>
38//         bool operator()(shared_ptr<T> const&, shared_ptr<U> const&) const noexcept;
39//     template<class T, class U>
40//         bool operator()(shared_ptr<T> const&, weak_ptr<U> const&) const noexcept;
41//     template<class T, class U>
42//         bool operator()(weak_ptr<T> const&, shared_ptr<U> const&) const noexcept;
43//     template<class T, class U>
44//         bool operator()(weak_ptr<T> const&, weak_ptr<U> const&) const noexcept;
45//
46//     typedef unspecified is_transparent;
47// };
48
49#include <memory>
50#include <cassert>
51#include <set>
52#include "test_macros.h"
53
54struct X {};
55
56int main()
57{
58    const std::shared_ptr<int> p1(new int);
59    const std::shared_ptr<int> p2 = p1;
60    const std::shared_ptr<int> p3(new int);
61    const std::weak_ptr<int> w1(p1);
62    const std::weak_ptr<int> w2(p2);
63    const std::weak_ptr<int> w3(p3);
64
65    {
66    typedef std::owner_less<std::shared_ptr<int> > CS;
67    CS cs;
68
69    static_assert((std::is_same<std::shared_ptr<int>, CS::first_argument_type>::value), "" );
70    static_assert((std::is_same<std::shared_ptr<int>, CS::second_argument_type>::value), "" );
71    static_assert((std::is_same<bool, CS::result_type>::value), "" );
72
73    assert(!cs(p1, p2));
74    assert(!cs(p2, p1));
75    assert(cs(p1 ,p3) || cs(p3, p1));
76    assert(cs(p3, p1) == cs(p3, p2));
77    ASSERT_NOEXCEPT(cs(p1, p1));
78
79    assert(!cs(p1, w2));
80    assert(!cs(p2, w1));
81    assert(cs(p1, w3) || cs(p3, w1));
82    assert(cs(p3, w1) == cs(p3, w2));
83    ASSERT_NOEXCEPT(cs(p1, w1));
84    ASSERT_NOEXCEPT(cs(w1, p1));
85    }
86    {
87    typedef std::owner_less<std::weak_ptr<int> > CS;
88    CS cs;
89
90    static_assert((std::is_same<std::weak_ptr<int>, CS::first_argument_type>::value), "" );
91    static_assert((std::is_same<std::weak_ptr<int>, CS::second_argument_type>::value), "" );
92    static_assert((std::is_same<bool, CS::result_type>::value), "" );
93
94    assert(!cs(w1, w2));
95    assert(!cs(w2, w1));
96    assert(cs(w1, w3) || cs(w3, w1));
97    assert(cs(w3, w1) == cs(w3, w2));
98    ASSERT_NOEXCEPT(cs(w1, w1));
99
100    assert(!cs(w1, p2));
101    assert(!cs(w2, p1));
102    assert(cs(w1, p3) || cs(w3, p1));
103    assert(cs(w3, p1) == cs(w3, p2));
104    ASSERT_NOEXCEPT(cs(w1, p1));
105    ASSERT_NOEXCEPT(cs(p1, w1));
106    }
107#if TEST_STD_VER > 14
108    {
109    std::shared_ptr<int> sp1;
110    std::shared_ptr<void> sp2;
111    std::shared_ptr<long> sp3;
112    std::weak_ptr<int> wp1;
113
114    std::owner_less<> cmp;
115    assert(!cmp(sp1, sp2));
116    assert(!cmp(sp1, wp1));
117    assert(!cmp(sp1, sp3));
118    assert(!cmp(wp1, sp1));
119    assert(!cmp(wp1, wp1));
120    ASSERT_NOEXCEPT(cmp(sp1, sp1));
121    ASSERT_NOEXCEPT(cmp(sp1, wp1));
122    ASSERT_NOEXCEPT(cmp(wp1, sp1));
123    ASSERT_NOEXCEPT(cmp(wp1, wp1));
124    }
125    {
126    // test heterogeneous lookups
127    std::set<std::shared_ptr<X>, std::owner_less<>> s;
128    std::shared_ptr<void> vp;
129    assert(s.find(vp) == s.end());
130    }
131#endif
132}
133