summaryrefslogtreecommitdiff
path: root/libs/interprocess/test/named_construct_test.cpp
blob: acdd9b7bdb430c7083cd62d4dba34152769d5bc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <utility>

typedef std::pair<double, int> simple_pair;

using namespace boost::interprocess;

struct array_pair :  public simple_pair
{
   array_pair(double d, int i)
      :  simple_pair(d, i) {}
};

struct array_it_pair :  public array_pair
{
   array_it_pair(double d, int i)
      :  array_pair(d, i)  {}
};

struct named_name_generator
{
   static const bool searchable = true;

   typedef simple_pair     simple_type;
   typedef array_pair      array_type;
   typedef array_it_pair   array_it_type;
   static const char *get_simple_name()
   {  return "MyType instance";  }
   static const char *get_array_name()
   {  return "MyType array";  }
   static const char *get_array_it_name()
   {  return "MyType array from it";   }
};

struct unique_name_generator
{
   static const bool searchable = true;

   typedef simple_pair     simple_type;
   typedef array_pair      array_type;
   typedef array_it_pair   array_it_type;
   static const ipcdetail::unique_instance_t *get_simple_name()
   {  return 0;  }
   static const ipcdetail::unique_instance_t *get_array_name()
   {  return 0;  }
   static const ipcdetail::unique_instance_t *get_array_it_name()
   {  return 0;  }
};

struct anonymous_name_generator
{
   static const bool searchable = false;

   typedef simple_pair simple_type;
   typedef array_pair array_type;
   typedef array_it_pair array_it_type;
   static const ipcdetail::anonymous_instance_t *get_simple_name()
   {  return 0;  }
   static const ipcdetail::anonymous_instance_t *get_array_name()
   {  return 0;  }
   static const ipcdetail::anonymous_instance_t *get_array_it_name()
   {  return 0;  }
};


template<class NameGenerator>
int construct_test()
{
   typedef typename NameGenerator::simple_type     simple_type;
   typedef typename NameGenerator::array_type      array_type;
   typedef typename NameGenerator::array_it_type   array_it_type;

   remove_shared_memory_on_destroy remover("MySharedMemory");
   shared_memory_object::remove("MySharedMemory");
   {
      //A special shared memory where we can
      //construct objects associated with a name.
      //First remove any old shared memory of the same name, create
      //the shared memory segment and initialize needed resources
      managed_shared_memory segment
         //create       segment name    segment size
         (create_only, "MySharedMemory", 65536);

      //Create an object of MyType initialized to {0.0, 0}
      simple_type *s = segment.construct<simple_type>
         (NameGenerator::get_simple_name())//name of the object
         (1.0, 2);            //ctor first argument
      assert(s->first == 1.0 && s->second == 2);
      if(!(s->first == 1.0 && s->second == 2))
         return 1;

      //Create an array of 10 elements of MyType initialized to {0.0, 0}
      array_type *a = segment.construct<array_type>
         (NameGenerator::get_array_name()) //name of the object
         [10]                 //number of elements
         (3.0, 4);            //Same two ctor arguments for all objects
      assert(a->first == 3.0 && a->second == 4);
      if(!(a->first == 3.0 && a->second == 4))
         return 1;

      //Create an array of 3 elements of MyType initializing each one
      //to a different value {0.0, 3}, {1.0, 4}, {2.0, 5}...
      float float_initializer[3] = { 0.0, 1.0, 2.0 };
      int   int_initializer[3]   = { 3, 4, 5 };

      array_it_type *a_it = segment.construct_it<array_it_type>
         (NameGenerator::get_array_it_name()) //name of the object
         [3]                        //number of elements
         ( &float_initializer[0]    //Iterator for the 1st ctor argument
         , &int_initializer[0]);    //Iterator for the 2nd ctor argument
      {
         const array_it_type *a_it_ptr = a_it;
         for(unsigned int i = 0, max = 3; i != max; ++i, ++a_it_ptr){
            assert(a_it_ptr->first == float_initializer[i]);
            if(a_it_ptr->first != float_initializer[i]){
               return 1;
            }
            assert(a_it_ptr->second == int_initializer[i]);
            if(a_it_ptr->second != int_initializer[i]){
               return 1;
            }
         }
      }

      if(NameGenerator::searchable){
         {
            std::pair<simple_type*, managed_shared_memory::size_type> res;
            //Find the object
            res = segment.find<simple_type> (NameGenerator::get_simple_name());
            //Length should be 1
            assert(res.second == 1);
            if(res.second != 1)
               return 1;
            assert(res.first == s);
            if(res.first != s)
               return 1;
         }
         {
            std::pair<array_type*, managed_shared_memory::size_type> res;

            //Find the array
            res = segment.find<array_type> (NameGenerator::get_array_name());
            //Length should be 10
            assert(res.second == 10);
            if(res.second != 10)
               return 1;
            assert(res.first == a);
            if(res.first != a)
               return 1;
         }
         {
            std::pair<array_it_type*, managed_shared_memory::size_type> res;
            //Find the array constructed from iterators
            res = segment.find<array_it_type> (NameGenerator::get_array_it_name());
            //Length should be 3
            assert(res.second == 3);
            if(res.second != 3)
               return 1;
            assert(res.first == a_it);
            if(res.first != a_it)
               return 1;
         }
      }
      //We're done, delete all the objects
      segment.destroy_ptr<simple_type>(s);
      segment.destroy_ptr<array_type>(a);
      segment.destroy_ptr<array_it_type>(a_it);
   }
   return 0;
}

int main ()
{
   if(0 != construct_test<named_name_generator>())
      return 1;
   if(0 != construct_test<unique_name_generator>())
      return 1;
   if(0 != construct_test<anonymous_name_generator>())
      return 1;
   return 0;
}

//]
#include <boost/interprocess/detail/config_end.hpp>