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/detail/workaround.hpp> |
12 | //[doc_vectorstream |
13 | #include <boost/interprocess/containers/vector.hpp> |
14 | #include <boost/interprocess/containers/string.hpp> |
15 | #include <boost/interprocess/allocators/allocator.hpp> |
16 | #include <boost/interprocess/managed_shared_memory.hpp> |
17 | #include <boost/interprocess/streams/vectorstream.hpp> |
18 | #include <iterator> |
19 | //<- |
20 | #include "../test/get_process_id_name.hpp" |
21 | //-> |
22 | |
23 | using namespace boost::interprocess; |
24 | |
25 | typedef allocator<int, managed_shared_memory::segment_manager> |
26 | IntAllocator; |
27 | typedef allocator<char, managed_shared_memory::segment_manager> |
28 | CharAllocator; |
29 | typedef vector<int, IntAllocator> MyVector; |
30 | typedef basic_string |
31 | <char, std::char_traits<char>, CharAllocator> MyString; |
32 | typedef basic_vectorstream<MyString> MyVectorStream; |
33 | |
34 | int main () |
35 | { |
36 | //Remove shared memory on construction and destruction |
37 | struct shm_remove |
38 | { |
39 | //<- |
40 | #if 1 |
41 | shm_remove() { shared_memory_object::remove(filename: test::get_process_id_name()); } |
42 | ~shm_remove(){ shared_memory_object::remove(filename: test::get_process_id_name()); } |
43 | #else |
44 | //-> |
45 | shm_remove() { shared_memory_object::remove("MySharedMemory" ); } |
46 | ~shm_remove(){ shared_memory_object::remove("MySharedMemory" ); } |
47 | //<- |
48 | #endif |
49 | //-> |
50 | } remover; |
51 | //<- |
52 | (void)remover; |
53 | //-> |
54 | |
55 | //<- |
56 | #if 1 |
57 | managed_shared_memory segment( |
58 | create_only, |
59 | test::get_process_id_name(), //segment name |
60 | 65536); //segment size in bytes |
61 | #else |
62 | //-> |
63 | managed_shared_memory segment( |
64 | create_only, |
65 | "MySharedMemory" , //segment name |
66 | 65536); //segment size in bytes |
67 | //<- |
68 | #endif |
69 | //-> |
70 | |
71 | //Construct shared memory vector |
72 | MyVector *myvector = |
73 | segment.construct<MyVector>(name: "MyVector" ) |
74 | (IntAllocator(segment.get_segment_manager())); |
75 | |
76 | //Fill vector |
77 | myvector->reserve(new_cap: 100); |
78 | for(int i = 0; i < 100; ++i){ |
79 | myvector->push_back(x: i); |
80 | } |
81 | |
82 | //Create the vectorstream. To create the internal shared memory |
83 | //basic_string we need to pass the shared memory allocator as |
84 | //a constructor argument |
85 | MyVectorStream myvectorstream(CharAllocator(segment.get_segment_manager())); |
86 | |
87 | //Reserve the internal string |
88 | myvectorstream.reserve(size: 100*5); |
89 | |
90 | //Write all vector elements as text in the internal string |
91 | //Data will be directly written in shared memory, because |
92 | //internal string's allocator is a shared memory allocator |
93 | for(std::size_t i = 0, max = myvector->size(); i < max; ++i){ |
94 | myvectorstream << (*myvector)[i] << std::endl; |
95 | } |
96 | |
97 | //Auxiliary vector to compare original data |
98 | MyVector *myvector2 = |
99 | segment.construct<MyVector>(name: "MyVector2" ) |
100 | (IntAllocator(segment.get_segment_manager())); |
101 | |
102 | //Avoid reallocations |
103 | myvector2->reserve(new_cap: 100); |
104 | |
105 | //Extract all values from the internal |
106 | //string directly to a shared memory vector. |
107 | std::istream_iterator<int> it(myvectorstream), itend; |
108 | std::copy(first: it, last: itend, result: std::back_inserter(x&: *myvector2)); |
109 | |
110 | //Compare vectors |
111 | assert(std::equal(myvector->begin(), myvector->end(), myvector2->begin())); |
112 | |
113 | //Create a copy of the internal string |
114 | MyString stringcopy (myvectorstream.vector()); |
115 | |
116 | //Now we create a new empty shared memory string... |
117 | MyString *mystring = |
118 | segment.construct<MyString>(name: "MyString" ) |
119 | (CharAllocator(segment.get_segment_manager())); |
120 | |
121 | //...and we swap vectorstream's internal string |
122 | //with the new one: after this statement mystring |
123 | //will be the owner of the formatted data. |
124 | //No reallocations, no data copies |
125 | myvectorstream.swap_vector(vect&: *mystring); |
126 | |
127 | //Let's compare both strings |
128 | assert(stringcopy == *mystring); |
129 | |
130 | //Done, destroy and delete vectors and string from the segment |
131 | segment.destroy_ptr(ptr: myvector2); |
132 | segment.destroy_ptr(ptr: myvector); |
133 | segment.destroy_ptr(ptr: mystring); |
134 | return 0; |
135 | } |
136 | //] |
137 | |
138 | |