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 #include "../helpers/prefix.hpp"
7 #include <boost/unordered_map.hpp>
8 #include <boost/unordered_set.hpp>
9 #include "../helpers/postfix.hpp"
10 
11 #include <utility>
12 
13 namespace x
14 {
15     struct D { boost::unordered_map<D, D> x; };
16 }
17 
18 namespace incomplete_test
19 {
20     // Declare, but don't define some types.
21 
22     struct value;
23     struct hash;
24     struct equals;
25     template <class T> struct allocator;
26 
27     // Declare some instances
28 
29     typedef boost::unordered_map<value, value, hash, equals,
30         allocator<std::pair<value const, value> > > map;
31     typedef boost::unordered_multimap<value, value, hash, equals,
32         allocator<std::pair<value const, value> > > multimap;
33     typedef boost::unordered_set<value, hash, equals,
34         allocator<value> > set;
35     typedef boost::unordered_multiset<value, hash, equals,
36         allocator<value> > multiset;
37 
38     // Now define the types which are stored as members, as they are needed for
39     // declaring struct members.
40 
41     struct hash {
42         template <typename T>
operator ()incomplete_test::hash43         std::size_t operator()(T const&) const { return 0; }
44     };
45 
46     struct equals {
47         template <typename T>
operator ()incomplete_test::equals48         bool operator()(T const&, T const&) const { return true; }
49     };
50 
51     // This is a dubious way to implement an allocator, but good enough
52     // for this test.
53     template <typename T>
54     struct allocator : std::allocator<T> {
allocatorincomplete_test::allocator55         allocator() {}
56 
57         template <typename T2>
allocatorincomplete_test::allocator58         allocator(const allocator<T2>& other) :
59             std::allocator<T>(other) {}
60     };
61 
62     // Declare some members of a structs.
63     //
64     // Incomplete hash, equals and allocator aren't here supported at the
65     // moment.
66 
67     struct struct1 {
68         boost::unordered_map<struct1, struct1, hash, equals,
69             allocator<std::pair<struct1 const, struct1> > > x;
70     };
71     struct struct2 {
72         boost::unordered_multimap<struct2, struct2, hash, equals,
73             allocator<std::pair<struct2 const, struct2> > > x;
74     };
75     struct struct3 {
76         boost::unordered_set<struct3, hash, equals,
77             allocator<struct3> > x;
78     };
79     struct struct4 {
80         boost::unordered_multiset<struct4, hash, equals,
81             allocator<struct4> > x;
82     };
83 
84     // Now define the value type.
85 
86     struct value {};
87 
88     // Create some instances.
89 
90     incomplete_test::map m1;
91     incomplete_test::multimap m2;
92     incomplete_test::set s1;
93     incomplete_test::multiset s2;
94 
95     incomplete_test::struct1 c1;
96     incomplete_test::struct2 c2;
97     incomplete_test::struct3 c3;
98     incomplete_test::struct4 c4;
99 
100     // Now declare, but don't define, the operators required for comparing
101     // elements.
102 
103     std::size_t hash_value(value const&);
104     bool operator==(value const&, value const&);
105 
106     std::size_t hash_value(struct1 const&);
107     std::size_t hash_value(struct2 const&);
108     std::size_t hash_value(struct3 const&);
109     std::size_t hash_value(struct4 const&);
110 
111     bool operator==(struct1 const&, struct1 const&);
112     bool operator==(struct2 const&, struct2 const&);
113     bool operator==(struct3 const&, struct3 const&);
114     bool operator==(struct4 const&, struct4 const&);
115 
116     // And finally use these
117 
use_types()118     void use_types()
119     {
120         incomplete_test::value x;
121         m1[x] = x;
122         m2.insert(std::make_pair(x, x));
123         s1.insert(x);
124         s2.insert(x);
125 
126         c1.x.insert(std::make_pair(c1, c1));
127         c2.x.insert(std::make_pair(c2, c2));
128         c3.x.insert(c3);
129         c4.x.insert(c4);
130     }
131 
132     // And finally define the operators required for comparing elements.
133 
hash_value(value const &)134     std::size_t hash_value(value const&) { return 0; }
operator ==(value const &,value const &)135     bool operator==(value const&, value const&) { return true; }
136 
hash_value(struct1 const &)137     std::size_t hash_value(struct1 const&) { return 0; }
hash_value(struct2 const &)138     std::size_t hash_value(struct2 const&) { return 0; }
hash_value(struct3 const &)139     std::size_t hash_value(struct3 const&) { return 0; }
hash_value(struct4 const &)140     std::size_t hash_value(struct4 const&) { return 0; }
141 
operator ==(struct1 const &,struct1 const &)142     bool operator==(struct1 const&, struct1 const&) { return true; }
operator ==(struct2 const &,struct2 const &)143     bool operator==(struct2 const&, struct2 const&) { return true; }
operator ==(struct3 const &,struct3 const &)144     bool operator==(struct3 const&, struct3 const&) { return true; }
operator ==(struct4 const &,struct4 const &)145     bool operator==(struct4 const&, struct4 const&) { return true; }
146 }
147 
main()148 int main() {
149     // This could just be a compile test, but I like to be able to run these
150     // things. It's probably irrational, but I find it reassuring.
151 
152     incomplete_test::use_types();
153 }
154