1 
2 // Copyright 2009 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // clang-format off
7 #include "../helpers/prefix.hpp"
8 #include <boost/unordered_map.hpp>
9 #include <boost/unordered_set.hpp>
10 #include "../helpers/postfix.hpp"
11 // clang-format on
12 
13 #include <utility>
14 
15 namespace x {
16   struct D
17   {
18     boost::unordered_map<D, D> x;
19   };
20 }
21 
22 namespace incomplete_test {
23   // Declare, but don't define some types.
24 
25   struct value;
26   struct hash;
27   struct equals;
28   template <class T> struct allocator;
29 
30   // Declare some instances
31 
32   typedef boost::unordered_map<value, value, hash, equals,
33     allocator<std::pair<value const, value> > >
34     map;
35   typedef boost::unordered_multimap<value, value, hash, equals,
36     allocator<std::pair<value const, value> > >
37     multimap;
38   typedef boost::unordered_set<value, hash, equals, allocator<value> > set;
39   typedef boost::unordered_multiset<value, hash, equals, allocator<value> >
40     multiset;
41 
42   // Now define the types which are stored as members, as they are needed for
43   // declaring struct members.
44 
45   struct hash
46   {
operator ()incomplete_test::hash47     template <typename T> std::size_t operator()(T const&) const { return 0; }
48   };
49 
50   struct equals
51   {
operator ()incomplete_test::equals52     template <typename T> bool operator()(T const&, T const&) const
53     {
54       return true;
55     }
56   };
57 
58   // This is a dubious way to implement an allocator, but good enough
59   // for this test.
60   template <typename T> struct allocator : std::allocator<T>
61   {
allocatorincomplete_test::allocator62     allocator() {}
63 
64     template <typename T2>
allocatorincomplete_test::allocator65     allocator(const allocator<T2>& other) : std::allocator<T>(other)
66     {
67     }
68 
69     template <typename T2>
allocatorincomplete_test::allocator70     allocator(const std::allocator<T2>& other) : std::allocator<T>(other)
71     {
72     }
73   };
74 
75   // Declare some members of a structs.
76   //
77   // Incomplete hash, equals and allocator aren't here supported at the
78   // moment.
79 
80   struct struct1
81   {
82     boost::unordered_map<struct1, struct1, hash, equals,
83       allocator<std::pair<struct1 const, struct1> > >
84       x;
85   };
86   struct struct2
87   {
88     boost::unordered_multimap<struct2, struct2, hash, equals,
89       allocator<std::pair<struct2 const, struct2> > >
90       x;
91   };
92   struct struct3
93   {
94     boost::unordered_set<struct3, hash, equals, allocator<struct3> > x;
95   };
96   struct struct4
97   {
98     boost::unordered_multiset<struct4, hash, equals, allocator<struct4> > x;
99   };
100 
101   // Now define the value type.
102 
103   struct value
104   {
105   };
106 
107   // Create some instances.
108 
109   incomplete_test::map m1;
110   incomplete_test::multimap m2;
111   incomplete_test::set s1;
112   incomplete_test::multiset s2;
113 
114   incomplete_test::struct1 c1;
115   incomplete_test::struct2 c2;
116   incomplete_test::struct3 c3;
117   incomplete_test::struct4 c4;
118 
119   // Now declare, but don't define, the operators required for comparing
120   // elements.
121 
122   std::size_t hash_value(value const&);
123   bool operator==(value const&, value const&);
124 
125   std::size_t hash_value(struct1 const&);
126   std::size_t hash_value(struct2 const&);
127   std::size_t hash_value(struct3 const&);
128   std::size_t hash_value(struct4 const&);
129 
130   bool operator==(struct1 const&, struct1 const&);
131   bool operator==(struct2 const&, struct2 const&);
132   bool operator==(struct3 const&, struct3 const&);
133   bool operator==(struct4 const&, struct4 const&);
134 
135   // And finally use these
136 
use_types()137   void use_types()
138   {
139     incomplete_test::value x;
140     m1[x] = x;
141     m2.insert(std::make_pair(x, x));
142     s1.insert(x);
143     s2.insert(x);
144 
145     c1.x.insert(std::make_pair(c1, c1));
146     c2.x.insert(std::make_pair(c2, c2));
147     c3.x.insert(c3);
148     c4.x.insert(c4);
149   }
150 
151   // And finally define the operators required for comparing elements.
152 
hash_value(value const &)153   std::size_t hash_value(value const&) { return 0; }
operator ==(value const &,value const &)154   bool operator==(value const&, value const&) { return true; }
155 
hash_value(struct1 const &)156   std::size_t hash_value(struct1 const&) { return 0; }
hash_value(struct2 const &)157   std::size_t hash_value(struct2 const&) { return 0; }
hash_value(struct3 const &)158   std::size_t hash_value(struct3 const&) { return 0; }
hash_value(struct4 const &)159   std::size_t hash_value(struct4 const&) { return 0; }
160 
operator ==(struct1 const &,struct1 const &)161   bool operator==(struct1 const&, struct1 const&) { return true; }
operator ==(struct2 const &,struct2 const &)162   bool operator==(struct2 const&, struct2 const&) { return true; }
operator ==(struct3 const &,struct3 const &)163   bool operator==(struct3 const&, struct3 const&) { return true; }
operator ==(struct4 const &,struct4 const &)164   bool operator==(struct4 const&, struct4 const&) { return true; }
165 }
166 
main()167 int main()
168 {
169   // This could just be a compile test, but I like to be able to run these
170   // things. It's probably irrational, but I find it reassuring.
171 
172   incomplete_test::use_types();
173 }
174