• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Copyright 2006-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 #if !defined(BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER)
7 #define BOOST_UNORDERED_EXCEPTION_TEST_OBJECTS_HEADER
8 
9 #include "../helpers/exception_test.hpp"
10 
11 #include "../helpers/count.hpp"
12 #include "../helpers/fwd.hpp"
13 #include "../helpers/generators.hpp"
14 #include "../helpers/memory.hpp"
15 #include "./fwd.hpp"
16 #include <boost/limits.hpp>
17 #include <cstddef>
18 #include <new>
19 
20 namespace test {
21   namespace exception {
22     class object;
23     class hash;
24     class equal_to;
25     template <class T> class allocator;
26     object generate(object const*, random_generator);
27     std::pair<object, object> generate(
28       std::pair<object, object> const*, random_generator);
29 
30     struct true_type
31     {
32       enum
33       {
34         value = true
35       };
36     };
37 
38     struct false_type
39     {
40       enum
41       {
42         value = false
43       };
44     };
45 
46     class object : private counted_object
47     {
48     public:
49       int tag1_, tag2_;
50 
object()51       explicit object() : tag1_(0), tag2_(0)
52       {
53         UNORDERED_SCOPE(object::object())
54         {
55           UNORDERED_EPOINT("Mock object default constructor.");
56         }
57       }
58 
object(int t1,int t2=0)59       explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2)
60       {
61         UNORDERED_SCOPE(object::object(int))
62         {
63           UNORDERED_EPOINT("Mock object constructor by value.");
64         }
65       }
66 
object(object const & x)67       object(object const& x)
68           : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
69       {
70         UNORDERED_SCOPE(object::object(object))
71         {
72           UNORDERED_EPOINT("Mock object copy constructor.");
73         }
74       }
75 
~object()76       ~object()
77       {
78         tag1_ = -1;
79         tag2_ = -1;
80       }
81 
operator =(object const & x)82       object& operator=(object const& x)
83       {
84         UNORDERED_SCOPE(object::operator=(object))
85         {
86           tag1_ = x.tag1_;
87           UNORDERED_EPOINT("Mock object assign operator 1.");
88           tag2_ = x.tag2_;
89           // UNORDERED_EPOINT("Mock object assign operator 2.");
90         }
91         return *this;
92       }
93 
operator ==(object const & x1,object const & x2)94       friend bool operator==(object const& x1, object const& x2)
95       {
96         UNORDERED_SCOPE(operator==(object, object))
97         {
98           UNORDERED_EPOINT("Mock object equality operator.");
99         }
100 
101         return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
102       }
103 
operator !=(object const & x1,object const & x2)104       friend bool operator!=(object const& x1, object const& x2)
105       {
106         UNORDERED_SCOPE(operator!=(object, object))
107         {
108           UNORDERED_EPOINT("Mock object inequality operator.");
109         }
110 
111         return !(x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_);
112       }
113 
114       // None of the last few functions are used by the unordered associative
115       // containers - so there aren't any exception points.
operator <(object const & x1,object const & x2)116       friend bool operator<(object const& x1, object const& x2)
117       {
118         return x1.tag1_ < x2.tag1_ ||
119                (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
120       }
121 
generate(object const *,random_generator g)122       friend object generate(object const*, random_generator g)
123       {
124         int* x = 0;
125         return object(::test::generate(x, g), ::test::generate(x, g));
126       }
127 
operator <<(std::ostream & out,object const & o)128       friend std::ostream& operator<<(std::ostream& out, object const& o)
129       {
130         return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
131       }
132     };
133 
generate(std::pair<object,object> const *,random_generator g)134     std::pair<object, object> generate(
135       std::pair<object, object> const*, random_generator g)
136     {
137       int* x = 0;
138       return std::make_pair(
139         object(::test::generate(x, g), ::test::generate(x, g)),
140         object(::test::generate(x, g), ::test::generate(x, g)));
141     }
142 
143     class hash
144     {
145       int tag_;
146 
147     public:
hash(int t=0)148       hash(int t = 0) : tag_(t)
149       {
150         UNORDERED_SCOPE(hash::object())
151         {
152           UNORDERED_EPOINT("Mock hash default constructor.");
153         }
154       }
155 
hash(hash const & x)156       hash(hash const& x) : tag_(x.tag_)
157       {
158         UNORDERED_SCOPE(hash::hash(hash))
159         {
160           UNORDERED_EPOINT("Mock hash copy constructor.");
161         }
162       }
163 
operator =(hash const & x)164       hash& operator=(hash const& x)
165       {
166         UNORDERED_SCOPE(hash::operator=(hash))
167         {
168           UNORDERED_EPOINT("Mock hash assign operator 1.");
169           tag_ = x.tag_;
170           UNORDERED_EPOINT("Mock hash assign operator 2.");
171         }
172         return *this;
173       }
174 
operator ()(object const & x) const175       std::size_t operator()(object const& x) const
176       {
177         UNORDERED_SCOPE(hash::operator()(object))
178         {
179           UNORDERED_EPOINT("Mock hash function.");
180         }
181 
182         return hash_impl(x);
183       }
184 
operator ()(std::pair<object,object> const & x) const185       std::size_t operator()(std::pair<object, object> const& x) const
186       {
187         UNORDERED_SCOPE(hash::operator()(std::pair<object, object>))
188         {
189           UNORDERED_EPOINT("Mock hash pair function.");
190         }
191 
192         return hash_impl(x.first) * 193ul + hash_impl(x.second) * 97ul + 29ul;
193       }
194 
hash_impl(object const & x) const195       std::size_t hash_impl(object const& x) const
196       {
197         int result;
198         switch (tag_) {
199         case 1:
200           result = x.tag1_;
201           break;
202         case 2:
203           result = x.tag2_;
204           break;
205         default:
206           result = x.tag1_ + x.tag2_;
207         }
208         return static_cast<std::size_t>(result);
209       }
210 
operator ==(hash const & x1,hash const & x2)211       friend bool operator==(hash const& x1, hash const& x2)
212       {
213         UNORDERED_SCOPE(operator==(hash, hash))
214         {
215           UNORDERED_EPOINT("Mock hash equality function.");
216         }
217         return x1.tag_ == x2.tag_;
218       }
219 
operator !=(hash const & x1,hash const & x2)220       friend bool operator!=(hash const& x1, hash const& x2)
221       {
222         UNORDERED_SCOPE(hash::operator!=(hash, hash))
223         {
224           UNORDERED_EPOINT("Mock hash inequality function.");
225         }
226         return x1.tag_ != x2.tag_;
227       }
228     };
229 
230     class less
231     {
232       int tag_;
233 
234     public:
less(int t=0)235       less(int t = 0) : tag_(t) {}
236 
less(less const & x)237       less(less const& x) : tag_(x.tag_) {}
238 
operator ()(object const & x1,object const & x2) const239       bool operator()(object const& x1, object const& x2) const
240       {
241         return less_impl(x1, x2);
242       }
243 
operator ()(std::pair<object,object> const & x1,std::pair<object,object> const & x2) const244       bool operator()(std::pair<object, object> const& x1,
245         std::pair<object, object> const& x2) const
246       {
247         if (less_impl(x1.first, x2.first)) {
248           return true;
249         }
250         if (!less_impl(x1.first, x2.first)) {
251           return false;
252         }
253         return less_impl(x1.second, x2.second);
254       }
255 
less_impl(object const & x1,object const & x2) const256       bool less_impl(object const& x1, object const& x2) const
257       {
258         switch (tag_) {
259         case 1:
260           return x1.tag1_ < x2.tag1_;
261         case 2:
262           return x1.tag2_ < x2.tag2_;
263         default:
264           return x1 < x2;
265         }
266       }
267 
operator ==(less const & x1,less const & x2)268       friend bool operator==(less const& x1, less const& x2)
269       {
270         return x1.tag_ == x2.tag_;
271       }
272 
operator !=(less const & x1,less const & x2)273       friend bool operator!=(less const& x1, less const& x2)
274       {
275         return x1.tag_ != x2.tag_;
276       }
277     };
278 
279     class equal_to
280     {
281       int tag_;
282 
283     public:
equal_to(int t=0)284       equal_to(int t = 0) : tag_(t)
285       {
286         UNORDERED_SCOPE(equal_to::equal_to())
287         {
288           UNORDERED_EPOINT("Mock equal_to default constructor.");
289         }
290       }
291 
equal_to(equal_to const & x)292       equal_to(equal_to const& x) : tag_(x.tag_)
293       {
294         UNORDERED_SCOPE(equal_to::equal_to(equal_to))
295         {
296           UNORDERED_EPOINT("Mock equal_to copy constructor.");
297         }
298       }
299 
operator =(equal_to const & x)300       equal_to& operator=(equal_to const& x)
301       {
302         UNORDERED_SCOPE(equal_to::operator=(equal_to))
303         {
304           UNORDERED_EPOINT("Mock equal_to assign operator 1.");
305           tag_ = x.tag_;
306           UNORDERED_EPOINT("Mock equal_to assign operator 2.");
307         }
308         return *this;
309       }
310 
operator ()(object const & x1,object const & x2) const311       bool operator()(object const& x1, object const& x2) const
312       {
313         UNORDERED_SCOPE(equal_to::operator()(object, object))
314         {
315           UNORDERED_EPOINT("Mock equal_to function.");
316         }
317 
318         return equal_impl(x1, x2);
319       }
320 
operator ()(std::pair<object,object> const & x1,std::pair<object,object> const & x2) const321       bool operator()(std::pair<object, object> const& x1,
322         std::pair<object, object> const& x2) const
323       {
324         UNORDERED_SCOPE(equal_to::operator()(
325           std::pair<object, object>, std::pair<object, object>))
326         {
327           UNORDERED_EPOINT("Mock equal_to function.");
328         }
329 
330         return equal_impl(x1.first, x2.first) &&
331                equal_impl(x1.second, x2.second);
332       }
333 
equal_impl(object const & x1,object const & x2) const334       bool equal_impl(object const& x1, object const& x2) const
335       {
336         switch (tag_) {
337         case 1:
338           return x1.tag1_ == x2.tag1_;
339         case 2:
340           return x1.tag2_ == x2.tag2_;
341         default:
342           return x1 == x2;
343         }
344       }
345 
operator ==(equal_to const & x1,equal_to const & x2)346       friend bool operator==(equal_to const& x1, equal_to const& x2)
347       {
348         UNORDERED_SCOPE(operator==(equal_to, equal_to))
349         {
350           UNORDERED_EPOINT("Mock equal_to equality function.");
351         }
352         return x1.tag_ == x2.tag_;
353       }
354 
operator !=(equal_to const & x1,equal_to const & x2)355       friend bool operator!=(equal_to const& x1, equal_to const& x2)
356       {
357         UNORDERED_SCOPE(operator!=(equal_to, equal_to))
358         {
359           UNORDERED_EPOINT("Mock equal_to inequality function.");
360         }
361         return x1.tag_ != x2.tag_;
362       }
363 
create_compare(equal_to x)364       friend less create_compare(equal_to x) { return less(x.tag_); }
365     };
366 
367     template <class T> class allocator
368     {
369     public:
370       int tag_;
371       typedef std::size_t size_type;
372       typedef std::ptrdiff_t difference_type;
373       typedef T* pointer;
374       typedef T const* const_pointer;
375       typedef T& reference;
376       typedef T const& const_reference;
377       typedef T value_type;
378 
379       template <class U> struct rebind
380       {
381         typedef allocator<U> other;
382       };
383 
allocator(int t=0)384       explicit allocator(int t = 0) : tag_(t)
385       {
386         UNORDERED_SCOPE(allocator::allocator())
387         {
388           UNORDERED_EPOINT("Mock allocator default constructor.");
389         }
390         test::detail::tracker.allocator_ref();
391       }
392 
allocator(allocator<Y> const & x)393       template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
394       {
395         test::detail::tracker.allocator_ref();
396       }
397 
allocator(allocator const & x)398       allocator(allocator const& x) : tag_(x.tag_)
399       {
400         test::detail::tracker.allocator_ref();
401       }
402 
~allocator()403       ~allocator() { test::detail::tracker.allocator_unref(); }
404 
operator =(allocator const & x)405       allocator& operator=(allocator const& x)
406       {
407         tag_ = x.tag_;
408         return *this;
409       }
410 
411       // If address throws, then it can't be used in erase or the
412       // destructor, which is very limiting. I need to check up on
413       // this.
414 
address(reference r)415       pointer address(reference r)
416       {
417         // UNORDERED_SCOPE(allocator::address(reference)) {
418         //    UNORDERED_EPOINT("Mock allocator address function.");
419         //}
420         return pointer(&r);
421       }
422 
address(const_reference r)423       const_pointer address(const_reference r)
424       {
425         // UNORDERED_SCOPE(allocator::address(const_reference)) {
426         //    UNORDERED_EPOINT("Mock allocator const address function.");
427         //}
428         return const_pointer(&r);
429       }
430 
allocate(size_type n)431       pointer allocate(size_type n)
432       {
433         T* ptr = 0;
434         UNORDERED_SCOPE(allocator::allocate(size_type))
435         {
436           UNORDERED_EPOINT("Mock allocator allocate function.");
437 
438           using namespace std;
439           ptr = (T*)malloc(n * sizeof(T));
440           if (!ptr)
441             throw std::bad_alloc();
442         }
443         test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
444         return pointer(ptr);
445 
446         // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
447       }
448 
allocate(size_type n,void const *)449       pointer allocate(size_type n, void const*)
450       {
451         T* ptr = 0;
452         UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer))
453         {
454           UNORDERED_EPOINT("Mock allocator allocate function.");
455 
456           using namespace std;
457           ptr = (T*)malloc(n * sizeof(T));
458           if (!ptr)
459             throw std::bad_alloc();
460         }
461         test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
462         return pointer(ptr);
463 
464         // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
465       }
466 
deallocate(pointer p,size_type n)467       void deallocate(pointer p, size_type n)
468       {
469         //::operator delete((void*) p);
470         if (p) {
471           test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
472           using namespace std;
473           free(p);
474         }
475       }
476 
construct(pointer p,T const & t)477       void construct(pointer p, T const& t)
478       {
479         UNORDERED_SCOPE(allocator::construct(T*, T))
480         {
481           UNORDERED_EPOINT("Mock allocator construct function.");
482           new (p) T(t);
483         }
484         test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
485       }
486 
487 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
construct(T * p,BOOST_FWD_REF (Args)...args)488       template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
489       {
490         UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...))
491         {
492           UNORDERED_EPOINT("Mock allocator construct function.");
493           new (p) T(boost::forward<Args>(args)...);
494         }
495         test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
496       }
497 #endif
498 
destroy(T * p)499       void destroy(T* p)
500       {
501         test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
502         p->~T();
503       }
504 
max_size() const505       size_type max_size() const
506       {
507         UNORDERED_SCOPE(allocator::construct(pointer, T))
508         {
509           UNORDERED_EPOINT("Mock allocator max_size function.");
510         }
511         return (std::numeric_limits<std::size_t>::max)();
512       }
513 
514       typedef true_type propagate_on_container_copy_assignment;
515       typedef true_type propagate_on_container_move_assignment;
516       typedef true_type propagate_on_container_swap;
517     };
518 
swap(allocator<T> & x,allocator<T> & y)519     template <class T> void swap(allocator<T>& x, allocator<T>& y)
520     {
521       std::swap(x.tag_, y.tag_);
522     }
523 
524     // It's pretty much impossible to write a compliant swap when these
525     // two can throw. So they don't.
526 
527     template <class T>
operator ==(allocator<T> const & x,allocator<T> const & y)528     inline bool operator==(allocator<T> const& x, allocator<T> const& y)
529     {
530       // UNORDERED_SCOPE(operator==(allocator, allocator)) {
531       //    UNORDERED_EPOINT("Mock allocator equality operator.");
532       //}
533       return x.tag_ == y.tag_;
534     }
535 
536     template <class T>
operator !=(allocator<T> const & x,allocator<T> const & y)537     inline bool operator!=(allocator<T> const& x, allocator<T> const& y)
538     {
539       // UNORDERED_SCOPE(operator!=(allocator, allocator)) {
540       //    UNORDERED_EPOINT("Mock allocator inequality operator.");
541       //}
542       return x.tag_ != y.tag_;
543     }
544 
545     template <class T> class allocator2
546     {
547     public:
548       int tag_;
549       typedef std::size_t size_type;
550       typedef std::ptrdiff_t difference_type;
551       typedef T* pointer;
552       typedef T const* const_pointer;
553       typedef T& reference;
554       typedef T const& const_reference;
555       typedef T value_type;
556 
557       template <class U> struct rebind
558       {
559         typedef allocator2<U> other;
560       };
561 
allocator2(int t=0)562       explicit allocator2(int t = 0) : tag_(t)
563       {
564         UNORDERED_SCOPE(allocator2::allocator2())
565         {
566           UNORDERED_EPOINT("Mock allocator2 default constructor.");
567         }
568         test::detail::tracker.allocator_ref();
569       }
570 
allocator2(allocator<T> const & x)571       allocator2(allocator<T> const& x) : tag_(x.tag_)
572       {
573         test::detail::tracker.allocator_ref();
574       }
575 
allocator2(allocator2<Y> const & x)576       template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
577       {
578         test::detail::tracker.allocator_ref();
579       }
580 
allocator2(allocator2 const & x)581       allocator2(allocator2 const& x) : tag_(x.tag_)
582       {
583         test::detail::tracker.allocator_ref();
584       }
585 
~allocator2()586       ~allocator2() { test::detail::tracker.allocator_unref(); }
587 
operator =(allocator2 const &)588       allocator2& operator=(allocator2 const&) { return *this; }
589 
590       // If address throws, then it can't be used in erase or the
591       // destructor, which is very limiting. I need to check up on
592       // this.
593 
address(reference r)594       pointer address(reference r)
595       {
596         // UNORDERED_SCOPE(allocator2::address(reference)) {
597         //    UNORDERED_EPOINT("Mock allocator2 address function.");
598         //}
599         return pointer(&r);
600       }
601 
address(const_reference r)602       const_pointer address(const_reference r)
603       {
604         // UNORDERED_SCOPE(allocator2::address(const_reference)) {
605         //    UNORDERED_EPOINT("Mock allocator2 const address function.");
606         //}
607         return const_pointer(&r);
608       }
609 
allocate(size_type n)610       pointer allocate(size_type n)
611       {
612         T* ptr = 0;
613         UNORDERED_SCOPE(allocator2::allocate(size_type))
614         {
615           UNORDERED_EPOINT("Mock allocator2 allocate function.");
616 
617           using namespace std;
618           ptr = (T*)malloc(n * sizeof(T));
619           if (!ptr)
620             throw std::bad_alloc();
621         }
622         test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
623         return pointer(ptr);
624 
625         // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
626       }
627 
allocate(size_type n,void const *)628       pointer allocate(size_type n, void const*)
629       {
630         T* ptr = 0;
631         UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer))
632         {
633           UNORDERED_EPOINT("Mock allocator2 allocate function.");
634 
635           using namespace std;
636           ptr = (T*)malloc(n * sizeof(T));
637           if (!ptr)
638             throw std::bad_alloc();
639         }
640         test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
641         return pointer(ptr);
642 
643         // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
644       }
645 
deallocate(pointer p,size_type n)646       void deallocate(pointer p, size_type n)
647       {
648         //::operator delete((void*) p);
649         if (p) {
650           test::detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
651           using namespace std;
652           free(p);
653         }
654       }
655 
construct(pointer p,T const & t)656       void construct(pointer p, T const& t)
657       {
658         UNORDERED_SCOPE(allocator2::construct(T*, T))
659         {
660           UNORDERED_EPOINT("Mock allocator2 construct function.");
661           new (p) T(t);
662         }
663         test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
664       }
665 
666 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
construct(T * p,BOOST_FWD_REF (Args)...args)667       template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
668       {
669         UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...))
670         {
671           UNORDERED_EPOINT("Mock allocator2 construct function.");
672           new (p) T(boost::forward<Args>(args)...);
673         }
674         test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
675       }
676 #endif
677 
destroy(T * p)678       void destroy(T* p)
679       {
680         test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
681         p->~T();
682       }
683 
max_size() const684       size_type max_size() const
685       {
686         UNORDERED_SCOPE(allocator2::construct(pointer, T))
687         {
688           UNORDERED_EPOINT("Mock allocator2 max_size function.");
689         }
690         return (std::numeric_limits<std::size_t>::max)();
691       }
692 
693       typedef false_type propagate_on_container_copy_assignment;
694       typedef false_type propagate_on_container_move_assignment;
695       typedef false_type propagate_on_container_swap;
696     };
697 
swap(allocator2<T> & x,allocator2<T> & y)698     template <class T> void swap(allocator2<T>& x, allocator2<T>& y)
699     {
700       std::swap(x.tag_, y.tag_);
701     }
702 
703     // It's pretty much impossible to write a compliant swap when these
704     // two can throw. So they don't.
705 
706     template <class T>
operator ==(allocator2<T> const & x,allocator2<T> const & y)707     inline bool operator==(allocator2<T> const& x, allocator2<T> const& y)
708     {
709       // UNORDERED_SCOPE(operator==(allocator2, allocator2)) {
710       //    UNORDERED_EPOINT("Mock allocator2 equality operator.");
711       //}
712       return x.tag_ == y.tag_;
713     }
714 
715     template <class T>
operator !=(allocator2<T> const & x,allocator2<T> const & y)716     inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y)
717     {
718       // UNORDERED_SCOPE(operator!=(allocator2, allocator2)) {
719       //    UNORDERED_EPOINT("Mock allocator2 inequality operator.");
720       //}
721       return x.tag_ != y.tag_;
722     }
723   }
724 }
725 
726 namespace test {
727   template <typename X> struct equals_to_compare;
728   template <> struct equals_to_compare<test::exception::equal_to>
729   {
730     typedef test::exception::less type;
731   };
732 }
733 
734 // Workaround for ADL deficient compilers
735 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
736 namespace test {
generate(test::exception::object const * x,random_generator g)737   test::exception::object generate(
738     test::exception::object const* x, random_generator g)
739   {
740     return test::exception::generate(x, g);
741   }
742 
generate(std::pair<test::exception::object,test::exception::object> const * x,random_generator g)743   std::pair<test::exception::object, test::exception::object> generate(
744     std::pair<test::exception::object, test::exception::object> const* x,
745     random_generator g)
746   {
747     return test::exception::generate(x, g);
748   }
749 }
750 #endif
751 
752 #endif
753