Merged for Boost 1.48

[SVN r74161]
This commit is contained in:
Ion Gaztañaga
2011-08-30 15:49:49 +00:00
parent f5db9a8d1f
commit 38805868fc
59 changed files with 8071 additions and 0 deletions

82
doc/Jamfile.v2 Normal file
View File

@@ -0,0 +1,82 @@
# Boost.Container library documentation Jamfile ---------------------------------
#
# Copyright Ion Gaztanaga 2009-2011. Use, modification and
# distribution is subject to 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 for updates, documentation, and revision history.
import doxygen ;
import quickbook ;
using auto-index ;
path-constant images_location : html ;
doxygen autodoc
:
[ glob ../../../boost/container/*.hpp ]
:
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_RV_REF(T)=T &&\" \\
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
\"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T<a, b> &&\" \\
\"BOOST_RV_REF_3_TEMPL_ARGS(T,a,b,c)=T<a,b,c>T<a,b,c> &&\" \\
\"BOOST_FWD_REF(a)=a &&\""
<xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference"
;
xml container : container.qbk
:
<include>../../../tools/auto_index/include
;
boostbook standalone
:
container
:
<xsl:param>boost.root=../../../..
<xsl:param>boost.libraries=../../../../libs/libraries.htm
<xsl:param>generate.section.toc.level=3
<xsl:param>chunk.first.sections=1
<format>pdf:<xsl:param>img.src.path=$(images_location)/
<dependency>autodoc
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
# Build requirements go here:
# <auto-index>on (or off) one turns on (or off) indexing:
<auto-index>on
# Turns on (or off) auto-index-verbose for diagnostic info.
# This is highly recommended until you have got all the many details correct!
<auto-index-verbose>on
# Choose the indexing method (separately for html and PDF) - see manual.
# Choose indexing method for PDFs:
<format>pdf:<auto-index-internal>off
# Choose indexing method for html:
<format>html:<auto-index-internal>on
# Set the name of the script file to use (index.idx is popular):
<auto-index-script>index.idx
# Commands in the script file should all use RELATIVE PATHS
# otherwise the script will not be portable to other machines.
# Relative paths are normally taken as relative to the location
# of the script file, but we can add a prefix to all
# those relative paths using the <auto-index-prefix> feature.
# The path specified by <auto-index-prefix> may be either relative or
# absolute, for example the following will get us up to the boost root
# directory for most Boost libraries:
<auto-index-prefix>"../../.."
;

590
doc/container.qbk Normal file
View File

@@ -0,0 +1,590 @@
[/
/ Copyright (c) 2009-2011 Ion Gazta\u00F1aga
/
/ 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)
/]
[library Boost.Container
[quickbook 1.5]
[authors [Gaztanaga, Ion]]
[copyright 2009-2011 Ion Gaztanaga]
[id container]
[dirname container]
[purpose Containers library]
[license
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])
]
]
[template super[x]'''<superscript>'''[x]'''</superscript>''']
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
[section:intro Introduction]
[*Boost.Container] library implements several well-known containers, including
STL containers. The aim of the library is to offers advanced features not present
in standard containers or to offer the latest standard draft features for compilers
that comply with C++03.
In short, what does [*Boost.Container] offer?
* Move semantics are implemented, including move emulation for pre-C++11 compilers.
* New advanced features (e.g. placement insertion, recursive containers) are present.
* Containers support stateful allocators and are compatible with [*Boost.Interprocess]
(they can be safely placed in shared memory).
* The library offers new useful containers:
* [classref boost::container::flat_map flat_map],
[classref boost::container::flat_map flat_set],
[classref boost::container::flat_map flat_multiset] and
[classref boost::container::flat_map flat_multiset]: drop-in
replacements for standard associative containers but more memory friendly and with faster
searches.
* [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid
container: vector-like random-access iterators and list-like iterator stability in insertions and erasures.
* [classref boost::container::slist slist]: the classic pre-standard singly linked list implementation
offering constant-time `size()`. Note that C++11 `forward_list` has no `size()`.
[section:introduction_building_container Building Boost.Container]
There is no need to compile [*Boost.Container], since it's
a header only library. Just include your Boost header directory in your
compiler include path.
[endsect]
[section:tested_compilers Tested compilers]
[*Boost.Container] requires a decent C++98 compatibility. Some compilers known to work are:
* Visual C++ >= 7.1.
* GCC >= 3.4.
* Intel C++ >= 9.0
[endsect]
[endsect]
[section:move_emplace Efficient insertion]
Move semantics and placement insertion are two features brought by C++11 containers
that can have a very positive impact in your C++ applications. Boost.Container implements
both techniques both for C++11 and C++03 compilers.
[section:move_containers Move-aware containers]
All containers offered by [*Boost.Container] can store movable-only types
and actual requirements for `value_type` depend on each container operations.
Following C++11 requirements even for C++03 compilers, many operations now require
movable or default constructible types instead of just copy constructible types.
Containers themselves are also movable, with no-throw guarantee if allocator
or predicate (if present) copy operations are no-throw. This allows
high performance operations when transferring data between vectors.
Let's see an example:
[import ../example/doc_move_containers.cpp]
[doc_move_containers]
[endsect]
[section:emplace Emplace: Placement insertion]
All containers offered by [*Boost.Container] implement placement insertion,
which means that objects can be built directly into the container from user arguments
without creating any temporary object. For compilers without variadic templates support
placement insertion is emulated up to a finite (10) number of arguments.
Expensive to move types are perfect candidates emplace functions and in case of node containers
([classref boost::container::list list], [classref boost::container::set set], ...)
emplace allows storing non-movable and non-copyable types in containers! Let's
see an example:
[import ../example/doc_emplace.cpp]
[doc_emplace]
[endsect]
[endsect]
[section:containers_of_incomplete_types Containers of Incomplete Types]
Incomplete types allow
[@http://en.wikipedia.org/wiki/Type_erasure [*type erasure ]] and
[@http://en.wikipedia.org/wiki/Recursive_data_type [*recursive data types]], and
C and C++ programmers have been using it for years to build complex data structures, like
tree structures where a node may have an arbitrary number of children.
What about standard containers? Containers of incomplete types have been under discussion for a long time,
as explained in Matt Austern's great article ([@http://drdobbs.com/184403814 [*The Standard Librarian: Containers of Incomplete Types]]):
["['Unlike most of my columns, this one is about something you can't do with the C++ Standard library:
put incomplete types in one of the standard containers. This column explains why you might want to
do this, why the standardization committee banned it even though they knew it was useful, and what
you might be able to do to get around the restriction.]]
["['In 1997, shortly before the C++ Standard was completed, the standardization committee received a
query: Is it possible to create standard containers with incomplete types? It took a while for the
committee to understand the question. What would such a thing even mean, and why on earth would you
ever want to do it? The committee eventually worked it out and came up with an answer to the question.
(Just so you don't have to skip ahead to the end, the answer is "no.") But the question is much more
interesting than the answer: it points to a useful, and insufficiently discussed, programming technique.
The standard library doesn't directly support that technique, but the two can be made to coexist.]]
["['In a future revision of C++, it might make sense to relax the restriction on instantiating
standard library templates with incomplete types. Clearly, the general prohibition should stay
in place - instantiating templates with incomplete types is a delicate business, and there are
too many classes in the standard library where it would make no sense. But perhaps it should be
relaxed on a case-by-case basis, and `vector` looks like a good candidate for such special-case
treatment: it's the one standard container class where there are good reasons to instantiate
it with an incomplete type and where Standard Library implementors want to make it work. As of
today, in fact, implementors would have to go out of their way to prohibit it!]]
C++11 standard is also cautious about incomplete types and STL: ["['17.6.4.8 Other functions (...) 2.
the effects are undefined in the following cases: (...) In particular - if an incomplete type (3.9)
is used as a template argument when instantiating a template component,
unless specifically allowed for that component]]. Fortunately [*Boost.Container] containers are designed
to support type erasure and recursive types, so let's see some examples:
[section:recursive_containers Recursive containers]
All containers offered by [*Boost.Container] can be used to define recursive containers:
[import ../example/doc_recursive_containers.cpp]
[doc_recursive_containers]
[endsect]
[section:type_erasure Type Erasure]
Containers of incomplete types are useful to break header file dependencies and improve
compilation types. With Boost.Container, you can write a header file defining a class
with containers of incomplete types as data members, if you carefully put all the
implementation details that require knowing the size of the `value_type` in your
implementation file:
[import ../example/doc_type_erasure.cpp]
In this header file we define a class (`MyClassHolder)` that holds a `vector` of an
incomplete type (`MyClass`) that it's only forward declared.
[doc_type_erasure_MyClassHolder_h]
Then we can define `MyClass` in its own header file.
[doc_type_erasure_MyClass_h]
And include it only in the implementation file of `MyClassHolder`
[doc_type_erasure_MyClassHolder_cpp]
Finally, we can just compile, link, and run!
[doc_type_erasure_main_cpp]
[endsect]
[endsect]
[section:non_standard_containers Non-standard containers]
[section:stable_vector ['stable_vector]]
This useful, fully STL-compliant stable container [@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html designed by by Joaqu\u00EDn M. L\u00F3pez Mu\u00F1oz]
is an hybrid between `vector` and `list`, providing most of
the features of `vector` except [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#69 element contiguity].
Extremely convenient as they are, `vector`s have a limitation that many novice C++ programmers frequently stumble upon:
iterators and references to an element of an `vector` are invalidated when a preceding element is erased or when the
vector expands and needs to migrate its internal storage to a wider memory region (i.e. when the required size exceeds
the vector's capacity). We say then that `vector`s are unstable: by contrast, stable containers are those for which
references and iterators to a given element remain valid as long as the element is not erased: examples of stable containers
within the C++ standard library are `list` and the standard associative containers (`set`, `map`, etc.).
Sometimes stability is too precious a feature to live without, but one particular property of `vector`s, element contiguity,
makes it impossible to add stability to this container. So, provided we sacrifice element contiguity, how much
can a stable design approach the behavior of `vector` (random access iterators, amortized constant time end
insertion/deletion, minimal memory overhead, etc.)?
The following image describes the layout of a possible data structure upon which to base the design of a stable vector:
[$images/stable_vector.png [width 50%] [align center] ]
Each element is stored in its own separate node. All the nodes are referenced from a contiguous array of pointers, but
also every node contains an "up" pointer referring back to the associated array cell. This up pointer is the key element
to implementing stability and random accessibility:
Iterators point to the nodes rather than to the pointer array. This ensures stability, as it is only the pointer array
that needs to be shifted or relocated upon insertion or deletion. Random access operations can be implemented by using
the pointer array as a convenient intermediate zone. For instance, if the iterator it holds a node pointer `it.p` and we
want to advance it by n positions, we simply do:
[c++]
it.p = *(it.p->up+n);
That is, we go "up" to the pointer array, add n there and then go "down" to the resulting node.
[*General properties]. `stable_vector` satisfies all the requirements of a container, a reversible container and a sequence
and provides all the optional operations present in vector. Like vector, iterators are random access. `stable_vector`
does not provide element contiguity; in exchange for this absence, the container is stable, i.e. references and iterators
to an element of a `stable_vector` remain valid as long as the element is not erased, and an iterator that has been
assigned the return value of end() always remain valid until the destruction of the associated `stable_vector`.
[*Operation complexity]. The big-O complexities of `stable_vector` operations match exactly those of vector. In general,
insertion/deletion is constant time at the end of the sequence and linear elsewhere. Unlike vector, `stable_vector`
does not internally perform any value_type destruction, copy/move construction/assignment operations other than those exactly
corresponding to the insertion of new elements or deletion of stored elements, which can sometimes compensate in terms of
performance for the extra burden of doing more pointer manipulation and an additional allocation per element.
[*Exception safety]. (according to [@http://www.boost.org/community/exception_safety.html Abrahams' terminology])
As `stable_vector` does not internally copy/move elements around, some
operations provide stronger exception safety guarantees than in vector:
[table:stable_vector_req Exception safety
[[operation] [exception safety for `vector<T>`] [exception safety for `stable_vector<T>`]]
[[insert] [strong unless copy/move construction/assignment of `T` throw (basic)] [strong]]
[[erase] [no-throw unless copy/move construction/assignment of `T` throw (basic)] [no-throw]]
]
[*Memory overhead]. The C++ standard does not specifiy requirements on memory consumption, but virtually any implementation
of `vector` has the same behavior wih respect to memory usage: the memory allocated by a `vector` v with n elements of type T
is
m[sub v] = c\u2219e,
where c is `v.capacity()` and e is `sizeof(T)`. c can be as low as n if the user has explicitly reserved the exact capacity
required; otherwise, the average value c for a growing `vector` oscillates between 1.25\u2219n and 1.5\u2219n for typical resizing
policies. For `stable_vector`, the memory usage is
m[sub sv] = (c + 1)p + (n + 1)(e + p),
where p is the size of a pointer. We have c + 1 and n + 1 rather than c and n because a dummy node is needed at the end of
the sequence. If we call f the capacity to size ratio c/n and assume that n is large enough, we have that
m[sub sv]/m[sub v] \u2243 (fp + e + p)/fe.
So, `stable_vector` uses less memory than `vector` only when e > p and the capacity to size ratio exceeds a given threshold:
m[sub sv] < m[sub v] <-> f > (e + p)/(e - p). (provided e > p)
This threshold approaches typical values of f below 1.5 when e > 5p; in a 32-bit architecture, when e > 20 bytes.
[*Summary]. `stable_vector` is a drop-in replacement for `vector` providing stability of references and iterators, in exchange
for missing element contiguity and also some performance and memory overhead. When the element objects are expensive to
move around, the performance overhead can turn into a net performance gain for `stable_vector` if many middle insertions
or deletions are performed or if resizing is very frequent. Similarly, if the elements are large there are situations when
the memory used by `stable_vector` can actually be less than required by vector.
['Note: Text and explanations taken from [@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html Joaqu\u00EDn's blog]]
[endsect]
[section:flat_xxx ['flat_(multi)map/set] associative containers]
Using sorted vectors instead of tree-based associative containers is a well-known technique in
C++ world. Matt Austern's classic article
[@http://lafstern.org/matt/col1.pdf Why You Shouldn't Use set, and What You Should Use Instead]
(C++ Report 12:4, April 2000) was enlightening:
["['Red-black trees aren't the only way to organize data that permits lookup in logarithmic time. One of the basic
algorithms of computer science is binary search, which works by successively dividing a range in half. Binary
search is log N and it doesn't require any fancy data structures, just a sorted collection of elements.
(...) You can use whatever data structure is convenient, so long as it provides STL iterator;
usually it's easiest to use a C array, or a vector.]]
["['Both std::lower_bound and set::find take time proportional to log N, but the constants of proportionality
are very different. Using g++ (...) it takes X seconds to perform a million lookups in a
sorted vector<double> of a million elements, and almost twice as long (...) using a set. Moreover,
the set uses almost three times as much memory (48 million bytes) as the vector (16.8 million).]]
["['Using a sorted vector instead of a set gives you faster lookup and much faster iteration,
but at the cost of slower insertion. Insertion into a set, using set::insert, is proportional
to log N, but insertion into a sorted vector, (...)
, is proportional to N. Whenever you insert something into a vector,
vector::insert has to make room by shifting all of the elements that follow it. On average, if you're equally
likely to insert a new element anywhere, you'll be shifting N/2 elements.]]
["['It may sometimes be convenient to bundle all of this together into a small container adaptor.
This class does not satisfy the requirements of a Standard Associative Container, since the complexity of insert is
O(N) rather than O(log N), but otherwise it is almost a drop-in replacement for set.]]
Following Matt Austern's indications, Andrei Alexandrescu's
[@http://www.bestwebbuys.com/Modern-C-Design-Generic-Programming-and-Design-Patterns-Applied-ISBN-9780201704310?isrc=-rd Modern C++ Design]
showed `AssocVector`, a `std::map` drop-in
replacement designed in his [@http://loki-lib.sourceforge.net/ Loki] library:
["['It seems as if we're better off with a sorted vector. The disadvantages of a sorted
vector are linear-time insertions and linear-time deletions (...). In exchange, a vector
offers about twice the lookup speed and a much smaller working set (...).
Loki saves the trouble of maintaining a sorted vector by hand by defining an AssocVector class
template. AssocVector is a drop-in replacement for std::map (it supports the same set of member
functions), implemented on top of std::vector. AssocVector differs from a map in the behavior of
its erase functions (AssocVector::erase invalidates all iterators into the object) and in the
complexity guarantees of insert and erase (linear as opposed to constant). ]]
[*Boost.Container] `flat_[multi]map/set` containers are ordered-vector based associative containers
based on Austern's and Alexandrescu's guidelines. These ordered vector containers have also
benefited recently with the addition of `move semantics` to C++, speeding up insertion
and erasure times considerably. Flat associative containers have the following
attributes:
* Faster lookup than standard associative containers
* Much faster iteration than standard associative containers
* Less memory consumption for small objects (and for big objects if `shrink_to_fit` is used)
* Improved cache performance (data is stored in contiguous memory)
* Non-stable iterators (iterators are invalidated when inserting and erasing elements)
* Non-copyable and non-movable values types can't be stored
* Weaker exception safety than standard associative containers
(copy/move constructors can throw when shifting values in erasures and insertions)
* Slower insertion and erasure than standard associative containers (specially for non-movable types)
[endsect]
[section:slist ['slist]]
When the standard template library was designed, it contained a singly linked list called `slist`.
Unfortunately, this container was not standardized and remained as an extension for many standard
library implementations until C++11 introduced `forward_list`, which is a bit different from the
the original SGI `slist`. According to [@http://www.sgi.com/tech/stl/Slist.html SGI STL documentation]:
["['An `slist` is a singly linked list: a list where each element is linked to the next element, but
not to the previous element. That is, it is a Sequence that supports forward but not backward traversal,
and (amortized) constant time insertion and removal of elements. Slists, like lists, have the important
property that insertion and splicing do not invalidate iterators to list elements, and that even removal
invalidates only the iterators that point to the elements that are removed. The ordering of iterators
may be changed (that is, slist<T>::iterator might have a different predecessor or successor after a list
operation than it did before), but the iterators themselves will not be invalidated or made to point to
different elements unless that invalidation or mutation is explicit.]]
["['The main difference between `slist` and list is that list's iterators are bidirectional iterators,
while slist's iterators are forward iterators. This means that `slist` is less versatile than list;
frequently, however, bidirectional iterators are unnecessary. You should usually use `slist` unless
you actually need the extra functionality of list, because singly linked lists are smaller and faster
than double linked lists.]]
["['Important performance note: like every other Sequence, `slist` defines the member functions insert and erase.
Using these member functions carelessly, however, can result in disastrously slow programs. The problem is that
insert's first argument is an iterator pos, and that it inserts the new element(s) before pos. This means that
insert must find the iterator just before pos; this is a constant-time operation for list, since list has
bidirectional iterators, but for `slist` it must find that iterator by traversing the list from the beginning
up to pos. In other words: insert and erase are slow operations anywhere but near the beginning of the slist.]]
["['Slist provides the member functions insert_after and erase_after, which are constant time operations: you should
always use insert_after and erase_after whenever possible. If you find that insert_after and erase_after aren't
adequate for your needs, and that you often need to use insert and erase in the middle of the list, then you
should probably use list instead of slist.]]
[*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement
insertion and implements it a bit differently for the standard C++11 `forward_list`. `forward_list` has no `size()`
method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size
with every insertion/erasure, allowing constant-time
`splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers
constant-time `size()` for those that don't care about linear-time `splice_after(iterator, slist &, iterator, iterator)`
`size()` and offers an additional `splice_after(iterator, slist &, iterator, iterator, size_type)` method that
can speed up `slist` merging when the programmer already knows the size. `slist` and `forward_list` are therefore
complementary.
[endsect]
[endsect]
[section:Cpp11_conformance C++11 Conformance]
[*Boost.Container] aims for full C++11 conformance except reasoned deviations,
backporting as much as possible for C++03. Obviously, this conformance is a work
in progress so this section explains what C++11 features are implemented and which of them
have been backported to C++03 compilers.
[section:move_emplace Move and Emplace]
For compilers with rvalue references and for those C++03 types that use
[@http://www.boost.org/libs/move Boost.Move] rvalue reference emulation
[*Boost.Container] supports all C++11 features related to move semantics: containers
are movable, requirements for `value_type` are those specified for C++11 containers.
For compilers with variadic templates, [*Boost.Container] supports placement insertion
(`emplace`, ...) functions from C++11. For those compilers without variadic templates
support [*Boost.Container] uses the preprocessor to create a set of overloads up to
a finite (10) number of parameters.
[endsect]
[section:alloc_traits_move_traits Stateful allocators and Scoped allocators]
C++03 was not stateful-allocator friendly. For compactness of container objects and for
simplicity, it did not require containers to support allocators with state: Allocator objects
need not be stored in container objects. It was not possible to store an allocator with state,
say an allocator that holds a pointer to an arena from which to allocate. C++03 allowed implementors
to suppose two allocators of the same type always compare equal (that means that memory allocated
by one allocator object could be deallocated by another instance of the same type) and
allocators were not swapped when the container was swapped.
Many C++ container implementors felt C++03 guarantees were too weak and started to offer extensions.
[*Boost.Container], following [@http://www.boost.org/libs/interprocess/ Boost.Interprocess]
containers experience supporting stateful allocators, offers the following guarantees:
* Allocators are copy-constructed in copy/move constructors
* If possible, a single allocator is hold to construct `value_type` and this allocator is copy constructed
from the user-supplied allocator object during container's constructor. If the container needs an auxiliary
allocator (e.g. a array allocator used by `deque` or `stable_vector`), that allocator is also
copy-constructed from the user-supplied allocator when the container is constructed (i.e. it's
not constructed on the fly when auxiliary memory is needed).
* Allocators are compared for equality when swapping containers. If allocators don't compare
equal allocators are swapped using an unqualified `swap` call.
C++11 further improves stateful allocator support through the
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf
Scoped Allocators model], using classes like `std::scoped_allocator_adaptor` and `std::allocator_traits`.
[*Boost.Container does not support it yet, but there are plans to do so and backport scoped allocator
support to C++03 compilers.
[endsect]
[section:initializer_lists Initializer lists]
[*Boost.Container] does not support initializer lists when constructing or assigning containers
but it will support it for compilers with initialized-list support. This feature won't be backported
to C++03 compilers.
[endsect]
[section:Vector_bool vector<bool>]
`vector<bool>` specialization has been quite problematic, and there have been several
unsuccessful tries to deprecate or remove it from the standard. [*Boost.Container] does not implement it
as there is a superior [@http://www.boost.org/libs/dynamic_bitset/ Boost.DynamicBitset]
solution. For issues with `vector<bool>` see papers
[@http://www.gotw.ca/publications/N1211.pdf vector<bool>: N1211: More Problems, Better Solutions],
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html N2160: Library Issue 96: Fixing vector<bool>],
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2204.html N2204 A Specification to deprecate vector<bool>].
* ["['In 1998, admitting that the committee made a mistake was controversial.
Since then Java has had to deprecate such significant portions of their libraries
that the idea C++ would be ridiculed for deprecating a single minor template specialization seems quaint.]]
* ["['`vector<bool>` is not a container and `vector<bool>::iterator` is not a random-access iterator
(or even a forward or bidirectional iterator either, for that matter). This has already broken user code
in the field in mysterious ways.]]
* ["['`vector<bool>` forces a specific (and potentially bad) optimization choice on all users by enshrining
it in the standard. The optimization is premature; different users have different requirements. This too
has already hurt users who have been forced to implement workarounds to disable the 'optimization'
(e.g., by using a vector<char> and manually casting to/from bool).]]
So `boost::container::vector<bool>::iterator` returns real `bool` references and works as a fully compliant container.
If you need a memory optimized version of `boost::container::vector<bool>` functionalities, please use
[@http://www.boost.org/libs/dynamic_bitset/ Boost.DynamicBitset].
[endsect]
[endsect]
[section:other_features Other features]
* Default constructors don't allocate memory which improves performance and
usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
* Small string optimization for [classref boost::container::basic_string basic_string],
with an internal buffer of 11/23 bytes (32/64 bit systems)
[*without] increasing the usual `sizeof` of the string (3 words).
* `[multi]set/map` containers are size optimized embedding the color bit of the red-black tree nodes
in the parent pointer.
* `[multi]set/map` containers use no recursive functions so stack problems are avoided.
[endsect]
[section:history_and_reasons History and reasons to use Boost.Container]
[section:boost_container_history Boost.Container history]
[*Boost.Container] is a product of a long development effort that started
[@http://lists.boost.org/Archives/boost/2004/11/76263.php in 2004 with the experimental Shmem library],
which pioneered the use of standard containers in shared memory. Shmem included modified SGI STL container
code tweaked to support non-raw `allocator::pointer` types and stateful allocators. Once reviewed,
Shmem was accepted as [@http://www.boost.org/libs/interprocess/ Boost.Interprocess] and this library
continued to refine and improve those containers.
In 2007, container code from node containers (`map`, `list`, `slist`) was rewritten, refactored
and expanded to build the intrusive container library [@http://www.boost.org/libs/intrusive/ Boost.Intrusive].
[*Boost.Interprocess] containers were refactored to take advantage of [*Boost.Intrusive] containers and
code duplication was minimized. Both libraries continued to gain support and bug fixes for years.
They introduced move semantics, emplacement insertion and more features of then unreleased C++0x
standard.
[*Boost.Interprocess] containers were always standard compliant, and those containers and new
containers like `stable_vector` and `flat_[multi]set/map` were used outside [*Boost.Interprocess]
with success. As containers were mature enough to get their own library, it was a natural step to
collect them containers and build [*Boost.Container], a library targeted to a wider audience.
[endsect]
[section:Why_boost_container Why Boost.Container?]
With so many high quality standard library implementations out there, why would you want to
use [*Boost.Container]? There are several reasons for that:
* If you have a C++03 compiler, you can have access to C++11 features and have an easy
code migration when you change your compiler.
* It's compatible with [*Boost.Interprocess] shared memory allocators.
* You have extremely useful new containers like `stable_vector` and `flat_[multi]set/map`.
* If you work on multiple platforms, you'll have a portable behaviour without depending
on the std-lib implementation conformance of each platform. Some examples:
* Default constructors don't allocate memory at all, which improves performance and
usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
* Small string optimization for [classref boost::container::basic_string basic_string].
* New extensions beyond the standard based on user feedback to improve code performance.
[endsect]
[endsect]
[include auto_index_helpers.qbk]
[section:index Indexes]
[named_index class_name Class Index]
[named_index typedef_name Typedef Index]
[named_index function_name Function Index]
[/named_index macro_name Macro Index]
[/index]
[endsect]
[xinclude autodoc.xml]
[section:acknowledgements_notes Acknowledgements, notes and links]
* Original standard container code comes from [@http://www.sgi.com/tech/stl/ SGI STL library],
which enhanced the original HP STL code. Most of this code was rewritten for
[*Boost.Interprocess] and moved to [*Boost.Intrusive]. `deque` and `string` containers still
have fragments of the original SGI code. Many thanks to Alexander Stepanov, Meng Lee, David Musser,
Matt Austern... and all HP and SGI STL developers.
* `flat_[multi]_map/set` containers were originally based on [@http://en.wikipedia.org/wiki/Loki_%28C%2B%2B%29 Loki's]
AssocVector class. Code was rewritten and expanded for [*Boost.Interprocess], so thanks to Andrei Alexandrescu.
* `stable_vector` was invented and coded by
[@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html Joaqu\u00EDn M. L\u00F3pez Mu\u00F1oz],
then adapted for [*Boost.Interprocess]. Thanks for such a great container.
* Howard Hinnant's help and advices were essential when implementing move semantics,
improving allocator support or implementing small string optimization. Thanks Howard
for your wonderful standard library implementations.
* And finally thanks to all Boosters who helped all these years, improving, fixing and
reviewing all my libraries.
[endsect]
[section:release_notes Release Notes]
* First release with Boost 1.48. Container code from [*Boost.Interprocess] was deleted
and redirected to [*Boost.Container ] via using directives.
[endsect]

537
doc/html/boostbook.css Normal file
View File

@@ -0,0 +1,537 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
Use, modification and distribution is subject to 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)
=============================================================================*/
/*=============================================================================
Body defaults
=============================================================================*/
body
{
margin: 1em;
font-family: sans-serif;
}
/*=============================================================================
Paragraphs
=============================================================================*/
p
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Program listings
=============================================================================*/
/* Code on paragraphs */
p tt.computeroutput
{
font-size: 10pt;
}
pre.synopsis
{
font-size: 10pt;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.programlisting,
.screen
{
font-size: 10pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/*=============================================================================
Headings
=============================================================================*/
h1, h2, h3, h4, h5, h6
{
text-align: left;
margin: 1em 0em 0.5em 0em;
font-weight: bold;
}
h1 { font: 140% }
h2 { font: bold 140% }
h3 { font: bold 130% }
h4 { font: bold 120% }
h5 { font: italic 110% }
h6 { font: italic 100% }
/* Top page titles */
title,
h1.title,
h2.title
h3.title,
h4.title,
h5.title,
h6.title,
.refentrytitle
{
font-weight: bold;
margin-bottom: 1pc;
}
h1.title { font-size: 140% }
h2.title { font-size: 140% }
h3.title { font-size: 130% }
h4.title { font-size: 120% }
h5.title { font-size: 110% }
h6.title { font-size: 100% }
.section h1
{
margin: 0em 0em 0.5em 0em;
font-size: 140%;
}
.section h2 { font-size: 140% }
.section h3 { font-size: 130% }
.section h4 { font-size: 120% }
.section h5 { font-size: 110% }
.section h6 { font-size: 100% }
/* Code on titles */
h1 tt.computeroutput { font-size: 140% }
h2 tt.computeroutput { font-size: 140% }
h3 tt.computeroutput { font-size: 130% }
h4 tt.computeroutput { font-size: 120% }
h5 tt.computeroutput { font-size: 110% }
h6 tt.computeroutput { font-size: 100% }
/*=============================================================================
Author
=============================================================================*/
h3.author
{
font-size: 100%
}
/*=============================================================================
Lists
=============================================================================*/
li
{
font-size: 10pt;
line-height: 1.3;
}
/* Unordered lists */
ul
{
text-align: left;
}
/* Ordered lists */
ol
{
text-align: left;
}
/*=============================================================================
Links
=============================================================================*/
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/*=============================================================================
Spirit style navigation
=============================================================================*/
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/*=============================================================================
Table of contents
=============================================================================*/
.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 10pt;
line-height: 1.15;
}
.toc-main
{
width: 600;
text-align: center;
margin: 1pc 1pc 1pc 10%;
padding: 2pc 1pc 3pc 1pc;
line-height: 0.1;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/*=============================================================================
Tables
=============================================================================*/
.table-title,
div.table p.title
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
}
.informaltable table,
.table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table,
div.table table
{
padding: 4px;
}
/* Table Cells */
div.informaltable table tr td,
div.table table tr td
{
padding: 0.5em;
text-align: left;
}
div.informaltable table tr th,
div.table table tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 120%;
}
/*=============================================================================
Blurbs
=============================================================================*/
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
font-size: 10pt;
line-height: 1.2;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
p.blurb img
{
padding: 1pt;
}
/*=============================================================================
Variable Lists
=============================================================================*/
span.term
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist table tbody tr td
{
text-align: left;
vertical-align: top;
padding: 0em 2em 0em 0em;
font-size: 10pt;
}
div.variablelist table tbody tr td p
{
margin: 0em 0em 0.5em 0em;
}
/* Make the terms in definition lists bold */
div.variablelist dl dt
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist dl dd
{
margin: 1em 0em 1em 2em;
font-size: 10pt;
}
/*=============================================================================
Misc
=============================================================================*/
/* Title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
span.underline
{
text-decoration: underline;
}
span.strikethrough
{
text-decoration: line-through;
}
/* Copyright, Legal Notice */
div div.legalnotice p
{
font-size: 8pt;
text-align: left
}
/*=============================================================================
Colors
=============================================================================*/
@media screen
{
/* Links */
a
{
color: #0C7445;
}
a:visited
{
color: #663974;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
{
text-decoration: none; /* no underline */
color: #000000;
}
/* Syntax Highlighting */
.keyword { color: #0000AA; }
.identifier { color: #000000; }
.special { color: #707070; }
.preprocessor { color: #402080; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.white_bkd { background-color: #E8FBE9; }
.dk_grey_bkd { background-color: #A0DAAC; }
/* Copyright, Legal Notice */
.copyright
{
color: #666666;
font-size: small;
}
div div.legalnotice p
{
color: #666666;
}
/* Program listing */
pre.synopsis
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
.programlisting,
.screen
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Blurbs */
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Table of contents */
.toc
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Table of contents */
.toc-main
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
background-color: #FAFFFB;
}
div.informaltable table tr th,
div.table table tr th
{
background-color: #E3F9E4;
border: 1px solid #DCDCDC;
}
/* Misc */
span.highlight
{
color: #00A000;
}
}
@media print
{
/* Links */
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Program listing */
pre.synopsis
{
border: 1px solid gray;
background-color: #FAFFFB;
}
.programlisting,
.screen
{
border: 1px solid gray;
background-color: #FAFFFB;
}
/* Table of contents */
.toc
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
/* Table of contents */
.toc-main
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
background-color: #FAFFFB;
}
.informaltable table,
.table table
{
border: 1px solid #DCDCDC;
border-bottom: 3px solid #9D9D9D;
border-right: 3px solid #9D9D9D;
border-collapse: collapse;
background-color: #FAFFFB;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
background-color: #FAFFFB;
}
div.informaltable table tr th,
div.table table tr th
{
border: 1px solid #DCDCDC;
background-color: #FAFFFB;
}
/* Misc */
span.highlight
{
font-weight: bold;
}
}

BIN
doc/html/images/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

BIN
doc/html/images/caution.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
doc/html/images/draft.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
doc/html/images/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

BIN
doc/html/images/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

BIN
doc/html/images/note.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

BIN
doc/html/images/prev.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
doc/html/images/tip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

BIN
doc/html/images/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

BIN
doc/html/images/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

12
doc/html/reference.css Normal file
View File

@@ -0,0 +1,12 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
Use, modification and distribution is subject to 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)
=============================================================================*/
PRE.synopsis {
background-color: #e0ffff;
border: thin solid blue;
padding: 1em
}

1
doc/index.idx Normal file
View File

@@ -0,0 +1 @@
!scan-path "boost/container" ".*.hpp" false

34
example/Jamfile.v2 Normal file
View File

@@ -0,0 +1,34 @@
# Boost Container Library Example Jamfile
# (C) Copyright Ion Gaztanaga 2009
# Use, modification and distribution are subject to 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)
# Adapted from John Maddock's TR1 Jamfile.v2
# Copyright John Maddock 2005.
# Use, modification and distribution are subject to 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)
# this rule enumerates through all the sources and invokes
# the run rule for each source, the result is a list of all
# the run rules, which we can pass on to the test_suite rule:
rule test_all
{
local all_rules = ;
for local fileb in [ glob doc_*.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite container_example : [ test_all r ] : <threading>multi ;

44
example/doc_emplace.cpp Normal file
View File

@@ -0,0 +1,44 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
//[doc_emplace
#include <boost/container/list.hpp>
#include <cassert>
//Non-copyable and non-movable class
class non_copy_movable
{
non_copy_movable(const non_copy_movable &);
non_copy_movable& operator=(const non_copy_movable &);
public:
non_copy_movable(int = 0) {}
};
int main ()
{
using namespace boost::container;
//Store non-copyable and non-movable objects in a list
list<non_copy_movable> l;
non_copy_movable ncm;
//A new element will be built calling non_copy_movable(int) contructor
l.emplace(l.begin(), 0);
assert(l.size() == 1);
//A new element will be built calling the default constructor
l.emplace(l.begin());
assert(l.size() == 2);
return 0;
}
//]
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
//[doc_move_containers
#include <boost/container/vector.hpp>
#include <boost/move/move.hpp>
#include <cassert>
//Non-copyable class
class non_copyable
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(non_copyable)
public:
non_copyable(){}
non_copyable(BOOST_RV_REF(non_copyable)) {}
non_copyable& operator=(BOOST_RV_REF(non_copyable)) { return *this; }
};
int main ()
{
using namespace boost::container;
//Store non-copyable objects in a vector
vector<non_copyable> v;
non_copyable nc;
v.push_back(boost::move(nc));
assert(v.size() == 1);
//Reserve no longer needs copy-constructible
v.reserve(100);
assert(v.capacity() >= 100);
//This resize overload only needs movable and default constructible
v.resize(200);
assert(v.size() == 200);
//Containers are also movable
vector<non_copyable> v_other(boost::move(v));
assert(v_other.size() == 200);
assert(v.empty());
return 0;
}
//]
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,61 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
//[doc_recursive_containers
#include <boost/container/vector.hpp>
#include <boost/container/list.hpp>
#include <boost/container/map.hpp>
#include <boost/container/stable_vector.hpp>
#include <boost/container/string.hpp>
using namespace boost::container;
struct data
{
int i_;
//A vector holding still undefined class 'data'
vector<data> v_;
//A list holding still undefined 'data'
list<data> l_;
//A map holding still undefined 'data'
map<data, data> m_;
friend bool operator <(const data &l, const data &r)
{ return l.i_ < r.i_; }
};
struct tree_node
{
string name;
string value;
//children nodes of this node
list<tree_node> children_;
};
int main()
{
//a container holding a recursive data type
stable_vector<data> sv;
sv.resize(100);
//Let's build a tree based in
//a recursive data type
tree_node root;
root.name = "root";
root.value = "root_value";
root.children_.resize(7);
return 0;
}
//]
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,91 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
//[doc_type_erasure_MyClassHolder_h
#include <boost/container/vector.hpp>
//MyClassHolder.h
//We don't need to include "MyClass.h"
//to store vector<MyClass>
class MyClass;
class MyClassHolder
{
public:
void AddNewObject(const MyClass &o);
const MyClass & GetLastObject() const;
private:
::boost::container::vector<MyClass> vector_;
};
//]
//[doc_type_erasure_MyClass_h
//MyClass.h
class MyClass
{
private:
int value_;
public:
MyClass(int val = 0) : value_(val){}
friend bool operator==(const MyClass &l, const MyClass &r)
{ return l.value_ == r.value_; }
//...
};
//]
//[doc_type_erasure_main_cpp
//Main.cpp
//=#include "MyClassHolder.h"
//=#include "MyClass.h"
#include <cassert>
int main()
{
MyClass mc(7);
MyClassHolder myclassholder;
myclassholder.AddNewObject(mc);
return myclassholder.GetLastObject() == mc ? 0 : 1;
}
//]
//[doc_type_erasure_MyClassHolder_cpp
//MyClassHolder.cpp
//=#include "MyClassHolder.h"
//In the implementation MyClass must be a complete
//type so we include the appropriate header
//=#include "MyClass.h"
void MyClassHolder::AddNewObject(const MyClass &o)
{ vector_.push_back(o); }
const MyClass & MyClassHolder::GetLastObject() const
{ return vector_.back(); }
//]
#include <boost/container/detail/config_end.hpp>

14
index.html Normal file
View File

@@ -0,0 +1,14 @@
<!--
Copyright 2005-2011 Ion Gaztanaga
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)
-->
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../doc/html/container.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="../../doc/html/container.html">../../doc/html/container.html</a>
</body>
</html>

2
proj/to-do.txt Normal file
View File

@@ -0,0 +1,2 @@
->Change "insert" and "push_back"/"push_front" to catch non-const rvalues
->Add an example with stateful allocators

87
proj/vc7ide/container.sln Normal file
View File

@@ -0,0 +1,87 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deque_test", "deque_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792655}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792637}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792632}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stable_vector_test", "stable_vector_test.vcproj", "{5E11C8D3-FA52-760A-84FE-943A6BA05A21}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_test", "string_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D4A792607}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tree_test", "tree_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist_test", "slist_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_test", "vector_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_containerlib", "container.vcproj", "{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Debug.ActiveCfg = Debug|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Debug.Build.0 = Debug|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Release.ActiveCfg = Release|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.Build.0 = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.ActiveCfg = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.Build.0 = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.ActiveCfg = Release|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,321 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="_containerlib"
ProjectGUID="{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32"
IntermediateDirectory="Debug"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/d.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32"
IntermediateDirectory="Release"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/container.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="detail"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\detail\adaptive_node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\advanced_insert_int.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\algorithms.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\allocation_type.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_begin.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_end.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\destroyers.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\flat_tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\iterators.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\multiallocation_chain.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pair.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pool_common.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\preprocessor.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\transform_iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\type_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\utilities.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\value_init.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\variadic_templates_tools.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\version_type.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\workaround.hpp">
</File>
</Filter>
<Filter
Name="Documentation"
Filter="">
<File
RelativePath="..\..\doc\container.qbk">
</File>
<File
RelativePath="..\..\doc\index.idx">
</File>
<File
RelativePath="..\..\doc\Jamfile.v2">
</File>
</Filter>
<Filter
Name="example"
Filter="">
<File
RelativePath="..\..\example\doc_emplace.cpp">
</File>
<File
RelativePath="..\..\example\doc_move_containers.cpp">
</File>
<File
RelativePath="..\..\example\doc_recursive_containers.cpp">
</File>
<File
RelativePath="..\..\example\doc_type_erasure.cpp">
</File>
<File
RelativePath="..\..\example\Jamfile.v2">
</File>
</Filter>
<Filter
Name="test"
Filter="">
<File
RelativePath="..\..\test\boost_interprocess_check.hpp">
</File>
<File
RelativePath="..\..\test\check_equal_containers.hpp">
</File>
<File
RelativePath="..\..\test\deque_test.cpp">
</File>
<File
RelativePath="..\..\test\dummy_test_allocator.hpp">
</File>
<File
RelativePath="..\..\test\emplace_test.hpp">
</File>
<File
RelativePath="..\..\test\expand_bwd_test_allocator.hpp">
</File>
<File
RelativePath="..\..\test\expand_bwd_test_template.hpp">
</File>
<File
RelativePath="..\..\test\flat_tree_test.cpp">
</File>
<File
RelativePath="..\..\test\heap_allocator_v1.hpp">
</File>
<File
RelativePath="..\..\test\Jamfile.v2">
</File>
<File
RelativePath="..\..\test\list_test.cpp">
</File>
<File
RelativePath="..\..\test\list_test.hpp">
</File>
<File
RelativePath="..\..\test\map_test.hpp">
</File>
<File
RelativePath="..\..\test\movable_int.hpp">
</File>
<File
RelativePath="..\..\test\print_container.hpp">
</File>
<File
RelativePath="..\..\test\set_test.hpp">
</File>
<File
RelativePath="..\..\test\slist_test.cpp">
</File>
<File
RelativePath="..\..\test\stable_vector_test.cpp">
</File>
<File
RelativePath="..\..\test\string_test.cpp">
</File>
<File
RelativePath="..\..\test\tree_test.cpp">
</File>
<File
RelativePath="..\..\test\util.hpp">
</File>
<File
RelativePath="..\..\test\vector_test.cpp">
</File>
<File
RelativePath="..\..\test\vector_test.hpp">
</File>
</Filter>
<File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\deque.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\flat_map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\flat_set.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\list.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\set.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\slist.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\stable_vector.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\string.hpp">
</File>
<File
RelativePath="..\to-do.txt">
</File>
<File
RelativePath="..\..\..\..\boost\container\vector.hpp">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="deque_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792655}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/deque_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/deque_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/deque_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/deque_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/deque_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\deque_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="flat_tree_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792637}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/flat_tree_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/flat_tree_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/flat_tree_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/flat_tree_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/flat_tree_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\flat_tree_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

