1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #include <boost/interprocess/offset_ptr.hpp>
12 #include <boost/interprocess/smart_ptr/unique_ptr.hpp>
13 #include <boost/interprocess/managed_shared_memory.hpp>
14 #include <boost/interprocess/allocators/allocator.hpp>
15 #include <boost/interprocess/containers/list.hpp>
16 #include <boost/interprocess/containers/set.hpp>
17 #include <boost/interprocess/containers/vector.hpp>
18 #include <boost/interprocess/smart_ptr/deleter.hpp>
19 #include <stdio.h>
20 #include <string>
21 #include "get_process_id_name.hpp"
22
23 using namespace boost::interprocess;
24
25 class MyClass
26 {
27 public:
MyClass()28 MyClass()
29 {}
30 };
31
32 typedef managed_unique_ptr<MyClass, managed_shared_memory>::type my_unique_ptr_class;
33 typedef set <my_unique_ptr_class
34 ,std::less<my_unique_ptr_class>
35 ,allocator <my_unique_ptr_class
36 ,managed_shared_memory::segment_manager>
37 > MySet;
38
39 typedef list<my_unique_ptr_class
40 ,allocator <my_unique_ptr_class
41 ,managed_shared_memory::segment_manager>
42 > MyList;
43
44 typedef vector <my_unique_ptr_class
45 ,allocator <my_unique_ptr_class
46 ,managed_shared_memory::segment_manager>
47 > MyVector;
48
main()49 int main()
50 {
51 std::string process_name;
52 test::get_process_id_name(process_name);
53
54 //Create managed shared memory
55 shared_memory_object::remove(process_name.c_str());
56 {
57 managed_shared_memory segment(create_only, process_name.c_str(), 10000);
58
59 //Create unique_ptr using dynamic allocation
60 my_unique_ptr_class my_ptr (segment.construct<MyClass>(anonymous_instance)()
61 ,segment.get_deleter<MyClass>());
62 my_unique_ptr_class my_ptr2(segment.construct<MyClass>(anonymous_instance)()
63 ,segment.get_deleter<MyClass>());
64
65 //Backup relative pointers to future tests
66 offset_ptr<MyClass> ptr1 = my_ptr.get();
67 offset_ptr<MyClass> ptr2 = my_ptr2.get();
68
69 //Test some copy constructors
70 my_unique_ptr_class my_ptr3(0, segment.get_deleter<MyClass>());
71 my_unique_ptr_class my_ptr4(boost::move(my_ptr3));
72
73 //Construct a list and fill
74 MyList list(segment.get_segment_manager());
75
76 //Insert from my_unique_ptr_class
77 list.push_front(boost::move(my_ptr));
78 list.push_back(boost::move(my_ptr2));
79
80 //Check pointers
81 assert(my_ptr.get() == 0);
82 assert(my_ptr2.get() == 0);
83 assert(list.begin()->get() == ptr1);
84 assert(list.rbegin()->get() == ptr2);
85
86 //Construct a set and fill
87 typedef std::less<my_unique_ptr_class> set_less_t;
88 MySet set(set_less_t(), segment.get_segment_manager());
89
90 //Insert in set from list passing ownership
91 set.insert(boost::move(*list.begin()));
92 set.insert(boost::move(*list.rbegin()));
93
94 //Check pointers
95 assert(list.begin()->get() == 0);
96 assert(list.rbegin()->get()== 0);
97
98 //A set is ordered by std::less<my_unique_ptr_class> so
99 //be careful when comparing pointers
100 if(ptr1 < ptr2){
101 assert(set.begin()->get() == ptr1);
102 assert(set.rbegin()->get() == ptr2);
103 }
104 else{
105 assert(set.rbegin()->get() == ptr1);
106 assert(set.begin()->get() == ptr2);
107 }
108
109 //Now with vector
110 MyVector vector(segment.get_segment_manager());
111
112 //Insert from my_unique_ptr_class
113 if(ptr1 < ptr2){
114 vector.insert(vector.begin(), boost::move(*set.begin()));
115 vector.insert(vector.end(), boost::move(*set.rbegin()));
116 }
117 else{
118 vector.insert(vector.begin(), boost::move(*set.rbegin()));
119 vector.insert(vector.end(), boost::move(*set.begin()));
120 }
121
122 //Check pointers
123 assert(my_ptr.get() == 0);
124 assert(my_ptr2.get() == 0);
125 assert(vector.begin()->get() == ptr1);
126 assert(vector.rbegin()->get() == ptr2);
127
128 MyVector vector2(boost::move(vector));
129 vector2.swap(vector);
130
131 assert(vector.begin()->get() == ptr1);
132 assert(vector.rbegin()->get() == ptr2);
133
134 my_unique_ptr_class a(0, segment.get_deleter<MyClass>()), b(0, segment.get_deleter<MyClass>());
135 a = boost::move(b);
136 }
137 shared_memory_object::remove(process_name.c_str());
138 return 0;
139 }
140