1/*
2 Copyright (c) 2005-2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17// Tests for compatibility with the host's STL.
18
19#include "harness.h"
20
21template<typename Container>
22void TestSequence(const typename Container::allocator_type &a) {
23 Container c(a);
24 for( int i=0; i<1000; ++i )
25 c.push_back(i*i);
26 typename Container::const_iterator p = c.begin();
27 for( int i=0; i<1000; ++i ) {
28 ASSERT( *p==i*i, NULL );
29 ++p;
30 }
31 // regression test against compilation error for GCC 4.6.2
32 c.resize(1000);
33}
34
35template<typename Set>
36void TestSet(const typename Set::allocator_type &a) {
37 Set s(typename Set::key_compare(), a);
38 typedef typename Set::value_type value_type;
39 for( int i=0; i<100; ++i )
40 s.insert(value_type(3*i));
41 for( int i=0; i<300; ++i ) {
42 ASSERT( s.erase(i)==size_t(i%3==0), NULL );
43 }
44}
45
46template<typename Map>
47void TestMap(const typename Map::allocator_type &a) {
48 Map m(typename Map::key_compare(), a);
49 typedef typename Map::value_type value_type;
50 for( int i=0; i<100; ++i )
51 m.insert(value_type(i,i*i));
52 for( int i=0; i<100; ++i )
53 ASSERT( m.find(i)->second==i*i, NULL );
54}
55
56#include <deque>
57#include <list>
58#include <map>
59#include <set>
60#include <vector>
61
62#if __TBB_CPP11_RVALUE_REF_PRESENT
63struct MoveOperationTracker {
64 int my_value;
65
66 MoveOperationTracker( int value = 0 ) : my_value( value ) {}
67 MoveOperationTracker(const MoveOperationTracker&) {
68 ASSERT( false, "Copy constructor is called" );
69 }
70 MoveOperationTracker(MoveOperationTracker&& m) __TBB_NOEXCEPT( true ) : my_value( m.my_value ) {
71 }
72 MoveOperationTracker& operator=(MoveOperationTracker const&) {
73 ASSERT( false, "Copy assignment operator is called" );
74 return *this;
75 }
76 MoveOperationTracker& operator=(MoveOperationTracker&& m) __TBB_NOEXCEPT( true ) {
77 my_value = m.my_value;
78 return *this;
79 }
80
81 bool operator==(int value) const {
82 return my_value == value;
83 }
84
85 bool operator==(const MoveOperationTracker& m) const {
86 return my_value == m.my_value;
87 }
88};
89#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
90
91template<typename Allocator>
92void TestAllocatorWithSTL(const Allocator &a = Allocator() ) {
93
94// Allocator type conversion section
95#if __TBB_ALLOCATOR_TRAITS_PRESENT
96 typedef typename std::allocator_traits<Allocator>::template rebind_alloc<int> Ai;
97 typedef typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<const int, int> > Acii;
98#if _MSC_VER
99 typedef typename std::allocator_traits<Allocator>::template rebind_alloc<const int> Aci;
100 typedef typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<int, int> > Aii;
101#endif // _MSC_VER
102#else
103 typedef typename Allocator::template rebind<int>::other Ai;
104 typedef typename Allocator::template rebind<std::pair<const int, int> >::other Acii;
105#if _MSC_VER
106 typedef typename Allocator::template rebind<const int>::other Aci;
107 typedef typename Allocator::template rebind<std::pair<int, int> >::other Aii;
108#endif // _MSC_VER
109#endif // __TBB_ALLOCATOR_TRAITS_PRESENT
110
111 // Sequenced containers
112 TestSequence<std::deque <int,Ai> >(a);
113 TestSequence<std::list <int,Ai> >(a);
114 TestSequence<std::vector<int,Ai> >(a);
115
116#if __TBB_CPP11_RVALUE_REF_PRESENT
117#if __TBB_ALLOCATOR_TRAITS_PRESENT
118 typedef typename std::allocator_traits<Allocator>::template rebind_alloc<MoveOperationTracker> Amot;
119#else
120 typedef typename Allocator::template rebind<MoveOperationTracker>::other Amot;
121#endif // __TBB_ALLOCATOR_TRAITS_PRESENT
122 TestSequence<std::deque <MoveOperationTracker, Amot> >(a);
123 TestSequence<std::list <MoveOperationTracker, Amot> >(a);
124 TestSequence<std::vector<MoveOperationTracker, Amot> >(a);
125#endif // __TBB_CPP11_RVALUE_REF_PRESENT
126
127 // Associative containers
128 TestSet<std::set <int, std::less<int>, Ai> >(a);
129 TestSet<std::multiset<int, std::less<int>, Ai> >(a);
130 TestMap<std::map <int, int, std::less<int>, Acii> >(a);
131 TestMap<std::multimap<int, int, std::less<int>, Acii> >(a);
132
133#if _MSC_VER && _CPPLIB_VER < 650
134 // Test compatibility with Microsoft's implementation of std::allocator for some cases that
135 // are undefined according to the ISO standard but permitted by Microsoft.
136 TestSequence<std::deque <const int,Aci> >(a);
137#if _CPPLIB_VER>=500
138 TestSequence<std::list <const int,Aci> >(a);
139#endif
140 TestSequence<std::vector<const int,Aci> >(a);
141 TestSet<std::set<const int, std::less<int>, Aci> >(a);
142 TestMap<std::map<int, int, std::less<int>, Aii> >(a);
143 TestMap<std::map<const int, int, std::less<int>, Acii> >(a);
144 TestMap<std::multimap<int, int, std::less<int>, Aii> >(a);
145 TestMap<std::multimap<const int, int, std::less<int>, Acii> >(a);
146#endif /* _MSC_VER */
147}
148