forked from boostorg/unordered
equality operators when not required, and some bookkeeping. ................ r42539 | danieljames | 2008-01-06 17:48:11 +0000 (Sun, 06 Jan 2008) | 2 lines Add the unordered library to the maintainers list. ................ r46579 | danieljames | 2008-06-21 16:32:11 +0100 (Sat, 21 Jun 2008) | 10 lines Define unordered containers' friend functions outside of the class. On some compilers, friend functions are being instantiated when the main class is explicitly instantiated. This is slightly problematic because the equality functions (which are an extension) put extra requirements on the types used. So I'm going to try defining the functions outside of the class, in the hope that they won't get instantiated. If someone wants non-member functions to be instantiated, I think it's reasonable to expect them to explicitly instantiate them, especially as compilers don't seem to be consistent about this. ................ r46587 | danieljames | 2008-06-21 20:58:39 +0100 (Sat, 21 Jun 2008) | 8 lines Get the test to pass when pair's default constructor creates two instances of the member classes. With some standard libraries I was getting two copies of the object after creating a default pair, probably because it was creating an instance for its default parameter. So only test after creating the pair object - since it isn't our concern how many instances that creates. ................ r46588 | danieljames | 2008-06-21 21:11:26 +0100 (Sat, 21 Jun 2008) | 1 line Markup an expected failure for unordered. ................ r46594 | danieljames | 2008-06-21 23:02:15 +0100 (Sat, 21 Jun 2008) | 19 lines Merge inspect fixes for the unordered library. Merged revisions 46470-46592 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/trunk ................ r46589 | danieljames | 2008-06-21 21:37:42 +0100 (Sat, 21 Jun 2008) | 2 lines Fix some inspect errors (tabs and missing copyright/license). ................ r46591 | danieljames | 2008-06-21 21:47:51 +0100 (Sat, 21 Jun 2008) | 1 line Move memory.hpp into the helpers subdirectory. ................ r46592 | danieljames | 2008-06-21 22:08:53 +0100 (Sat, 21 Jun 2008) | 1 line Prevent inspect errors for unnamed namespaces in some of the test header files. ................ ................ r46607 | danieljames | 2008-06-22 14:54:45 +0100 (Sun, 22 Jun 2008) | 9 lines Extract the hash and equality functions from hash_table_data_*. As these are extensions and add extra requirements to the container elements, they shouldn't be part of hash_table_data_* so that they won't get instantiated if an unordered container is explicitly instantiated. Merged revisions 46594-46604 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/trunk ................ r46608 | danieljames | 2008-06-22 16:00:02 +0100 (Sun, 22 Jun 2008) | 5 lines Remove the svnmerge integration information for the unordered branch. Now that the unordered library is moving towards release, the main development version is in trunk. New features will be developed on a new branch. ................ [SVN r46629]
293 lines
7.7 KiB
C++
293 lines
7.7 KiB
C++
|
|
// Copyright 2006-2008 Daniel James.
|
|
// 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)
|
|
|
|
#if !defined(BOOST_UNORDERED_TEST_OBJECTS_HEADER)
|
|
#define BOOST_UNORDERED_TEST_OBJECTS_HEADER
|
|
|
|
#include <boost/config.hpp>
|
|
#include <boost/limits.hpp>
|
|
#include <cstddef>
|
|
#include <iostream>
|
|
#include "../helpers/fwd.hpp"
|
|
#include "../helpers/count.hpp"
|
|
#include "../helpers/memory.hpp"
|
|
#include <map>
|
|
|
|
namespace test
|
|
{
|
|
// Note that the default hash function will work for any equal_to (but not
|
|
// very well).
|
|
class object;
|
|
class hash;
|
|
class less;
|
|
class equal_to;
|
|
template <class T> class allocator;
|
|
object generate(object const*);
|
|
|
|
class object : globally_counted_object
|
|
{
|
|
friend class hash;
|
|
friend class equal_to;
|
|
friend class less;
|
|
int tag1_, tag2_;
|
|
public:
|
|
explicit object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
|
|
|
|
~object() {
|
|
tag1_ = -1;
|
|
tag2_ = -1;
|
|
}
|
|
|
|
friend bool operator==(object const& x1, object const& x2) {
|
|
return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
|
|
}
|
|
|
|
friend bool operator!=(object const& x1, object const& x2) {
|
|
return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
|
|
}
|
|
|
|
friend bool operator<(object const& x1, object const& x2) {
|
|
return x1.tag1_ < x2.tag1_ ||
|
|
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
|
|
}
|
|
|
|
friend object generate(object const*) {
|
|
int* x = 0;
|
|
return object(generate(x), generate(x));
|
|
}
|
|
|
|
friend std::ostream& operator<<(std::ostream& out, object const& o)
|
|
{
|
|
return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
|
|
}
|
|
};
|
|
|
|
class hash
|
|
{
|
|
int type_;
|
|
public:
|
|
explicit hash(int t = 0) : type_(t) {}
|
|
|
|
std::size_t operator()(object const& x) const {
|
|
switch(type_) {
|
|
case 1:
|
|
return x.tag1_;
|
|
case 2:
|
|
return x.tag2_;
|
|
default:
|
|
return x.tag1_ + x.tag2_;
|
|
}
|
|
}
|
|
|
|
std::size_t operator()(int x) const {
|
|
return x;
|
|
}
|
|
|
|
friend bool operator==(hash const& x1, hash const& x2) {
|
|
return x1.type_ == x2.type_;
|
|
}
|
|
|
|
friend bool operator!=(hash const& x1, hash const& x2) {
|
|
return x1.type_ != x2.type_;
|
|
}
|
|
};
|
|
|
|
class less
|
|
{
|
|
int type_;
|
|
public:
|
|
explicit less(int t = 0) : type_(t) {}
|
|
|
|
bool operator()(object const& x1, object const& x2) const {
|
|
switch(type_) {
|
|
case 1:
|
|
return x1.tag1_ < x2.tag1_;
|
|
case 2:
|
|
return x1.tag2_ < x2.tag2_;
|
|
default:
|
|
return x1 < x2;
|
|
}
|
|
}
|
|
|
|
std::size_t operator()(int x1, int x2) const {
|
|
return x1 < x2;
|
|
}
|
|
|
|
friend bool operator==(less const& x1, less const& x2) {
|
|
return x1.type_ == x2.type_;
|
|
}
|
|
};
|
|
|
|
class equal_to
|
|
{
|
|
int type_;
|
|
public:
|
|
explicit equal_to(int t = 0) : type_(t) {}
|
|
|
|
bool operator()(object const& x1, object const& x2) const {
|
|
switch(type_) {
|
|
case 1:
|
|
return x1.tag1_ == x2.tag1_;
|
|
case 2:
|
|
return x1.tag2_ == x2.tag2_;
|
|
default:
|
|
return x1 == x2;
|
|
}
|
|
}
|
|
|
|
std::size_t operator()(int x1, int x2) const {
|
|
return x1 == x2;
|
|
}
|
|
|
|
friend bool operator==(equal_to const& x1, equal_to const& x2) {
|
|
return x1.type_ == x2.type_;
|
|
}
|
|
|
|
friend bool operator!=(equal_to const& x1, equal_to const& x2) {
|
|
return x1.type_ != x2.type_;
|
|
}
|
|
|
|
friend less create_compare(equal_to x) {
|
|
return less(x.type_);
|
|
}
|
|
};
|
|
|
|
namespace detail
|
|
{
|
|
// This won't be a problem as I'm only using a single compile unit
|
|
// in each test (this is actually require by the minimal test
|
|
// framework).
|
|
//
|
|
// boostinspect:nounnamed
|
|
namespace {
|
|
test::detail::memory_tracker<std::allocator<int> > tracker;
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
class allocator
|
|
{
|
|
# ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
|
public:
|
|
# else
|
|
template <class> friend class allocator;
|
|
# endif
|
|
int tag_;
|
|
public:
|
|
typedef std::size_t size_type;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef T* pointer;
|
|
typedef T const* const_pointer;
|
|
typedef T& reference;
|
|
typedef T const& const_reference;
|
|
typedef T value_type;
|
|
|
|
template <class U> struct rebind { typedef allocator<U> other; };
|
|
|
|
explicit allocator(int t = 0) : tag_(t) { detail::tracker.allocator_ref(); }
|
|
template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
|
|
allocator(allocator const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
|
|
~allocator() { detail::tracker.allocator_unref(); }
|
|
|
|
pointer address(reference r) { return pointer(&r); }
|
|
const_pointer address(const_reference r) { return const_pointer(&r); }
|
|
|
|
pointer allocate(size_type n) {
|
|
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
|
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
|
return ptr;
|
|
}
|
|
|
|
pointer allocate(size_type n, void const* u)
|
|
{
|
|
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
|
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
|
return ptr;
|
|
}
|
|
|
|
void deallocate(pointer p, size_type n)
|
|
{
|
|
detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
|
|
::operator delete((void*) p);
|
|
}
|
|
|
|
void construct(pointer p, T const& t) {
|
|
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
|
|
new(p) T(t);
|
|
}
|
|
|
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
|
template<class... Args> void construct(pointer p, Args&&... args) {
|
|
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
|
|
new(p) T(std::forward<Args>(args)...);
|
|
}
|
|
#endif
|
|
|
|
void destroy(pointer p) {
|
|
detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
|
|
p->~T();
|
|
}
|
|
|
|
size_type max_size() const {
|
|
return (std::numeric_limits<size_type>::max)();
|
|
}
|
|
|
|
bool operator==(allocator const& x) const
|
|
{
|
|
return tag_ == x.tag_;
|
|
}
|
|
|
|
bool operator!=(allocator const& x) const
|
|
{
|
|
return tag_ != x.tag_;
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
bool equivalent_impl(allocator<T> const& x, allocator<T> const& y, test::derived_type) {
|
|
return x == y;
|
|
}
|
|
|
|
#if BOOST_WORKAROUND(__GNUC__, < 3)
|
|
void swap(test::object& x, test::object& y) {
|
|
test::object tmp;
|
|
tmp = x;
|
|
x = y;
|
|
y = tmp;
|
|
}
|
|
|
|
void swap(test::hash& x, test::hash& y) {
|
|
test::hash tmp;
|
|
tmp = x;
|
|
x = y;
|
|
y = tmp;
|
|
}
|
|
|
|
void swap(test::less& x, test::less& y) {
|
|
test::less tmp;
|
|
tmp = x;
|
|
x = y;
|
|
y = tmp;
|
|
}
|
|
|
|
void swap(test::equal_to& x, test::equal_to& y) {
|
|
test::equal_to tmp;
|
|
tmp = x;
|
|
x = y;
|
|
y = tmp;
|
|
}
|
|
|
|
template <class T>
|
|
void swap(test::allocator<T>& x, test::allocator<T>& y) {
|
|
test::allocator<T> tmp;
|
|
tmp = x;
|
|
x = y;
|
|
y = tmp;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endif
|