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 #include <boost/interprocess/detail/config_begin.hpp>
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
main()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(test::get_process_id_name()); }
42 ~shm_remove(){ shared_memory_object::remove(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>("MyVector")
74 (IntAllocator(segment.get_segment_manager()));
75
76 //Fill vector
77 myvector->reserve(100);
78 for(int i = 0; i < 100; ++i){
79 myvector->push_back(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(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>("MyVector2")
100 (IntAllocator(segment.get_segment_manager()));
101
102 //Avoid reallocations
103 myvector2->reserve(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(it, itend, std::back_inserter(*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>("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(*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(myvector2);
132 segment.destroy_ptr(myvector);
133 segment.destroy_ptr(mystring);
134 return 0;
135 }
136 //]
137 #include <boost/interprocess/detail/config_end.hpp>
138