140
proj/vc7ide/list_ex.vcproj Normal file
View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="list_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792632}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/list_ex"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/list_ex_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/list_ex.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/list_ex"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/list_ex.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\list_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="slist_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/slist_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/slist_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/slist_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/slist_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/slist_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\slist_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="stable_vector_test"
ProjectGUID="{5E11C8D3-FA52-760A-84FE-943A6BA05A21}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/stable_vector_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/stable_vector_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/stable_vector_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/stable_vector_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/stable_vector_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{37BC807F-2451-A306-7AC5-7A35A32A22DF}">
<File
RelativePath="..\..\test\stable_vector_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="string_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D4A792607}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/string_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/string_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/string_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/string_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/string_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\string_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="tree_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/tree_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/tree_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/tree_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/tree_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/tree_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\tree_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="vector_test"
ProjectGUID="{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/vector_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/vector_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/vector_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/vector_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/vector_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\vector_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

34
test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,34 @@
# Boost Container Library Test Jamfile
# (C) Copyright Ion Gaztanaga 2009.
# Use, modification and distribution are subject to 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)
# Adapted from John Maddock's TR1 Jamfile.v2
# Copyright John Maddock 2005.
# Use, modification and distribution are subject to 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)
# this rule enumerates through all the sources and invokes
# the run rule for each source, the result is a list of all
# the run rules, which we can pass on to the test_suite rule:
rule test_all
{
local all_rules = ;
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite container_test : [ test_all r ] ;

View File

@@ -0,0 +1,76 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
#include <boost/container/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
namespace boost{
namespace container {
namespace test{
//Function to check if both containers are equal
template<class MyBoostCont
,class MyStdCont>
bool CheckEqualContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
{
if(boostcont->size() != stdcont->size())
return false;
typedef typename MyBoostCont::value_type value_type;
typename MyBoostCont::iterator itboost(boostcont->begin()), itboostend(boostcont->end());
typename MyStdCont::iterator itstd(stdcont->begin());
typename MyStdCont::size_type dist = (typename MyStdCont::size_type)std::distance(itboost, itboostend);
if(dist != boostcont->size()){
return false;
}
std::size_t i = 0;
for(; itboost != itboostend; ++itboost, ++itstd, ++i){
value_type val(*itstd);
const value_type &v = *itboost;
if(v != val)
return false;
}
return true;
}
template<class MyBoostCont
,class MyStdCont>
bool CheckEqualPairContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
{
if(boostcont->size() != stdcont->size())
return false;
typedef typename MyBoostCont::key_type key_type;
typedef typename MyBoostCont::mapped_type mapped_type;
typename MyBoostCont::iterator itboost(boostcont->begin()), itboostend(boostcont->end());
typename MyStdCont::iterator itstd(stdcont->begin());
for(; itboost != itboostend; ++itboost, ++itstd){
if(itboost->first != key_type(itstd->first))
return false;
if(itboost->second != mapped_type(itstd->second))
return false;
}
return true;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP

295
test/deque_test.cpp Normal file
View File

@@ -0,0 +1,295 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <deque>
#include <iostream>
#include <functional>
#include <list>
#include <boost/container/deque.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include <boost/move/move.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <string>
#include "emplace_test.hpp"
#include "vector_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::deque
< test::movable_and_copyable_int
, test::dummy_test_allocator<test::movable_and_copyable_int> >;
//Function to check if both sets are equal
template<class V1, class V2>
bool deque_copyable_only(V1 *, V2 *, containers_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, containers_detail::true_type)
{
typedef typename V1::value_type IntType;
std::size_t size = cntdeque->size();
stddeque->insert(stddeque->end(), 50, 1);
cntdeque->insert(cntdeque->end(), 50, 1);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
{
IntType move_me(1);
stddeque->insert(stddeque->begin()+size/2, 50, 1);
cntdeque->insert(cntdeque->begin()+size/2, 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType move_me(2);
cntdeque->assign(cntdeque->size()/2, boost::move(move_me));
stddeque->assign(stddeque->size()/2, 2);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType move_me(1);
stddeque->clear();
cntdeque->clear();
stddeque->insert(stddeque->begin(), 50, 1);
cntdeque->insert(cntdeque->begin(), 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->begin()+20, 50, 1);
cntdeque->insert(cntdeque->begin()+20, 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->begin()+20, 20, 1);
cntdeque->insert(cntdeque->begin()+20, 20, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType move_me(1);
stddeque->clear();
cntdeque->clear();
stddeque->insert(stddeque->end(), 50, 1);
cntdeque->insert(cntdeque->end(), 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->end()-20, 50, 1);
cntdeque->insert(cntdeque->end()-20, 50, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
stddeque->insert(stddeque->end()-20, 20, 1);
cntdeque->insert(cntdeque->end()-20, 20, boost::move(move_me));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
return true;
}
//Test recursive structures
class recursive_deque
{
public:
int id_;
deque<recursive_deque> deque_;
};
template<class IntType>
bool do_test()
{
//Test for recursive types
{
deque<recursive_deque> recursive_deque_deque;
}
{
//Now test move semantics
deque<recursive_deque> original;
deque<recursive_deque> move_ctor(boost::move(original));
deque<recursive_deque> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
//Alias deque types
typedef deque<IntType> MyCntDeque;
typedef std::deque<int> MyStdDeque;
const int max = 100;
try{
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyCntDeque *cntdeque = new MyCntDeque;
MyStdDeque *stddeque = new MyStdDeque;
//Compare several shared memory deque operations with std::deque
int i;
for(i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->insert(cntdeque->end(), boost::move(move_me));
stddeque->insert(stddeque->end(), i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
cntdeque->clear();
stddeque->clear();
for(i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->push_back(boost::move(move_me));
stddeque->push_back(i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
cntdeque->clear();
stddeque->clear();
for(i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->push_front(boost::move(move_me));
stddeque->push_front(i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
typename MyCntDeque::iterator it;
typename MyCntDeque::const_iterator cit = it;
cntdeque->erase(cntdeque->begin()++);
stddeque->erase(stddeque->begin()++);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
cntdeque->erase(cntdeque->begin());
stddeque->erase(stddeque->begin());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
{
//Initialize values
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me (-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
cntdeque->insert(cntdeque->end()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
for(int i = 0, j = static_cast<int>(cntdeque->size()); i < j; ++i){
cntdeque->erase(cntdeque->begin());
stddeque->erase(stddeque->begin());
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
cntdeque->insert(cntdeque->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stddeque->insert(stddeque->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
}
if(!deque_copyable_only(cntdeque, stddeque
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return false;
}
cntdeque->erase(cntdeque->begin());
stddeque->erase(stddeque->begin());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
for(i = 0; i < max; ++i){
IntType move_me(i);
cntdeque->insert(cntdeque->begin(), boost::move(move_me));
stddeque->insert(stddeque->begin(), i);
}
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
//Test insertion from list
{
std::list<int> l(50, int(1));
cntdeque->insert(cntdeque->begin(), l.begin(), l.end());
stddeque->insert(stddeque->begin(), l.begin(), l.end());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
cntdeque->assign(l.begin(), l.end());
stddeque->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
}
cntdeque->resize(100);
stddeque->resize(100);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
cntdeque->resize(200);
stddeque->resize(200);
if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1;
delete cntdeque;
delete stddeque;
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;
return false;
}
std::cout << std::endl << "Test OK!" << std::endl;
return true;
}
int main ()
{
if(!do_test<int>())
return 1;
if(!do_test<test::movable_int>())
return 1;
{
typedef deque<int> MyDeque;
typedef deque<test::movable_int> MyMoveDeque;
typedef deque<test::movable_and_copyable_int> MyCopyMoveDeque;
typedef deque<test::copyable_int> MyCopyDeque;
if(test::vector_test<MyDeque>())
return 1;
if(test::vector_test<MyMoveDeque>())
return 1;
if(test::vector_test<MyCopyMoveDeque>())
return 1;
if(test::vector_test<MyCopyDeque>())
return 1;
}
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace
< deque<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,157 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
#define BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file
//!Describes an allocator to test expand capabilities
namespace boost {
namespace container {
namespace test {
//This allocator just allows two allocations. The first one will return
//mp_buffer + m_offset configured in the constructor. The second one
//will return mp_buffer.
template<class T>
class dummy_test_allocator
{
private:
typedef dummy_test_allocator<T> self_t;
typedef void * aux_pointer_t;
typedef const void * cvoid_ptr;
template<class T2>
dummy_test_allocator& operator=(const dummy_test_allocator<T2>&);
dummy_test_allocator& operator=(const dummy_test_allocator&);
public:
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef typename containers_detail::add_reference
<value_type>::type reference;
typedef typename containers_detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// typedef boost::container::version_type<dummy_test_allocator, 2> version;
template<class T2>
struct rebind
{ typedef dummy_test_allocator<T2> other; };
//!Default constructor. Never throws
dummy_test_allocator()
{}
//!Constructor from other dummy_test_allocator. Never throws
dummy_test_allocator(const dummy_test_allocator &)
{}
//!Constructor from related dummy_test_allocator. Never throws
template<class T2>
dummy_test_allocator(const dummy_test_allocator<T2> &)
{}
pointer address(reference value)
{ return pointer(addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
pointer allocate(size_type, cvoid_ptr = 0)
{ return 0; }
void deallocate(const pointer &, size_type)
{ }
template<class Convertible>
void construct(pointer, const Convertible &)
{}
void destroy(pointer)
{}
size_type max_size() const
{ return 0; }
friend void swap(self_t &, self_t &)
{}
//Experimental version 2 dummy_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::container::allocation_type,
size_type,
size_type,
size_type &, const pointer & = 0)
{ return std::pair<pointer, bool>(pointer(0), true); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
size_type size(const pointer &) const
{ return 0; }
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate_one()
{ return pointer(0); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &)
{}
};
//!Equality test for same type of dummy_test_allocator
template<class T> inline
bool operator==(const dummy_test_allocator<T> &,
const dummy_test_allocator<T> &)
{ return false; }
//!Inequality test for same type of dummy_test_allocator
template<class T> inline
bool operator!=(const dummy_test_allocator<T> &,
const dummy_test_allocator<T> &)
{ return true; }
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP

625
test/emplace_test.hpp Normal file
View File

@@ -0,0 +1,625 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
#define BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
#include <iostream>
#include <typeinfo>
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/aligned_storage.hpp>
namespace boost{
namespace container {
namespace test{
class EmplaceInt
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
public:
EmplaceInt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0)
: a_(a), b_(b), c_(c), d_(d), e_(e)
{}
EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
: a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
{}
EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
{
this->a_ = o.a_;
this->b_ = o.b_;
this->c_ = o.c_;
this->d_ = o.d_;
this->e_ = o.e_;
return *this;
}
friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
{
return l.a_ == r.a_ &&
l.b_ == r.b_ &&
l.c_ == r.c_ &&
l.d_ == r.d_ &&
l.e_ == r.e_;
}
friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
{ return l.sum() < r.sum(); }
friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
{ return l.sum() > r.sum(); }
friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
{ return !(l == r); }
friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
{
os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
return os;
}
~EmplaceInt()
{ a_ = b_ = c_ = d_ = e_ = 0; }
//private:
int sum() const
{ return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
int a_, b_, c_, d_, e_;
int padding[6];
};
} //namespace test {
namespace test {
enum EmplaceOptions{
EMPLACE_BACK = 1 << 0,
EMPLACE_FRONT = 1 << 1,
EMPLACE_BEFORE = 1 << 2,
EMPLACE_AFTER = 1 << 3,
EMPLACE_ASSOC = 1 << 4,
EMPLACE_HINT = 1 << 5,
EMPLACE_ASSOC_PAIR = 1 << 6,
EMPLACE_HINT_PAIR = 1 << 7
};
template<class Container>
bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n)
{
typedef typename Container::const_iterator const_iterator;
const_iterator itb(ec.begin()), ite(ec.end());
unsigned int cur = 0;
if(only_first_n > ec.size()){
return false;
}
for(; itb != ite && only_first_n--; ++itb, ++cur){
const EmplaceInt & cr = *itb;
if(cr != Expected[cur]){
return false;
}
}
return true;
}
template<class Container>
bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
{
typedef typename Container::const_iterator const_iterator;
const_iterator itb(ec.begin()), ite(ec.end());
unsigned int cur = 0;
if(only_first_n > ec.size()){
return false;
}
for(; itb != ite && only_first_n--; ++itb, ++cur){
if(itb->first != Expected[cur].first){
std::cout << "Error in first: " << itb->first << ' ' << Expected[cur].first << std::endl;
return false;
}
else if(itb->second != Expected[cur].second){
std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
return false;
}
}
return true;
}
static EmplaceInt expected [10];
typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
static boost::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
static EmplaceIntPair* initialize_emplace_int_pair()
{
EmplaceIntPair* ret = reinterpret_cast<EmplaceIntPair*>(&pair_storage);
for(unsigned int i = 0; i != 10; ++i){
new(&ret->first)EmplaceInt();
new(&ret->second)EmplaceInt();
}
return ret;
}
static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
template<class Container>
bool test_emplace_back(containers_detail::true_)
{
std::cout << "Starting test_emplace_back." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
Container c;
c.emplace_back();
if(!test_expected_container(c, &expected[0], 1))
return false;
c.emplace_back(1);
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace_back(1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
c.emplace_back(1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
c.emplace_back(1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
c.emplace_back(1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_back(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_front(containers_detail::true_)
{
std::cout << "Starting test_emplace_front." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
new(&expected [1]) EmplaceInt(1, 2, 3, 4);
new(&expected [2]) EmplaceInt(1, 2, 3);
new(&expected [3]) EmplaceInt(1, 2);
new(&expected [4]) EmplaceInt(1);
new(&expected [5]) EmplaceInt();
Container c;
c.emplace_front();
if(!test_expected_container(c, &expected[0] + 5, 1))
return false;
c.emplace_front(1);/*
if(!test_expected_container(c, &expected[0] + 4, 2))
return false;
c.emplace_front(1, 2);
if(!test_expected_container(c, &expected[0] + 3, 3))
return false;
c.emplace_front(1, 2, 3);
if(!test_expected_container(c, &expected[0] + 2, 4))
return false;
c.emplace_front(1, 2, 3, 4);
if(!test_expected_container(c, &expected[0] + 1, 5))
return false;
c.emplace_front(1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0] + 0, 6))
return false;*/
}
return true;
}
template<class Container>
bool test_emplace_front(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_before(containers_detail::true_)
{
std::cout << "Starting test_emplace_before." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt();
Container c;
c.emplace(c.cend(), 1);
c.emplace(c.cbegin());
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace(c.cend());
if(!test_expected_container(c, &expected[0], 3))
return false;
}
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
//emplace_front-like
Container c;
c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
c.emplace(c.cbegin(), 1, 2, 3, 4);
c.emplace(c.cbegin(), 1, 2, 3);
c.emplace(c.cbegin(), 1, 2);
c.emplace(c.cbegin(), 1);
c.emplace(c.cbegin());
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace_back-like
typename Container::const_iterator i = c.emplace(c.cend());
if(!test_expected_container(c, &expected[0], 1))
return false;
i = c.emplace(++i, 1);
if(!test_expected_container(c, &expected[0], 2))
return false;
i = c.emplace(++i, 1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
i = c.emplace(++i, 1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
i = c.emplace(++i, 1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
i = c.emplace(++i, 1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace in the middle
c.emplace(c.cbegin());
i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
i = c.emplace(i, 1, 2, 3, 4);
i = c.emplace(i, 1, 2, 3);
i = c.emplace(i, 1, 2);
i = c.emplace(i, 1);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_before(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_after(containers_detail::true_)
{
std::cout << "Starting test_emplace_after." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt();
Container c;
typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
c.emplace_after(c.cbefore_begin());
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace_after(i);
if(!test_expected_container(c, &expected[0], 3))
return false;
}
{
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
//emplace_front-like
Container c;
c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4, 5);
c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4);
c.emplace_after(c.cbefore_begin(), 1, 2, 3);
c.emplace_after(c.cbefore_begin(), 1, 2);
c.emplace_after(c.cbefore_begin(), 1);
c.emplace_after(c.cbefore_begin());
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace_back-like
typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
if(!test_expected_container(c, &expected[0], 1))
return false;
i = c.emplace_after(i, 1);
if(!test_expected_container(c, &expected[0], 2))
return false;
i = c.emplace_after(i, 1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
i = c.emplace_after(i, 1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
i = c.emplace_after(i, 1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
i = c.emplace_after(i, 1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
c.clear();
//emplace_after in the middle
i = c.emplace_after(c.cbefore_begin());
c.emplace_after(i, 1, 2, 3, 4, 5);
c.emplace_after(i, 1, 2, 3, 4);
c.emplace_after(i, 1, 2, 3);
c.emplace_after(i, 1, 2);
c.emplace_after(i, 1);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_after(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_assoc(containers_detail::true_)
{
std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
{
Container c;
c.emplace();
if(!test_expected_container(c, &expected[0], 1))
return false;
c.emplace(1);
if(!test_expected_container(c, &expected[0], 2))
return false;
c.emplace(1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
c.emplace(1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
c.emplace(1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
c.emplace(1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_assoc(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_hint(containers_detail::true_)
{
std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected [0]) EmplaceInt();
new(&expected [1]) EmplaceInt(1);
new(&expected [2]) EmplaceInt(1, 2);
new(&expected [3]) EmplaceInt(1, 2, 3);
new(&expected [4]) EmplaceInt(1, 2, 3, 4);
new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
{
Container c;
typename Container::const_iterator it;
it = c.emplace_hint(c.begin());
if(!test_expected_container(c, &expected[0], 1))
return false;
it = c.emplace_hint(it, 1);
if(!test_expected_container(c, &expected[0], 2))
return false;
it = c.emplace_hint(it, 1, 2);
if(!test_expected_container(c, &expected[0], 3))
return false;
it = c.emplace_hint(it, 1, 2, 3);
if(!test_expected_container(c, &expected[0], 4))
return false;
it = c.emplace_hint(it, 1, 2, 3, 4);
if(!test_expected_container(c, &expected[0], 5))
return false;
it = c.emplace_hint(it, 1, 2, 3, 4, 5);
if(!test_expected_container(c, &expected[0], 6))
return false;
}
return true;
}
template<class Container>
bool test_emplace_hint(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_assoc_pair(containers_detail::true_)
{
std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected_pair[0].first) EmplaceInt();
new(&expected_pair[0].second) EmplaceInt();
new(&expected_pair[1].first) EmplaceInt(1);
new(&expected_pair[1].second) EmplaceInt();
new(&expected_pair[2].first) EmplaceInt(2);
new(&expected_pair[2].second) EmplaceInt(2);
new(&expected_pair[3].first) EmplaceInt(3);
new(&expected_pair[3].second) EmplaceInt(2, 3);
new(&expected_pair[4].first) EmplaceInt(4);
new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
new(&expected_pair[5].first) EmplaceInt(5);
new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
{
Container c;
c.emplace();
if(!test_expected_container(c, &expected_pair[0], 1)){
std::cout << "Error after c.emplace();\n";
return false;
}
c.emplace(1);
if(!test_expected_container(c, &expected_pair[0], 2)){
std::cout << "Error after c.emplace(1);\n";
return false;
}
c.emplace(2, 2);
if(!test_expected_container(c, &expected_pair[0], 3)){
std::cout << "Error after c.emplace(2, 2);\n";
return false;
}
c.emplace(3, 2, 3);
if(!test_expected_container(c, &expected_pair[0], 4)){
std::cout << "Error after c.emplace(3, 2, 3);\n";
return false;
}
c.emplace(4, 2, 3, 4);
if(!test_expected_container(c, &expected_pair[0], 5)){
std::cout << "Error after c.emplace(4, 2, 3, 4);\n";
return false;
}
c.emplace(5, 2, 3, 4, 5);
if(!test_expected_container(c, &expected_pair[0], 6)){
std::cout << "Error after c.emplace(5, 2, 3, 4, 5);\n";
return false;
}
}
return true;
}
template<class Container>
bool test_emplace_assoc_pair(containers_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_hint_pair(containers_detail::true_)
{
std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
new(&expected_pair[0].first) EmplaceInt();
new(&expected_pair[0].second) EmplaceInt();
new(&expected_pair[1].first) EmplaceInt(1);
new(&expected_pair[1].second) EmplaceInt();
new(&expected_pair[2].first) EmplaceInt(2);
new(&expected_pair[2].second) EmplaceInt(2);
new(&expected_pair[3].first) EmplaceInt(3);
new(&expected_pair[3].second) EmplaceInt(2, 3);
new(&expected_pair[4].first) EmplaceInt(4);
new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
new(&expected_pair[5].first) EmplaceInt(5);
new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
{
Container c;
typename Container::const_iterator it;
it = c.emplace_hint(c.begin());
if(!test_expected_container(c, &expected_pair[0], 1)){
std::cout << "Error after c.emplace(1);\n";
return false;
}
it = c.emplace_hint(it, 1);
if(!test_expected_container(c, &expected_pair[0], 2)){
std::cout << "Error after c.emplace(it, 1);\n";
return false;
}
it = c.emplace_hint(it, 2, 2);
if(!test_expected_container(c, &expected_pair[0], 3)){
std::cout << "Error after c.emplace(it, 2, 2);\n";
return false;
}
it = c.emplace_hint(it, 3, 2, 3);
if(!test_expected_container(c, &expected_pair[0], 4)){
std::cout << "Error after c.emplace(it, 3, 2, 3);\n";
return false;
}
it = c.emplace_hint(it, 4, 2, 3, 4);
if(!test_expected_container(c, &expected_pair[0], 5)){
std::cout << "Error after c.emplace(it, 4, 2, 3, 4);\n";
return false;
}
it = c.emplace_hint(it, 5, 2, 3, 4, 5);
if(!test_expected_container(c, &expected_pair[0], 6)){
std::cout << "Error after c.emplace(it, 5, 2, 3, 4, 5);\n";
return false;
}
}
return true;
}
template<class Container>
bool test_emplace_hint_pair(containers_detail::false_)
{ return true; }
template <EmplaceOptions O, EmplaceOptions Mask>
struct emplace_active
{
static const bool value = (0 != (O & Mask));
typedef containers_detail::bool_<value> type;
operator type() const{ return type(); }
};
template<class Container, EmplaceOptions O>
bool test_emplace()
{
// if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>()))
// return false;
if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>()))
return false;/*
if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>()))
return false;
if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>()))
return false;
if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>()))
return false;
if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>()))
return false;
if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>()))
return false;
if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>()))
return false;*/
return true;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP

View File

@@ -0,0 +1,193 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
#define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/version_type.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file
//!Describes an allocator to test expand capabilities
namespace boost {
namespace container {
namespace test {
//This allocator just allows two allocations. The first one will return
//mp_buffer + m_offset configured in the constructor. The second one
//will return mp_buffer.
template<class T>
class expand_bwd_test_allocator
{
private:
typedef expand_bwd_test_allocator<T> self_t;
typedef void * aux_pointer_t;
typedef const void * cvoid_ptr;
template<class T2>
expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
public:
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef typename containers_detail::add_reference
<value_type>::type reference;
typedef typename containers_detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef boost::container::containers_detail::version_type<expand_bwd_test_allocator, 2> version;
template<class T2>
struct rebind
{ typedef expand_bwd_test_allocator<T2> other; };
//!Constructor from the segment manager. Never throws
expand_bwd_test_allocator(T *buffer, size_type size, difference_type offset)
: mp_buffer(buffer), m_size(size)
, m_offset(offset), m_allocations(0){ }
//!Constructor from other expand_bwd_test_allocator. Never throws
expand_bwd_test_allocator(const expand_bwd_test_allocator &other)
: mp_buffer(other.mp_buffer), m_size(other.m_size)
, m_offset(other.m_offset), m_allocations(0){ }
//!Constructor from related expand_bwd_test_allocator. Never throws
template<class T2>
expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
: mp_buffer(other.mp_buffer), m_size(other.m_size)
, m_offset(other.m_offset), m_allocations(0){ }
pointer address(reference value)
{ return pointer(addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
pointer allocate(size_type , cvoid_ptr hint = 0)
{ (void)hint; return 0; }
void deallocate(const pointer &, size_type)
{}
template<class Convertible>
void construct(pointer ptr, const Convertible &value)
{ new((void*)ptr) value_type(value); }
void destroy(pointer ptr)
{ (*ptr).~value_type(); }
size_type max_size() const
{ return m_size; }
friend void swap(self_t &alloc1, self_t &alloc2)
{
containers_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
containers_detail::do_swap(alloc1.m_size, alloc2.m_size);
containers_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
}
//Experimental version 2 expand_bwd_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::container::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
(void)preferred_size; (void)reuse; (void)command;
//This allocator only expands backwards!
assert(m_allocations == 0 || (command & boost::container::expand_bwd));
received_size = limit_size;
if(m_allocations == 0){
if((m_offset + limit_size) > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer + m_offset, false);
}
else if(m_allocations == 1){
if(limit_size > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer, true);
}
else{
assert(0);
throw std::bad_alloc();
}
}
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
size_type size(const pointer &p) const
{ (void)p; return m_size; }
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate_one()
{ return this->allocate(1); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &p)
{ return this->deallocate(p, 1); }
pointer mp_buffer;
size_type m_size;
difference_type m_offset;
char m_allocations;
};
//!Equality test for same type of expand_bwd_test_allocator
template<class T> inline
bool operator==(const expand_bwd_test_allocator<T> &alloc1,
const expand_bwd_test_allocator<T> &alloc2)
{ return false; }
//!Inequality test for same type of expand_bwd_test_allocator
template<class T> inline
bool operator!=(const expand_bwd_test_allocator<T> &alloc1,
const expand_bwd_test_allocator<T> &alloc2)
{ return true; }
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP

View File

@@ -0,0 +1,269 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
#define BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <vector>
#include <typeinfo>
#include "expand_bwd_test_allocator.hpp"
#include <algorithm>
#include <boost/type_traits/remove_volatile.hpp>
namespace boost { namespace container { namespace test {
template<class T>
struct value_holder
{
value_holder(T val) : m_value(val){}
value_holder(): m_value(0){}
~value_holder(){ m_value = 0; }
bool operator == (const value_holder &other) const
{ return m_value == other.m_value; }
bool operator != (const value_holder &other) const
{ return m_value != other.m_value; }
T m_value;
};
template<class T>
struct triple_value_holder
{
triple_value_holder(T val)
: m_value1(val)
, m_value2(val)
, m_value3(val)
{}
triple_value_holder()
: m_value1(0)
, m_value2(0)
, m_value3(0)
{}
~triple_value_holder()
{ m_value1 = m_value2 = m_value3 = 0; }
bool operator == (const triple_value_holder &other) const
{
return m_value1 == other.m_value1
&& m_value2 == other.m_value2
&& m_value3 == other.m_value3;
}
bool operator != (const triple_value_holder &other) const
{
return m_value1 != other.m_value1
|| m_value2 != other.m_value2
|| m_value3 != other.m_value3;
}
T m_value1;
T m_value2;
T m_value3;
};
typedef value_holder<int> int_holder;
typedef triple_value_holder<int> triple_int_holder;
//Function to check if both sets are equal
template <class Vector1, class Vector2>
bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
{
if(vector1.size() != vector2.size())
return false;
return std::equal(vector1.begin(), vector1.end(), vector2.begin());
}
template<class Vector>
bool CheckUninitializedIsZero(const Vector & v)
{
typedef typename Vector::value_type value_type;
typename Vector::size_type sz = v.size();
typename Vector::size_type extra = v.capacity() - v.size();
value_type comp(0);
const value_type *holder = &v[0] + sz;
while(extra--){
if(*holder++ != comp)
return false;
}
return true;
}
//This function tests all the possible combinations when
//inserting data in a vector and expanding backwards
template<class VectorWithExpandBwdAllocator>
bool test_insert_with_expand_bwd()
{
typedef typename VectorWithExpandBwdAllocator::value_type value_type;
typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
typedef std::vector<non_volatile_value_type> Vect;
const int MemorySize = 1000;
//Distance old and new buffer
const int Offset[] =
{ 350, 250, 150, 150,
150, 50, 50, 50 };
//Insert position
const int Position[] =
{ 100, 100, 100, 100,
100, 100, 100, 100 };
//Initial vector size
const int InitialSize[] =
{ 200, 200, 200, 200,
200, 200, 200, 200 };
//Size of the data to insert
const int InsertSize[] =
{ 100, 100, 100, 200,
300, 25, 100, 200 };
//Number of tests
const int Iterations = sizeof(InsertSize)/sizeof(int);
for(int iteration = 0; iteration < Iterations; ++iteration)
{
value_type *memory = new value_type[MemorySize];
try {
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}
Vect data_to_insert;
data_to_insert.resize(InsertSize[iteration]);
for(int i = 0; i < InsertSize[iteration]; ++i){
data_to_insert[i] = -i;
}
expand_bwd_test_allocator<value_type> alloc
(&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
vector.insert( vector.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
initial_data.insert(initial_data.begin() + Position[iteration]
, data_to_insert.begin(), data_to_insert.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
}
}
catch(...){
delete [](const_cast<non_volatile_value_type*>(memory));
throw;
}
delete [](const_cast<non_volatile_value_type*>(memory));
}
return true;
}
//This function tests all the possible combinations when
//inserting data in a vector and expanding backwards
template<class VectorWithExpandBwdAllocator>
bool test_assign_with_expand_bwd()
{
typedef typename VectorWithExpandBwdAllocator::value_type value_type;
typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
typedef std::vector<non_volatile_value_type> Vect;
const int MemorySize = 200;
const int Offset[] = { 50, 50, 50};
const int InitialSize[] = { 25, 25, 25};
const int AssignSize[] = { 40, 60, 80};
const int Iterations = sizeof(AssignSize)/sizeof(int);
for(int iteration = 0; iteration <Iterations; ++iteration)
{
value_type *memory = new value_type[MemorySize];
try {
//Create initial data
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
initial_data[i] = i;
}
//Create data to assign
std::vector<non_volatile_value_type> data_to_assign;
data_to_assign.resize(AssignSize[iteration]);
for(int i = 0; i < AssignSize[iteration]; ++i){
data_to_assign[i] = -i;
}
//Insert initial data to the vector to test
expand_bwd_test_allocator<value_type> alloc
(&memory[0], MemorySize, Offset[iteration]);
VectorWithExpandBwdAllocator vector(alloc);
vector.insert( vector.begin()
, initial_data.begin(), initial_data.end());
//Assign data
vector.assign(data_to_assign.begin(), data_to_assign.end());
initial_data.assign(data_to_assign.begin(), data_to_assign.end());
//Now check that values are equal
if(!CheckEqualVector(vector, initial_data)){
std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
<< " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
<< " Iteration: " << iteration << std::endl;
return false;
}
}
catch(...){
delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
throw;
}
delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
}
return true;
}
//This function calls all tests
template<class VectorWithExpandBwdAllocator>
bool test_all_expand_bwd()
{
std::cout << "Starting test_insert_with_expand_bwd." << std::endl << " Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
if(!test_insert_with_expand_bwd<VectorWithExpandBwdAllocator>()){
std::cout << "test_allocation_direct_deallocation failed. Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
return false;
}
std::cout << "Starting test_assign_with_expand_bwd." << std::endl << " Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
if(!test_assign_with_expand_bwd<VectorWithExpandBwdAllocator>()){
std::cout << "test_allocation_direct_deallocation failed. Class: "
<< typeid(VectorWithExpandBwdAllocator).name() << std::endl;
return false;
}
return true;
}
}}} //namespace boost { namespace container { namespace test {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_TEST_ALLOCATION_TEST_TEMPLATE_HEADER

333
test/flat_tree_test.cpp Normal file
View File

@@ -0,0 +1,333 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <set>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
#include "print_container.hpp"
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Alias allocator type
typedef std::allocator<int> allocator_t;
typedef std::allocator<test::movable_int>
movable_allocator_t;
typedef std::allocator<std::pair<int, int> >
pair_allocator_t;
typedef std::allocator<std::pair<test::movable_int, test::movable_int> >
movable_pair_allocator_t;
typedef std::allocator<test::movable_and_copyable_int >
move_copy_allocator_t;
typedef std::allocator<std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
move_copy_pair_allocator_t;
typedef std::allocator<test::copyable_int >
copy_allocator_t;
typedef std::allocator<std::pair<test::copyable_int, test::copyable_int> >
copy_pair_allocator_t;
//Alias set types
typedef std::set<int> MyStdSet;
typedef std::multiset<int> MyStdMultiSet;
typedef std::map<int, int> MyStdMap;
typedef std::multimap<int, int> MyStdMultiMap;
typedef flat_set<int, std::less<int>, allocator_t> MyBoostSet;
typedef flat_multiset<int, std::less<int>, allocator_t> MyBoostMultiSet;
typedef flat_map<int, int, std::less<int>, pair_allocator_t> MyBoostMap;
typedef flat_multimap<int, int, std::less<int>, pair_allocator_t> MyBoostMultiMap;
typedef flat_set<test::movable_int, std::less<test::movable_int>
,movable_allocator_t> MyMovableBoostSet;
typedef flat_multiset<test::movable_int,std::less<test::movable_int>
,movable_allocator_t> MyMovableBoostMultiSet;
typedef flat_map<test::movable_int, test::movable_int
,std::less<test::movable_int>
,movable_pair_allocator_t> MyMovableBoostMap;
typedef flat_multimap<test::movable_int, test::movable_int
,std::less<test::movable_int>
,movable_pair_allocator_t> MyMovableBoostMultiMap;
typedef flat_set<test::movable_and_copyable_int, std::less<test::movable_and_copyable_int>
,move_copy_allocator_t> MyMoveCopyBoostSet;
typedef flat_multiset<test::movable_and_copyable_int,std::less<test::movable_and_copyable_int>
,move_copy_allocator_t> MyMoveCopyBoostMultiSet;
typedef flat_map<test::movable_and_copyable_int, test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>
,move_copy_pair_allocator_t> MyMoveCopyBoostMap;
typedef flat_multimap<test::movable_and_copyable_int, test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>
,move_copy_pair_allocator_t> MyMoveCopyBoostMultiMap;
typedef flat_set<test::copyable_int, std::less<test::copyable_int>
,copy_allocator_t> MyCopyBoostSet;
typedef flat_multiset<test::copyable_int,std::less<test::copyable_int>
,copy_allocator_t> MyCopyBoostMultiSet;
typedef flat_map<test::copyable_int, test::copyable_int
,std::less<test::copyable_int>
,copy_pair_allocator_t> MyCopyBoostMap;
typedef flat_multimap<test::copyable_int, test::copyable_int
,std::less<test::copyable_int>
,copy_pair_allocator_t> MyCopyBoostMultiMap;
//Test recursive structures
class recursive_flat_set
{
public:
recursive_flat_set(const recursive_flat_set &c)
: id_(c.id_), flat_set_(c.flat_set_)
{}
recursive_flat_set & operator =(const recursive_flat_set &c)
{
id_ = c.id_;
flat_set_= c.flat_set_;
return *this;
}
int id_;
flat_set<recursive_flat_set> flat_set_;
friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b)
{ return a.id_ < b.id_; }
};
class recursive_flat_map
{
public:
recursive_flat_map(const recursive_flat_map &c)
: id_(c.id_), map_(c.map_)
{}
recursive_flat_map & operator =(const recursive_flat_map &c)
{
id_ = c.id_;
map_= c.map_;
return *this;
}
int id_;
flat_map<recursive_flat_map, recursive_flat_map> map_;
friend bool operator< (const recursive_flat_map &a, const recursive_flat_map &b)
{ return a.id_ < b.id_; }
};
//Test recursive structures
class recursive_flat_multiset
{
public:
recursive_flat_multiset(const recursive_flat_multiset &c)
: id_(c.id_), flat_set_(c.flat_set_)
{}
recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
{
id_ = c.id_;
flat_set_= c.flat_set_;
return *this;
}
int id_;
flat_multiset<recursive_flat_multiset> flat_set_;
friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
{ return a.id_ < b.id_; }
};
class recursive_flat_multimap
{
public:
recursive_flat_multimap(const recursive_flat_multimap &c)
: id_(c.id_), map_(c.map_)
{}
recursive_flat_multimap & operator =(const recursive_flat_multimap &c)
{
id_ = c.id_;
map_= c.map_;
return *this;
}
int id_;
flat_map<recursive_flat_multimap, recursive_flat_multimap> map_;
friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b)
{ return a.id_ < b.id_; }
};
template<class C>
void test_move()
{
//Now test move semantics
C original;
C move_ctor(boost::move(original));
C move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
int main()
{
using namespace boost::container::test;
//Now test move semantics
{
test_move<flat_set<recursive_flat_set> >();
test_move<flat_multiset<recursive_flat_multiset> >();
test_move<flat_map<recursive_flat_map, recursive_flat_map> >();
test_move<flat_multimap<recursive_flat_multimap, recursive_flat_multimap> >();
}
if (0 != set_test<
MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test_copyable<
MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test<
MyMovableBoostSet
,MyStdSet
,MyMovableBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyMovableBoostSet>" << std::endl;
return 1;
}
if (0 != set_test<
MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyMoveCopyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test_copyable<
MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test<
MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyCopyBoostSet>" << std::endl;
return 1;
}
if (0 != set_test_copyable<
MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
std::cout << "Error in set_test<MyBoostSet>" << std::endl;
return 1;
}
if (0 != map_test<
MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test_copyable<
MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
// if (0 != map_test<
// MyMovableBoostMap
// ,MyStdMap
// ,MyMovableBoostMultiMap
// ,MyStdMultiMap>()){
// return 1;
// }
if (0 != map_test<
MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyMoveCopyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test_copyable<
MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test<
MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyCopyBoostMap>" << std::endl;
return 1;
}
if (0 != map_test_copyable<
MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
std::cout << "Error in set_test<MyBoostMap>" << std::endl;
return 1;
}
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
// if(!boost::container::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
// return 1;
if(!boost::container::test::test_emplace<flat_multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_set<test::EmplaceInt>, SetOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

159
test/heap_allocator_v1.hpp Normal file
View File

@@ -0,0 +1,159 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
#define BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/exceptions.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
//!\file
//!Describes an heap_allocator_v1 that allocates portions of fixed size
//!memory buffer (shared memory, mapped file...)
namespace boost {
namespace container {
namespace test {
//!An STL compatible heap_allocator_v1 that uses a segment manager as
//!memory source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/
template<class T, class SegmentManager>
class heap_allocator_v1
{
private:
typedef heap_allocator_v1<T, SegmentManager> self_t;
typedef SegmentManager segment_manager;
typedef typename segment_manager::void_pointer aux_pointer_t;
typedef typename
boost::pointer_to_other
<aux_pointer_t, const void>::type cvoid_ptr;
typedef typename boost::pointer_to_other
<cvoid_ptr, segment_manager>::type alloc_ptr_t;
template<class T2, class SegmentManager2>
heap_allocator_v1& operator=(const heap_allocator_v1<T2, SegmentManager2>&);
heap_allocator_v1& operator=(const heap_allocator_v1&);
alloc_ptr_t mp_mngr;
public:
typedef T value_type;
typedef typename boost::pointer_to_other
<cvoid_ptr, T>::type pointer;
typedef typename boost::
pointer_to_other<pointer, const T>::type const_pointer;
typedef typename detail::add_reference
<value_type>::type reference;
typedef typename detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
//!Obtains an heap_allocator_v1 of other type
template<class T2>
struct rebind
{
typedef heap_allocator_v1<T2, SegmentManager> other;
};
//!Returns the segment manager. Never throws
segment_manager* get_segment_manager()const
{ return detail::get_pointer(mp_mngr); }
/*
//!Returns address of mutable object. Never throws
pointer address(reference value) const
{ return pointer(addressof(value)); }
//!Returns address of non mutable object. Never throws
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
*/
//!Constructor from the segment manager. Never throws
heap_allocator_v1(segment_manager *segment_mngr)
: mp_mngr(segment_mngr) { }
//!Constructor from other heap_allocator_v1. Never throws
heap_allocator_v1(const heap_allocator_v1 &other)
: mp_mngr(other.get_segment_manager()){ }
//!Constructor from related heap_allocator_v1. Never throws
template<class T2>
heap_allocator_v1(const heap_allocator_v1<T2, SegmentManager> &other)
: mp_mngr(other.get_segment_manager()){}
//!Allocates memory for an array of count elements.
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_ptr hint = 0)
{ (void)hint; return ::new value_type[count]; }
//!Deallocates memory previously allocated. Never throws
void deallocate(const pointer &ptr, size_type)
{ return ::delete[] detail::get_pointer(ptr) ; }
//!Construct object, calling constructor.
//!Throws if T(const T&) throws
void construct(const pointer &ptr, const_reference value)
{ new((void*)detail::get_pointer(ptr)) value_type(value); }
//!Destroys object. Throws if object's destructor throws
void destroy(const pointer &ptr)
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
//!Returns the number of elements that could be allocated. Never throws
size_type max_size() const
{ return mp_mngr->get_size(); }
//!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
};
//!Equality test for same type of heap_allocator_v1
template<class T, class SegmentManager> inline
bool operator==(const heap_allocator_v1<T , SegmentManager> &alloc1,
const heap_allocator_v1<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
//!Inequality test for same type of heap_allocator_v1
template<class T, class SegmentManager> inline
bool operator!=(const heap_allocator_v1<T, SegmentManager> &alloc1,
const heap_allocator_v1<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP

78
test/list_test.cpp Normal file
View File

@@ -0,0 +1,78 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/list.hpp>
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "list_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::list<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
typedef list<int> MyList;
typedef list<test::movable_int> MyMoveList;
typedef list<test::movable_and_copyable_int> MyCopyMoveList;
typedef list<test::copyable_int> MyCopyList;
class recursive_list
{
public:
int id_;
list<recursive_list> list_;
recursive_list &operator=(const recursive_list &o)
{ list_ = o.list_; return *this; }
};
void recursive_list_test()//Test for recursive types
{
list<recursive_list> recursive, copy;
//Test to test both move emulations
if(!copy.size()){
copy = recursive;
}
}
int main ()
{
recursive_list_test();
{
//Now test move semantics
list<recursive_list> original;
list<recursive_list> move_ctor(boost::move(original));
list<recursive_list> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
if(test::list_test<MyList, true>())
return 1;
if(test::list_test<MyMoveList, true>())
return 1;
if(test::list_test<MyCopyMoveList, true>())
return 1;
if(test::list_test<MyCopyList, true>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace<list<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

312
test/list_test.hpp Normal file
View File

@@ -0,0 +1,312 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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/container for documentation.
//
////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_LIST_TEST_HEADER
#define BOOST_CONTAINER_TEST_LIST_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <memory>
#include <list>
#include <vector>
#include <functional>
#include "print_container.hpp"
#include <boost/move/move.hpp>
#include <string>
namespace boost{
namespace container {
namespace test{
template<class V1, class V2>
bool list_copyable_only(V1 *, V2 *, boost::container::containers_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool list_copyable_only(V1 *boostlist, V2 *stdlist, boost::container::containers_detail::true_type)
{
typedef typename V1::value_type IntType;
boostlist->insert(boostlist->end(), 50, IntType(1));
stdlist->insert(stdlist->end(), 50, 1);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
{
IntType move_me(1);
boostlist->insert(boostlist->begin(), 50, boost::move(move_me));
stdlist->insert(stdlist->begin(), 50, 1);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
{
IntType move_me(2);
boostlist->assign(boostlist->size()/2, boost::move(move_me));
stdlist->assign(stdlist->size()/2, 2);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
{
IntType move_me(3);
boostlist->assign(boostlist->size()*3-1, boost::move(move_me));
stdlist->assign(stdlist->size()*3-1, 3);
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
{
IntType copy_me(3);
const IntType ccopy_me(3);
boostlist->push_front(copy_me);
stdlist->push_front(int(3));
boostlist->push_front(ccopy_me);
stdlist->push_front(int(3));
if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
}
return true;
}
template<bool DoublyLinked>
struct list_push_data_function
{
template<class MyBoostList, class MyStdList>
static int execute(int max, MyBoostList *boostlist, MyStdList *stdlist)
{
typedef typename MyBoostList::value_type IntType;
for(int i = 0; i < max; ++i){
IntType move_me(i);
boostlist->push_back(boost::move(move_me));
stdlist->push_back(i);
boostlist->push_front(IntType(i));
stdlist->push_front(int(i));
}
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
return 0;
}
};
template<>
struct list_push_data_function<false>
{
template<class MyBoostList, class MyStdList>
static int execute(int max, MyBoostList *boostlist, MyStdList *stdlist)
{
typedef typename MyBoostList::value_type IntType;
for(int i = 0; i < max; ++i){
IntType move_me(i);
boostlist->push_front(boost::move(move_me));
stdlist->push_front(i);
boostlist->push_front(IntType(i));
stdlist->push_front(int(i));
}
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
return 0;
}
};
template<bool DoublyLinked>
struct list_pop_back_function
{
template<class MyStdList, class MyBoostList>
static int execute(MyBoostList *boostlist, MyStdList *stdlist)
{
boostlist->pop_back();
stdlist->pop_back();
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
return 0;
}
};
template<>
struct list_pop_back_function<false>
{
template<class MyStdList, class MyBoostList>
static int execute(MyBoostList *boostlist, MyStdList *stdlist)
{
(void)boostlist; (void)stdlist;
return 0;
}
};
template<class MyBoostList
,bool DoublyLinked>
int list_test (bool copied_allocators_equal = true)
{
typedef std::list<int> MyStdList;
typedef typename MyBoostList::value_type IntType;
const int max = 100;
typedef list_push_data_function<DoublyLinked> push_data_t;
try{
MyBoostList *boostlist = new MyBoostList;
MyStdList *stdlist = new MyStdList;
if(push_data_t::execute(max, boostlist, stdlist)){
return 1;
}
boostlist->erase(boostlist->begin()++);
stdlist->erase(stdlist->begin()++);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
if(list_pop_back_function<DoublyLinked>::execute(boostlist, stdlist)){
return 1;
}
boostlist->pop_front();
stdlist->pop_front();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostlist->assign(boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
}
if(copied_allocators_equal){
boostlist->sort();
stdlist->sort();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
}
boostlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
boostlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostlist->insert(boostlist->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
}
boostlist->unique();
stdlist->unique();
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
if(copied_allocators_equal){
boostlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
for(int i = 0; i < max; ++i){
IntType new_int(i);
boostlist->insert(boostlist->end(), boost::move(new_int));
stdlist->insert(stdlist->end(), i);
if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
}
if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
boostlist->resize(25);
stdlist->resize(25);
boostlist->resize(50);
stdlist->resize(50);
boostlist->resize(0);
stdlist->resize(0);
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
if(push_data_t::execute(max, boostlist, stdlist)){
return 1;
}
{
MyBoostList otherboostlist(boostlist->get_allocator());
MyStdList otherstdlist;
int listsize = (int)boostlist->size();
if(push_data_t::execute(listsize, boostlist, stdlist)){
return 1;
}
if(copied_allocators_equal){
boostlist->splice(boostlist->begin(), otherboostlist);
stdlist->splice(stdlist->begin(), otherstdlist);
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
listsize = (int)boostlist->size();
if(push_data_t::execute(listsize, boostlist, stdlist)){
return 1;
}
if(push_data_t::execute(listsize, &otherboostlist, &otherstdlist)){
return 1;
}
if(copied_allocators_equal){
boostlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
otherboostlist.sort(std::greater<IntType>());
otherstdlist.sort(std::greater<int>());
if(!CheckEqualContainers(&otherboostlist, &otherstdlist))
return 1;
boostlist->merge(otherboostlist, std::greater<IntType>());
stdlist->merge(otherstdlist, std::greater<int>());
if(!CheckEqualContainers(boostlist, stdlist))
return 1;
}
if(!list_copyable_only(boostlist, stdlist
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return 1;
}
}
delete boostlist;
delete stdlist;
}
catch(...){
throw;
}
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif

521
test/map_test.hpp Normal file
View File

@@ -0,0 +1,521 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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/container for documentation.
//
////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_MAP_TEST_HEADER
#define BOOST_CONTAINER_TEST_MAP_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <map>
#include <functional>
#include <utility>
#include "print_container.hpp"
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <string>
template<class T1, class T2, class T3, class T4>
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
{
return p1.first == p2.first && p1.second == p2.second;
}
namespace boost{
namespace container {
namespace test{
template<class MyBoostMap
,class MyStdMap
,class MyBoostMultiMap
,class MyStdMultiMap>
int map_test ()
{
typedef typename MyBoostMap::key_type IntType;
typedef containers_detail::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
try{
MyBoostMap *boostmap = new MyBoostMap;
MyStdMap *stdmap = new MyStdMap;
MyBoostMultiMap *boostmultimap = new MyBoostMultiMap;
MyStdMultiMap *stdmultimap = new MyStdMultiMap;
//Test construction from a range
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType i1(i/2);
IntType i2(i/2);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
typedef typename MyStdMap::value_type StdValueType;
typedef typename MyStdMap::key_type StdKeyType;
typedef typename MyStdMap::mapped_type StdMappedType;
StdValueType aux_vect2[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect2[i])StdValueType(StdKeyType(i/2), StdMappedType(i/2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType i1(i/2);
IntType i2(i/2);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
MyBoostMap *boostmap2 = new MyBoostMap
( boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdMap *stdmap2 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyBoostMultiMap *boostmultimap2 = new MyBoostMultiMap
( boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiMap *stdmultimap2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostmap2, stdmap2)) return 1;
if(!CheckEqualContainers(boostmultimap2, stdmultimap2)) return 1;
//ordered range insertion
//This is really nasty, but we have no other simple choice
for(int i = 0; i < 50; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
for(int i = 0; i < 50; ++i){
new(&aux_vect2[i])StdValueType(StdKeyType(i), StdMappedType(i));
}
for(int i = 0; i < 50; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
/*
MyBoostMap *boostmap3 = new MyBoostMap
( ordered_unique_range
, boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdMap *stdmap3 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyBoostMultiMap *boostmultimap3 = new MyBoostMultiMap
( ordered_range
, boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiMap *stdmultimap3 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostmap3, stdmap3)){
std::cout << "Error in construct<MyBoostMap>(MyBoostMap3)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultimap3, stdmultimap3)){
std::cout << "Error in construct<MyBoostMultiMap>(MyBoostMultiMap3)" << std::endl;
return 1;
}
*/
delete boostmap2;
delete boostmultimap2;
delete stdmap2;
delete stdmultimap2;
//delete boostmap3;
//delete boostmultimap3;
//delete stdmap3;
//delete stdmultimap3;
}
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
for(int i = 0; i < max; ++i){
boostmap->insert(boost::move(aux_vect[i]));
stdmap->insert(StdPairType(i, i));
boostmultimap->insert(boost::move(aux_vect3[i]));
stdmultimap->insert(StdPairType(i, i));
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
typename MyBoostMap::iterator it;
typename MyBoostMap::const_iterator cit = it;
boostmap->erase(boostmap->begin()++);
stdmap->erase(stdmap->begin()++);
boostmultimap->erase(boostmultimap->begin()++);
stdmultimap->erase(stdmultimap->begin()++);
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
boostmap->erase(boostmap->begin());
stdmap->erase(stdmap->begin());
boostmultimap->erase(boostmultimap->begin());
stdmultimap->erase(stdmultimap->begin());
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
//Swapping test
MyBoostMap tmpboostemap2;
MyStdMap tmpstdmap2;
MyBoostMultiMap tmpboostemultimap2;
MyStdMultiMap tmpstdmultimap2;
boostmap->swap(tmpboostemap2);
stdmap->swap(tmpstdmap2);
boostmultimap->swap(tmpboostemultimap2);
stdmultimap->swap(tmpstdmultimap2);
boostmap->swap(tmpboostemap2);
stdmap->swap(tmpstdmap2);
boostmultimap->swap(tmpboostemultimap2);
stdmultimap->swap(tmpstdmultimap2);
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
}
//Insertion from other container
//Initialize values
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
boostmultimap->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
for(std::size_t i = 0; i != 50; ++i){
StdPairType stdpairtype(-1, -1);
stdmap->insert(stdpairtype);
stdmultimap->insert(stdpairtype);
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
for(int i = 0, j = static_cast<int>(boostmap->size()); i < j; ++i){
boostmap->erase(IntType(i));
stdmap->erase(i);
boostmultimap->erase(IntType(i));
stdmultimap->erase(i);
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
}
{
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect4[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType i1(-1);
IntType i2(-1);
new(&aux_vect5[i])IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
boostmap->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
boostmultimap->insert(boost::make_move_iterator(&aux_vect4[0]), boost::make_move_iterator(aux_vect4 + 50));
boostmultimap->insert(boost::make_move_iterator(&aux_vect5[0]), boost::make_move_iterator(aux_vect5 + 50));
for(std::size_t i = 0; i != 50; ++i){
StdPairType stdpairtype(-1, -1);
stdmap->insert(stdpairtype);
stdmultimap->insert(stdpairtype);
stdmap->insert(stdpairtype);
stdmultimap->insert(stdpairtype);
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
boostmap->erase(boostmap->begin()->first);
stdmap->erase(stdmap->begin()->first);
boostmultimap->erase(boostmultimap->begin()->first);
stdmultimap->erase(stdmultimap->begin()->first);
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
}
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
}
IntPairType aux_vect3[max];
for(int i = 0; i < max; ++i){
IntType i1(i);
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
for(int i = 0; i < max; ++i){
boostmap->insert(boost::move(aux_vect[i]));
stdmap->insert(StdPairType(i, i));
boostmultimap->insert(boost::move(aux_vect3[i]));
stdmultimap->insert(StdPairType(i, i));
}
if(!CheckEqualPairContainers(boostmap, stdmap)) return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) return 1;
for(int i = 0; i < max; ++i){
IntPairType intpair;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boostmap->begin(), boost::move(intpair));
stdmap->insert(stdmap->begin(), StdPairType(i, i));
//PrintContainers(boostmap, stdmap);
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmultimap->insert(boostmultimap->begin(), boost::move(intpair));
stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i));
//PrintContainers(boostmultimap, stdmultimap);
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boostmap->end(), boost::move(intpair));
stdmap->insert(stdmap->end(), StdPairType(i, i));
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmultimap->insert(boostmultimap->end(), boost::move(intpair));
stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boostmap->lower_bound(IntType(i)), boost::move(intpair));
stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
//PrintContainers(boostmap, stdmap);
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
{
IntType i1(i);
boostmultimap->insert(boostmultimap->lower_bound(boost::move(i1)), boost::move(intpair));
stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
}
//PrintContainers(boostmultimap, stdmultimap);
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
{
IntType i1(i);
boostmap->insert(boostmap->upper_bound(boost::move(i1)), boost::move(intpair));
stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
}
//PrintContainers(boostmap, stdmap);
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
{
IntType i1(i);
boostmultimap->insert(boostmultimap->upper_bound(boost::move(i1)), boost::move(intpair));
stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
}
//PrintContainers(boostmultimap, stdmultimap);
if(!CheckEqualPairContainers(boostmap, stdmap))
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
}
//Compare count with std containers
for(int i = 0; i < max; ++i){
if(boostmap->count(IntType(i)) != stdmap->count(i)){
return -1;
}
if(boostmultimap->count(IntType(i)) != stdmultimap->count(i)){
return -1;
}
}
//Now do count exercise
boostmap->erase(boostmap->begin(), boostmap->end());
boostmultimap->erase(boostmultimap->begin(), boostmultimap->end());
boostmap->clear();
boostmultimap->clear();
for(int j = 0; j < 3; ++j)
for(int i = 0; i < 100; ++i){
IntPairType intpair;
{
IntType i1(i), i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmap->insert(boost::move(intpair));
{
IntType i1(i), i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
}
boostmultimap->insert(boost::move(intpair));
if(boostmap->count(IntType(i)) != typename MyBoostMultiMap::size_type(1))
return 1;
if(boostmultimap->count(IntType(i)) != typename MyBoostMultiMap::size_type(j+1))
return 1;
}
}
delete boostmap;
delete stdmap;
delete boostmultimap;
delete stdmultimap;
}
catch(...){
throw;
}
return 0;
}
template<class MyBoostMap
,class MyStdMap
,class MyBoostMultiMap
,class MyStdMultiMap>
int map_test_copyable ()
{
typedef typename MyBoostMap::key_type IntType;
typedef containers_detail::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
try{
MyBoostMap *boostmap = new MyBoostMap;
MyStdMap *stdmap = new MyStdMap;
MyBoostMultiMap *boostmultimap = new MyBoostMultiMap;
MyStdMultiMap *stdmultimap = new MyStdMultiMap;
int i;
for(i = 0; i < max; ++i){
{
IntType i1(i), i2(i);
IntPairType intpair1(boost::move(i1), boost::move(i2));
boostmap->insert(boost::move(intpair1));
stdmap->insert(StdPairType(i, i));
}
{
IntType i1(i), i2(i);
IntPairType intpair2(boost::move(i1), boost::move(i2));
boostmultimap->insert(boost::move(intpair2));
stdmultimap->insert(StdPairType(i, i));
}
}
if(!CheckEqualContainers(boostmap, stdmap)) return 1;
if(!CheckEqualContainers(boostmultimap, stdmultimap)) return 1;
{
//Now, test copy constructor
MyBoostMap boostmapcopy(*boostmap);
MyStdMap stdmapcopy(*stdmap);
MyBoostMultiMap boostmmapcopy(*boostmultimap);
MyStdMultiMap stdmmapcopy(*stdmultimap);
if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy))
return 1;
//And now assignment
boostmapcopy = *boostmap;
stdmapcopy = *stdmap;
boostmmapcopy = *boostmultimap;
stdmmapcopy = *stdmultimap;
if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy))
return 1;
delete boostmap;
delete boostmultimap;
delete stdmap;
delete stdmultimap;
}
}
catch(...){
throw;
}
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_MAP_TEST_HEADER

230
test/movable_int.hpp Normal file
View File

@@ -0,0 +1,230 @@
///////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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/container for documentation.
//
///////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER
#define BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp>
namespace boost {
namespace container {
namespace test {
template<class T>
struct is_copyable;
template<>
struct is_copyable<int>
{
static const bool value = true;
};
class movable_int
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int)
public:
movable_int()
: m_int(0)
{}
explicit movable_int(int a)
: m_int(a)
{}
movable_int(BOOST_RV_REF(movable_int) mmi)
: m_int(mmi.m_int)
{ mmi.m_int = 0; }
movable_int & operator= (BOOST_RV_REF(movable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
movable_int & operator= (int i)
{ this->m_int = i; return *this; }
bool operator ==(const movable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const movable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const movable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const movable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const movable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const movable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, movable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<movable_int>
{
static const bool value = false;
};
class movable_and_copyable_int
{
BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
public:
movable_and_copyable_int()
: m_int(0)
{}
explicit movable_and_copyable_int(int a)
: m_int(a)
{}
movable_and_copyable_int(const movable_and_copyable_int& mmi)
: m_int(mmi.m_int)
{}
movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi)
: m_int(mmi.m_int)
{ mmi.m_int = 0; }
movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi)
{ this->m_int = mi.m_int; return *this; }
movable_and_copyable_int & operator= (BOOST_RV_REF(movable_and_copyable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
movable_and_copyable_int & operator= (int i)
{ this->m_int = i; return *this; }
bool operator ==(const movable_and_copyable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const movable_and_copyable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const movable_and_copyable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const movable_and_copyable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const movable_and_copyable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const movable_and_copyable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<movable_and_copyable_int>
{
static const bool value = true;
};
class copyable_int
{
public:
copyable_int()
: m_int(0)
{}
explicit copyable_int(int a)
: m_int(a)
{}
copyable_int(const copyable_int& mmi)
: m_int(mmi.m_int)
{}
copyable_int & operator= (int i)
{ this->m_int = i; return *this; }
bool operator ==(const copyable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const copyable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const copyable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const copyable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const copyable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const copyable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, copyable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<copyable_int>
{
static const bool value = true;
};
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_MOVABLE_INT_HEADER

64
test/print_container.hpp Normal file
View File

@@ -0,0 +1,64 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_PRINTCONTAINER_HPP
#define BOOST_PRINTCONTAINER_HPP
#include <boost/container/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
namespace boost{
namespace container {
namespace test{
struct PrintValues : public std::unary_function<int, void>
{
void operator() (int value) const
{
std::cout << value << " ";
}
};
template<class Container>
void PrintContents(const Container &cont, const char *contName)
{
std::cout<< "Printing contents of " << contName << std::endl;
std::for_each(cont.begin(), cont.end(), PrintValues());
std::cout<< std::endl << std::endl;
}
//Function to dump data
template<class MyBoostCont
,class MyStdCont>
void PrintContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
{
typename MyBoostCont::iterator itboost = boostcont->begin(), itboostend = boostcont->end();
typename MyStdCont::iterator itstd = stdcont->begin(), itstdend = stdcont->end();
std::cout << "MyBoostCont" << std::endl;
for(; itboost != itboostend; ++itboost){
std::cout << *itboost << std::endl;
}
std::cout << "MyStdCont" << std::endl;
for(; itstd != itstdend; ++itstd){
std::cout << *itstd << std::endl;
}
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_PRINTCONTAINER_HPP

504
test/set_test.hpp Normal file
View File

@@ -0,0 +1,504 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_SET_TEST_HEADER
#define BOOST_CONTAINER_TEST_SET_TEST_HEADER
#include <boost/container/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <memory>
#include <set>
#include <functional>
#include "print_container.hpp"
#include <boost/move/move.hpp>
#include <string>
namespace boost{
namespace container {
namespace test{
template<class MyBoostSet
,class MyStdSet
,class MyBoostMultiSet
,class MyStdMultiSet>
int set_test ()
{
typedef typename MyBoostSet::value_type IntType;
const int max = 100;
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyBoostSet *boostset = new MyBoostSet;
MyStdSet *stdset = new MyStdSet;
MyBoostMultiSet *boostmultiset = new MyBoostMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
//Test construction from a range
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i/2;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect3[i] = boost::move(move_me);
}
MyBoostSet *boostset2 = new MyBoostSet
( boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyBoostMultiSet *boostmultiset2 = new MyBoostMultiSet
( boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset2, stdset2)){
std::cout << "Error in construct<MyBoostSet>(MyBoostSet2)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset2, stdmultiset2)){
std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet2)" << std::endl;
return 1;
}
//ordered range insertion
for(int i = 0; i < 50; ++i){
IntType move_me(i);
aux_vect[i] = boost::move(move_me);
}
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i;
}
for(int i = 0; i < 50; ++i){
IntType move_me(i);
aux_vect3[i] = boost::move(move_me);
}
/*
MyBoostSet *boostset3 = MyBoostSet
( ordered_unique_range
, boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyBoostMultiSet *boostmultiset3 = MyBoostMultiSet
( ordered_range
, boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
MyStdMultiSet *stdmultiset3 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset3, stdset3)){
std::cout << "Error in construct<MyBoostSet>(MyBoostSet3)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset3, stdmultiset3)){
std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
return 1;
}
*/
delete boostset2;
delete boostmultiset2;
delete stdset2;
delete stdmultiset2;
//delete boostset3;
//delete boostmultiset3;
//delete stdset3;
//delete stdmultiset3;
}
int i, j;
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
boostset->insert(IntType(i));
stdset->insert(i);
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
boostmultiset->insert(IntType(i));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::move(move_me)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::move(move_me)" << std::endl;
return 1;
}
typename MyBoostSet::iterator it;
typename MyBoostSet::const_iterator cit = it;
boostset->erase(boostset->begin()++);
stdset->erase(stdset->begin()++);
boostmultiset->erase(boostmultiset->begin()++);
stdmultiset->erase(stdmultiset->begin()++);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(boostset->begin()++)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(boostmultiset->begin()++)" << std::endl;
return 1;
}
boostset->erase(boostset->begin());
stdset->erase(stdset->begin());
boostmultiset->erase(boostmultiset->begin());
stdmultiset->erase(stdmultiset->begin());
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(boostset->begin())" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(boostmultiset->begin())" << std::endl;
return 1;
}
//Swapping test
MyBoostSet tmpboosteset2;
MyStdSet tmpstdset2;
MyBoostMultiSet tmpboostemultiset2;
MyStdMultiSet tmpstdmultiset2;
boostset->swap(tmpboosteset2);
stdset->swap(tmpstdset2);
boostmultiset->swap(tmpboostemultiset2);
stdmultiset->swap(tmpstdmultiset2);
boostset->swap(tmpboosteset2);
stdset->swap(tmpstdset2);
boostmultiset->swap(tmpboostemultiset2);
stdmultiset->swap(tmpstdmultiset2);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->swap(tmpboosteset2)" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->swap(tmpboostemultiset2)" << std::endl;
return 1;
}
//Insertion from other container
//Initialize values
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = boost::move(move_me);
}
boostset->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
boostmultiset->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::make_move_iterator(&aux_vect[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
return 1;
}
for(int i = 0, j = static_cast<int>(boostset->size()); i < j; ++i){
IntType erase_me(i);
boostset->erase(erase_me);
stdset->erase(i);
boostmultiset->erase(erase_me);
stdmultiset->erase(i);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(erase_me)" << boostset->size() << " " << stdset->size() << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(erase_me)" << std::endl;
return 1;
}
}
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = boost::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = boost::move(move_me);
}
IntType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect4[i] = boost::move(move_me);
}
IntType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect5[i] = boost::move(move_me);
}
boostset->insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(aux_vect + 50));
boostset->insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
stdset->insert(aux_vect2, aux_vect2 + 50);
boostmultiset->insert(boost::make_move_iterator(&aux_vect4[0]), boost::make_move_iterator(aux_vect4 + 50));
boostmultiset->insert(boost::make_move_iterator(&aux_vect5[0]), boost::make_move_iterator(aux_vect5 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
return 1;
}
boostset->erase(*boostset->begin());
stdset->erase(*stdset->begin());
boostmultiset->erase(*boostmultiset->begin());
stdmultiset->erase(*stdmultiset->begin());
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->erase(*boostset->begin())" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->erase(*boostmultiset->begin())" << std::endl;
return 1;
}
}
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boost::move(move_me)) try 2" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boost::move(move_me2)) try 2" << std::endl;
return 1;
}
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boostset->begin(), boost::move(move_me));
stdset->insert(stdset->begin(), i);
//PrintContainers(boostset, stdset);
IntType move_me2(i);
boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//PrintContainers(boostmultiset, stdmultiset);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->begin(), boost::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2))" << std::endl;
return 1;
}
IntType move_me3(i);
boostset->insert(boostset->end(), boost::move(move_me3));
stdset->insert(stdset->end(), i);
IntType move_me4(i);
boostmultiset->insert(boostmultiset->end(), boost::move(move_me4));
stdmultiset->insert(stdmultiset->end(), i);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->end(), boost::move(move_me3))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->end(), boost::move(move_me4))" << std::endl;
return 1;
}
{
IntType move_me(i);
boostset->insert(boostset->upper_bound(move_me), boost::move(move_me));
stdset->insert(stdset->upper_bound(i), i);
//PrintContainers(boostset, stdset);
IntType move_me2(i);
boostmultiset->insert(boostmultiset->upper_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->upper_bound(i), i);
//PrintContainers(boostmultiset, stdmultiset);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->upper_bound(move_me), boost::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->upper_bound(move_me2), boost::move(move_me2))" << std::endl;
return 1;
}
}
{
IntType move_me(i);
boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(boostset, stdset);
IntType move_me2(i);
boostmultiset->insert(boostmultiset->lower_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(boostmultiset, stdmultiset);
if(!CheckEqualContainers(boostset, stdset)){
std::cout << "Error in boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2))" << std::endl;
return 1;
}
if(!CheckEqualContainers(boostmultiset, stdmultiset)){
std::cout << "Error in boostmultiset->insert(boostmultiset->lower_bound(move_me2), boost::move(move_me2))" << std::endl;
return 1;
}
}
}
//Compare count with std containers
for(i = 0; i < max; ++i){
IntType count_me(i);
if(boostset->count(count_me) != stdset->count(i)){
return -1;
}
if(boostmultiset->count(count_me) != stdmultiset->count(i)){
return -1;
}
}
//Now do count exercise
boostset->erase(boostset->begin(), boostset->end());
boostmultiset->erase(boostmultiset->begin(), boostmultiset->end());
boostset->clear();
boostmultiset->clear();
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
IntType count_me(i);
if(boostset->count(count_me) != typename MyBoostMultiSet::size_type(1)){
std::cout << "Error in boostset->count(count_me)" << std::endl;
return 1;
}
if(boostmultiset->count(count_me) != typename MyBoostMultiSet::size_type(j+1)){
std::cout << "Error in boostmultiset->count(count_me)" << std::endl;
return 1;
}
}
delete boostset;
delete stdset;
delete boostmultiset;
delete stdmultiset;
return 0;
}
template<class MyBoostSet
,class MyStdSet
,class MyBoostMultiSet
,class MyStdMultiSet>
int set_test_copyable ()
{
typedef typename MyBoostSet::value_type IntType;
const int max = 100;
try{
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyBoostSet *boostset = new MyBoostSet;
MyStdSet *stdset = new MyStdSet;
MyBoostMultiSet *boostmultiset = new MyBoostMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
int i;
for(i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
IntType move_me2(i);
boostmultiset->insert(boost::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(boostset, stdset)) return 1;
if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
{
//Now, test copy constructor
MyBoostSet boostsetcopy(*boostset);
MyStdSet stdsetcopy(*stdset);
if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy))
return 1;
MyBoostMultiSet boostmsetcopy(*boostmultiset);
MyStdMultiSet stdmsetcopy(*stdmultiset);
if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy))
return 1;
//And now assignment
boostsetcopy = *boostset;
stdsetcopy = *stdset;
if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy))
return 1;
boostmsetcopy = *boostmultiset;
stdmsetcopy = *stdmultiset;
if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy))
return 1;
}
delete boostset;
delete boostmultiset;
}
catch(...){
throw;
}
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif

82
test/slist_test.cpp Normal file
View File

@@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/slist.hpp>
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "list_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::slist<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
typedef slist<int> MyList;
typedef slist<test::movable_int> MyMoveList;
typedef slist<test::movable_and_copyable_int> MyCopyMoveList;
typedef slist<test::copyable_int> MyCopyList;
class recursive_slist
{
public:
int id_;
slist<recursive_slist> slist_;
recursive_slist &operator=(const recursive_slist &o)
{ slist_ = o.slist_; return *this; }
};
void recursive_slist_test()//Test for recursive types
{
slist<recursive_slist> recursive_list_list;
}
int main ()
{
recursive_slist_test();
{
//Now test move semantics
slist<recursive_slist> original;
slist<recursive_slist> move_ctor(boost::move(original));
slist<recursive_slist> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
{
slist<recursive_slist> recursive, copy;
//Test to test both move emulations
if(!copy.size()){
copy = recursive;
}
}
}
if(test::list_test<MyList, false>())
return 1;
if(test::list_test<MyMoveList, false>())
return 1;
if(test::list_test<MyCopyMoveList, false>())
return 1;
if(test::list_test<MyCopyList, false>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)
(test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE | test::EMPLACE_AFTER);
if(!boost::container::test::test_emplace
< slist<test::EmplaceInt>, Options>())
return 1;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,86 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/container/stable_vector.hpp>
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include "vector_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
//template class stable_vector<test::movable_and_copyable_int,
//test::dummy_test_allocator<test::movable_and_copyable_int> >;
class recursive_vector
{
public:
int id_;
stable_vector<recursive_vector> vector_;
recursive_vector &operator=(const recursive_vector &o)
{ vector_ = o.vector_; return *this; }
};
void recursive_vector_test()//Test for recursive types
{
stable_vector<recursive_vector> recursive, copy;
//Test to test both move emulations
if(!copy.size()){
copy = recursive;
}
}
int main()
{
recursive_vector_test();
{
//Now test move semantics
stable_vector<recursive_vector> original;
stable_vector<recursive_vector> move_ctor(boost::move(original));
stable_vector<recursive_vector> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
typedef stable_vector<int> MyVector;
typedef stable_vector<test::movable_int> MyMoveVector;
typedef stable_vector<test::movable_and_copyable_int> MyCopyMoveVector;
typedef stable_vector<test::copyable_int> MyCopyVector;
if(test::vector_test<MyVector>())
return 1;
if(test::vector_test<MyMoveVector>())
return 1;
if(test::vector_test<MyCopyMoveVector>())
return 1;
if(test::vector_test<MyCopyVector>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace
< stable_vector<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

293
test/string_test.cpp Normal file
View File

@@ -0,0 +1,293 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/string.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstddef>
#include <new>
#include "dummy_test_allocator.hpp"
#include "check_equal_containers.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
using namespace boost::container;
typedef test::dummy_test_allocator<char> DummyCharAllocator;
typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString;
typedef test::dummy_test_allocator<DummyString> DummyStringAllocator;
typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator;
typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString;
typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator;
//Explicit instantiations of container::basic_string
template class basic_string<char, std::char_traits<char>, DummyCharAllocator>;
template class basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator>;
//Explicit instantiation of container::vectors of container::strings
template class vector<DummyString, DummyStringAllocator>;
template class vector<DummyWString, DummyWStringAllocator>;
struct StringEqual
{
template<class Str1, class Str2>
bool operator ()(const Str1 &string1, const Str2 &string2) const
{
if(string1.size() != string2.size())
return false;
return std::char_traits<typename Str1::value_type>::compare
(string1.c_str(), string2.c_str(), string1.size()) == 0;
}
};
//Function to check if both lists are equal
template<class StrVector1, class StrVector2>
bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
{
StringEqual comp;
return std::equal(strvect1->begin(), strvect1->end(),
strvect2->begin(), comp);
}
template<class CharType>
int string_test()
{
typedef std::string StdString;
typedef vector<StdString> StdStringVector;
typedef basic_string<CharType> BoostString;
typedef vector<BoostString> BoostStringVector;
const int MaxSize = 100;
//Create shared memory
{
BoostStringVector *boostStringVect = new BoostStringVector;
StdStringVector *stdStringVect = new StdStringVector;
BoostString auxBoostString;
StdString auxStdString(StdString(auxBoostString.begin(), auxBoostString.end() ));
CharType buffer [20];
//First, push back
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->push_back(auxBoostString);
stdStringVect->push_back(auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//Now push back moving
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->push_back(boost::move(auxBoostString));
stdStringVect->push_back(auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//push front
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->insert(boostStringVect->begin(), auxBoostString);
stdStringVect->insert(stdStringVect->begin(), auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//Now push front moving
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->insert(boostStringVect->begin(), boost::move(auxBoostString));
stdStringVect->insert(stdStringVect->begin(), auxStdString);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1;
}
//Now test long and short representation swapping
//Short first
auxBoostString = "String";
auxStdString = "String";
BoostString boost_swapper;
StdString std_swapper;
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
if(!StringEqual()(boost_swapper, std_swapper))
return 1;
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
if(!StringEqual()(boost_swapper, std_swapper))
return 1;
//Shrink_to_fit
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
//Reserve + shrink_to_fit
auxBoostString.reserve(boost_swapper.size()*2+1);
auxStdString.reserve(std_swapper.size()*2+1);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
//Long string
auxBoostString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
boost_swapper = BoostString();
std_swapper = StdString();
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
if(!StringEqual()(boost_swapper, std_swapper))
return 1;
boost_swapper.swap(auxBoostString);
std_swapper.swap(auxStdString);
//Shrink_to_fit
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
auxBoostString.clear();
auxStdString.clear();
auxBoostString.shrink_to_fit();
StdString(auxStdString).swap(auxStdString);
if(!StringEqual()(auxBoostString, auxStdString))
return 1;
//No sort
std::sort(boostStringVect->begin(), boostStringVect->end());
std::sort(stdStringVect->begin(), stdStringVect->end());
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
const CharType prefix [] = "Prefix";
const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1;
const CharType sufix [] = "Suffix";
for(int i = 0; i < MaxSize; ++i){
(*boostStringVect)[i].append(sufix);
(*stdStringVect)[i].append(sufix);
(*boostStringVect)[i].insert((*boostStringVect)[i].begin(),
prefix, prefix + prefix_size);
(*stdStringVect)[i].insert((*stdStringVect)[i].begin(),
prefix, prefix + prefix_size);
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end());
std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end());
std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
std::sort(boostStringVect->begin(), boostStringVect->end());
std::sort(stdStringVect->begin(), stdStringVect->end());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
for(int i = 0; i < MaxSize; ++i){
(*boostStringVect)[i].replace((*boostStringVect)[i].begin(),
(*boostStringVect)[i].end(),
"String");
(*stdStringVect)[i].replace((*stdStringVect)[i].begin(),
(*stdStringVect)[i].end(),
"String");
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
boostStringVect->erase(std::unique(boostStringVect->begin(), boostStringVect->end()),
boostStringVect->end());
stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()),
stdStringVect->end());
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
//When done, delete vector
delete boostStringVect;
delete stdStringVect;
}
return 0;
}
bool test_expand_bwd()
{
//Now test all back insertion possibilities
typedef test::expand_bwd_test_allocator<char>
allocator_type;
typedef basic_string<char, std::char_traits<char>, allocator_type>
string_type;
return test::test_all_expand_bwd<string_type>();
}
int main()
{
if(string_test<char>()){
return 1;
}
if(!test_expand_bwd())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

233
test/tree_test.cpp Normal file
View File

@@ -0,0 +1,233 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <set>
#include <boost/container/set.hpp>
#include <boost/container/map.hpp>
#include "print_container.hpp"
#include "movable_int.hpp"
#include "dummy_test_allocator.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
//Alias standard types
typedef std::set<int> MyStdSet;
typedef std::multiset<int> MyStdMultiSet;
typedef std::map<int, int> MyStdMap;
typedef std::multimap<int, int> MyStdMultiMap;
//Alias non-movable types
typedef set<int> MyBoostSet;
typedef multiset<int> MyBoostMultiSet;
typedef map<int, int> MyBoostMap;
typedef multimap<int, int> MyBoostMultiMap;
//Alias movable types
typedef set<test::movable_int> MyMovableBoostSet;
typedef multiset<test::movable_int> MyMovableBoostMultiSet;
typedef map<test::movable_int, test::movable_int> MyMovableBoostMap;
typedef multimap<test::movable_int, test::movable_int> MyMovableBoostMultiMap;
typedef set<test::movable_and_copyable_int> MyMoveCopyBoostSet;
typedef set<test::copyable_int> MyCopyBoostSet;
typedef multiset<test::movable_and_copyable_int> MyMoveCopyBoostMultiSet;
typedef multiset<test::copyable_int> MyCopyBoostMultiSet;
typedef map<test::movable_and_copyable_int
,test::movable_and_copyable_int> MyMoveCopyBoostMap;
typedef multimap<test::movable_and_copyable_int
,test::movable_and_copyable_int> MyMoveCopyBoostMultiMap;
typedef map<test::copyable_int
,test::copyable_int> MyCopyBoostMap;
typedef multimap<test::copyable_int
,test::copyable_int> MyCopyBoostMultiMap;
//Test recursive structures
class recursive_set
{
public:
int id_;
set<recursive_set> set_;
friend bool operator< (const recursive_set &a, const recursive_set &b)
{ return a.id_ < b.id_; }
};
class recursive_map
{
public:
int id_;
map<recursive_map, recursive_map> map_;
friend bool operator< (const recursive_map &a, const recursive_map &b)
{ return a.id_ < b.id_; }
};
//Test recursive structures
class recursive_multiset
{
public:
int id_;
multiset<recursive_multiset> multiset_;
friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
{ return a.id_ < b.id_; }
};
class recursive_multimap
{
public:
int id_;
multimap<recursive_multimap, recursive_multimap> multimap_;
friend bool operator< (const recursive_multimap &a, const recursive_multimap &b)
{ return a.id_ < b.id_; }
};
template<class C>
void test_move()
{
//Now test move semantics
C original;
C move_ctor(boost::move(original));
C move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
int main ()
{
//Recursive container instantiation
{
set<recursive_set> set_;
multiset<recursive_multiset> multiset_;
map<recursive_map, recursive_map> map_;
multimap<recursive_multimap, recursive_multimap> multimap_;
}
//Now test move semantics
{
test_move<set<recursive_set> >();
test_move<multiset<recursive_multiset> >();
test_move<map<recursive_map, recursive_map> >();
test_move<multimap<recursive_multimap, recursive_multimap> >();
}
//using namespace boost::container::detail;
if(0 != test::set_test<MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test_copyable<MyBoostSet
,MyStdSet
,MyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test<MyMovableBoostSet
,MyStdSet
,MyMovableBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test<MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test_copyable<MyMoveCopyBoostSet
,MyStdSet
,MyMoveCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test<MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if(0 != test::set_test_copyable<MyCopyBoostSet
,MyStdSet
,MyCopyBoostMultiSet
,MyStdMultiSet>()){
return 1;
}
if (0 != test::map_test<MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if(0 != test::map_test_copyable<MyBoostMap
,MyStdMap
,MyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
// if (0 != test::map_test<my_managed_shared_memory
// ,MyMovableBoostMap
// ,MyStdMap
// ,MyMovableBoostMultiMap
// ,MyStdMultiMap>()){
// return 1;
// }
if (0 != test::map_test<MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test_copyable<MyMoveCopyBoostMap
,MyStdMap
,MyMoveCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test<MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test_copyable<MyCopyBoostMap
,MyStdMap
,MyCopyBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
if(!boost::container::test::test_emplace<set<test::EmplaceInt>, SetOptions>())
return 1;
if(!boost::container::test::test_emplace<multiset<test::EmplaceInt>, SetOptions>())
return 1;
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
if(!boost::container::test::test_emplace<map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

113
test/util.hpp Normal file
View File

@@ -0,0 +1,113 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2001-2003
// William E. Kempf
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_CONTAINER_TEST_UTIL_HEADER
#define BOOST_CONTAINER_TEST_UTIL_HEADER
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/sync/container_mutex.hpp>
#include <boost/container/sync/container_condition.hpp>
#include <boost/container/sync/scoped_lock.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <algorithm>
#include <iostream>
#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
#endif
namespace boost {
namespace container {
namespace test {
inline void sleep(const boost::posix_time::ptime &xt)
{
boost::container::container_mutex mx;
boost::container::scoped_lock<boost::container::container_mutex>
lock(mx);
boost::container::container_condition cond;
cond.timed_wait(lock, xt);
}
inline boost::posix_time::ptime delay(int secs, int msecs=0, int nsecs = 0)
{
(void)msecs;
using namespace boost::posix_time;
int count = static_cast<int>(double(nsecs)*
(double(time_duration::ticks_per_second())/double(1000000000.0)));
count += static_cast<int>(double(msecs)*
(double(time_duration::ticks_per_second())/double(1000.0)));
boost::posix_time::ptime cur = microsec_clock::universal_time();
return cur += boost::posix_time::time_duration(0, 0, secs, count);
}
inline bool in_range(const boost::posix_time::ptime& xt, int secs=1)
{
boost::posix_time::ptime min = delay(-secs);
boost::posix_time::ptime max = delay(0);
return (xt > min) && (max > xt);
}
boost::xtime xsecs(int secs)
{
boost::xtime ret;
boost::xtime_get(&ret, boost::TIME_UTC);
ret.sec += secs;
return ret;
}
template <typename P>
class thread_adapter
{
public:
thread_adapter(void (*func)(void*, P &), void* param1, P &param2)
: _func(func), _param1(param1) ,_param2(param2){ }
void operator()() const { _func(_param1, _param2); }
private:
void (*_func)(void*, P &);
void* _param1;
P& _param2;
};
template <typename P>
struct data
{
data(int id, int secs=0)
: m_id(id), m_value(-1), m_secs(secs)
{}
int m_id;
int m_value;
int m_secs;
};
static int shared_val = 0;
static const int BaseSeconds = 1;
} //namespace test {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_UTIL_HEADER

127
test/vector_test.cpp Normal file
View File

@@ -0,0 +1,127 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/container/vector.hpp>
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include "vector_test.hpp"
using namespace boost::container;
//Explicit instantiation to detect compilation errors
template class boost::container::vector<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
int test_expand_bwd()
{
//Now test all back insertion possibilities
//First raw ints
typedef test::expand_bwd_test_allocator<int>
int_allocator_type;
typedef vector<int, int_allocator_type>
int_vector;
if(!test::test_all_expand_bwd<int_vector>())
return 1;
//Now user defined wrapped int
typedef test::expand_bwd_test_allocator<test::int_holder>
int_holder_allocator_type;
typedef vector<test::int_holder, int_holder_allocator_type>
int_holder_vector;
if(!test::test_all_expand_bwd<int_holder_vector>())
return 1;
//Now user defined bigger wrapped int
typedef test::expand_bwd_test_allocator<test::triple_int_holder>
triple_int_holder_allocator_type;
typedef vector<test::triple_int_holder, triple_int_holder_allocator_type>
triple_int_holder_vector;
if(!test::test_all_expand_bwd<triple_int_holder_vector>())
return 1;
return 0;
}
class recursive_vector
{
public:
int id_;
vector<recursive_vector> vector_;
};
void recursive_vector_test()//Test for recursive types
{
vector<recursive_vector> recursive_vector_vector;
}
enum Test
{
zero, one, two, three, four, five, six
};
int main()
{
recursive_vector_test();
{
//Now test move semantics
vector<recursive_vector> original;
vector<recursive_vector> move_ctor(boost::move(original));
vector<recursive_vector> move_assign;
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
typedef vector<int> MyVector;
typedef vector<test::movable_int> MyMoveVector;
typedef vector<test::movable_and_copyable_int> MyCopyMoveVector;
typedef vector<test::copyable_int> MyCopyVector;
typedef vector<Test> MyEnumVector;
if(test::vector_test<MyVector>())
return 1;
if(test::vector_test<MyMoveVector>())
return 1;
if(test::vector_test<MyCopyMoveVector>())
return 1;
if(test::vector_test<MyCopyVector>())
return 1;
if(test_expand_bwd())
return 1;
MyEnumVector v;
Test t;
v.push_back(t);
v.push_back(::boost::move(t));
v.push_back(Test());
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
if(!boost::container::test::test_emplace
< vector<test::EmplaceInt>, Options>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

253
test/vector_test.hpp Normal file
View File

@@ -0,0 +1,253 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <list>
#include <boost/move/move.hpp>
#include <boost/container/detail/mpl.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include <string>
#include <vector>
#include "emplace_test.hpp"
namespace boost{
namespace container {
namespace test{
template<class V1, class V2>
bool vector_copyable_only(V1 *, V2 *, boost::container::containers_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool vector_copyable_only(V1 *boostvector, V2 *stdvector, boost::container::containers_detail::true_type)
{
typedef typename V1::value_type IntType;
std::size_t size = boostvector->size();
boostvector->insert(boostvector->end(), 50, IntType(1));
stdvector->insert(stdvector->end(), 50, 1);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
{
IntType move_me(1);
boostvector->insert(boostvector->begin()+size/2, 50, boost::move(move_me));
stdvector->insert(stdvector->begin()+size/2, 50, 1);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
{
IntType move_me(2);
boostvector->assign(boostvector->size()/2, boost::move(move_me));
stdvector->assign(stdvector->size()/2, 2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
{
IntType move_me(3);
boostvector->assign(boostvector->size()*3-1, boost::move(move_me));
stdvector->assign(stdvector->size()*3-1, 3);
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
{
IntType copy_me(3);
const IntType ccopy_me(3);
boostvector->push_back(copy_me);
stdvector->push_back(int(3));
boostvector->push_back(ccopy_me);
stdvector->push_back(int(3));
if(!test::CheckEqualContainers(boostvector, stdvector)) return false;
}
return true;
}
template<class MyBoostVector>
int vector_test()
{
typedef std::vector<int> MyStdVector;
typedef typename MyBoostVector::value_type IntType;
const int max = 100;
{
try{
MyBoostVector *boostvector = new MyBoostVector;
MyStdVector *stdvector = new MyStdVector;
boostvector->resize(100);
stdvector->resize(100);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(200);
stdvector->resize(200);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(0);
stdvector->resize(0);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0; i < max; ++i){
IntType new_int(i);
boostvector->insert(boostvector->end(), boost::move(new_int));
stdvector->insert(stdvector->end(), i);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
typename MyBoostVector::iterator boostit(boostvector->begin());
typename MyStdVector::iterator stdit(stdvector->begin());
typename MyBoostVector::const_iterator cboostit = boostit;
++boostit; ++stdit;
boostvector->erase(boostit);
stdvector->erase(stdit);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->erase(boostvector->begin());
stdvector->erase(stdvector->begin());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
{
//Initialize values
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
BOOST_STATIC_ASSERT((boost::container::test::is_copyable<boost::container::test::movable_int>::value == false));
aux_vect[i] = boost::move(new_int);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostvector->insert(boostvector->end()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0, j = static_cast<int>(boostvector->size()); i < j; ++i){
boostvector->erase(boostvector->begin());
stdvector->erase(stdvector->begin());
}
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
aux_vect[i] = boost::move(new_int);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
boostvector->insert(boostvector->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
/*
boostvector->reserve(boostvector->size()*2);
stdvector->reserve(stdvector->size()*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
*/
boostvector->shrink_to_fit();
MyStdVector(*stdvector).swap(*stdvector);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->shrink_to_fit();
MyStdVector(*stdvector).swap(*stdvector);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
IntType push_back_this(1);
boostvector->push_back(boost::move(push_back_this));
stdvector->push_back(int(1));
boostvector->push_back(IntType(1));
stdvector->push_back(int(1));
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
if(!vector_copyable_only(boostvector, stdvector
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return 1;
}
boostvector->erase(boostvector->begin());
stdvector->erase(stdvector->begin());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
for(int i = 0; i < max; ++i){
IntType insert_this(i);
boostvector->insert(boostvector->begin(), boost::move(insert_this));
stdvector->insert(stdvector->begin(), i);
boostvector->insert(boostvector->begin(), IntType(i));
stdvector->insert(stdvector->begin(), int(i));
}
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
//Test insertion from list
{
std::list<int> l(50, int(1));
boostvector->insert(boostvector->begin(), l.begin(), l.end());
stdvector->insert(stdvector->begin(), l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->assign(l.begin(), l.end());
stdvector->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
/*
std::size_t cap = boostvector->capacity();
boostvector->reserve(cap*2);
stdvector->reserve(cap*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(0);
stdvector->resize(0);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(cap*2);
stdvector->resize(cap*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->clear();
stdvector->clear();
boostvector->shrink_to_fit();
MyStdVector(*stdvector).swap(*stdvector);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->resize(cap*2);
stdvector->resize(cap*2);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
*/
delete stdvector;
delete boostvector;
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;
return 1;
}
}
std::cout << std::endl << "Test OK!" << std::endl;
return 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>