Build attempt
This commit is contained in:
parent
1182e784eb
commit
5ed0b82de7
5 changed files with 1336 additions and 15 deletions
|
|
@ -1,22 +1,81 @@
|
|||
diff --git a/adobe/move.hpp b/adobe/move.hpp
|
||||
index 350000d..6c302a2 100644
|
||||
--- a/adobe/move.hpp
|
||||
+++ b/adobe/move.hpp
|
||||
@@ -440,8 +440,8 @@ with move semantics, for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
diff --git a/asl-uninitialized-move.patch b/asl-uninitialized-move.patch
|
||||
index 2cce2e7..e69de29 100644
|
||||
--- a/asl-uninitialized-move.patch
|
||||
+++ b/asl-uninitialized-move.patch
|
||||
@@ -1,56 +0,0 @@
|
||||
-diff --git a/adobe/move.hpp b/adobe/move.hpp
|
||||
-index 350000d..6c302a2 100644
|
||||
---- a/adobe/move.hpp
|
||||
-+++ b/adobe/move.hpp
|
||||
-@@ -440,8 +440,8 @@ with move semantics, for movable types, otherwise with copy semantics.
|
||||
- */
|
||||
- template <typename I, // I models BidirectionalRange
|
||||
- typename O> // O models BidirectionalIterator
|
||||
--inline O move_backward(I& in, O out)
|
||||
--{ return move_backward(boost::begin(in), boost::end(in), out); }
|
||||
-+inline O adobe::move_backward(I& in, O out)
|
||||
-+{ return adobe::move_backward(boost::begin(in), boost::end(in), out); }
|
||||
-
|
||||
- /*************************************************************************************************/
|
||||
-
|
||||
-diff --git a/adobe/once.hpp b/adobe/once.hpp
|
||||
-index 5f005a4..e349b92 100644
|
||||
---- a/adobe/once.hpp
|
||||
-+++ b/adobe/once.hpp
|
||||
-@@ -11,12 +11,12 @@
|
||||
-
|
||||
- /*************************************************************************************************/
|
||||
-
|
||||
--#include <adobe/config.hpp>
|
||||
--
|
||||
- #if defined(BOOST_HAS_THREADS)
|
||||
- #include <boost/thread.hpp>
|
||||
- #endif
|
||||
-
|
||||
-+#include <adobe/config.hpp>
|
||||
-+
|
||||
- /*************************************************************************************************/
|
||||
-
|
||||
- namespace adobe {
|
||||
-diff --git a/adobe/vector.hpp b/adobe/vector.hpp
|
||||
-index 2d23e59..8968b59 100644
|
||||
---- a/adobe/vector.hpp
|
||||
-+++ b/adobe/vector.hpp
|
||||
-@@ -319,7 +319,7 @@ void vector<T, A>::append_move(I f, I l, std::forward_iterator_tag)
|
||||
- size_type n(std::distance(f, l));
|
||||
-
|
||||
- if (remaining() < n) reserve((adobe::max)(size() + n, 2 * size()));
|
||||
-- set_finish(uninitialized_move(f, l, end()));
|
||||
-+ set_finish(adobe::uninitialized_move(f, l, end()));
|
||||
- }
|
||||
-
|
||||
- template <typename T, typename A>
|
||||
-@@ -406,7 +406,7 @@ void vector<T, A>::reserve(size_type n)
|
||||
- if (capacity() < n) {
|
||||
- vector tmp;
|
||||
- tmp.header_m = allocate(get_allocator(), n);
|
||||
-- tmp.header_m->finish() = uninitialized_move(begin(), end(), tmp.end());
|
||||
-+ tmp.header_m->finish() = adobe::uninitialized_move(begin(), end(), tmp.end());
|
||||
- swap(tmp);
|
||||
- }
|
||||
- }
|
||||
diff --git a/tmp/source_release/adobe/move.hpp b/tmp/source_release/adobe/move.hpp
|
||||
index 350000d..5fe6db5 100644
|
||||
--- a/tmp/source_release/adobe/move.hpp
|
||||
+++ b/tmp/source_release/adobe/move.hpp
|
||||
@@ -441,7 +441,7 @@ with move semantics, for movable types, otherwise with copy semantics.
|
||||
template <typename I, // I models BidirectionalRange
|
||||
typename O> // O models BidirectionalIterator
|
||||
-inline O move_backward(I& in, O out)
|
||||
inline O move_backward(I& in, O out)
|
||||
-{ return move_backward(boost::begin(in), boost::end(in), out); }
|
||||
+inline O adobe::move_backward(I& in, O out)
|
||||
+{ return adobe::move_backward(boost::begin(in), boost::end(in), out); }
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
diff --git a/adobe/once.hpp b/adobe/once.hpp
|
||||
diff --git a/tmp/source_release/adobe/once.hpp b/tmp/source_release/adobe/once.hpp
|
||||
index 5f005a4..e349b92 100644
|
||||
--- a/adobe/once.hpp
|
||||
+++ b/adobe/once.hpp
|
||||
--- a/tmp/source_release/adobe/once.hpp
|
||||
+++ b/tmp/source_release/adobe/once.hpp
|
||||
@@ -11,12 +11,12 @@
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -32,10 +91,10 @@ index 5f005a4..e349b92 100644
|
|||
/*************************************************************************************************/
|
||||
|
||||
namespace adobe {
|
||||
diff --git a/adobe/vector.hpp b/adobe/vector.hpp
|
||||
index 2d23e59..8968b59 100644
|
||||
--- a/adobe/vector.hpp
|
||||
+++ b/adobe/vector.hpp
|
||||
diff --git a/tmp/source_release/adobe/vector.hpp b/tmp/source_release/adobe/vector.hpp
|
||||
index 926cfa9..8968b59 100644
|
||||
--- a/tmp/source_release/adobe/vector.hpp
|
||||
+++ b/tmp/source_release/adobe/vector.hpp
|
||||
@@ -319,7 +319,7 @@ void vector<T, A>::append_move(I f, I l, std::forward_iterator_tag)
|
||||
size_type n(std::distance(f, l));
|
||||
|
||||
|
|
@ -45,6 +104,24 @@ index 2d23e59..8968b59 100644
|
|||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
@@ -354,7 +354,7 @@ typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l, std::
|
||||
|
||||
if (n < after) {
|
||||
append_move(last - n, last);
|
||||
- move_backward(p, last - n, last);
|
||||
+ adobe::move_backward(p, last - n, last);
|
||||
std::copy(f, l, p);
|
||||
} else {
|
||||
I m = f;
|
||||
@@ -387,7 +387,7 @@ typename vector<T, A>::iterator vector<T, A>::insert_move(iterator p, I f, I l)
|
||||
|
||||
if (n < after) {
|
||||
append_move(last - n, last);
|
||||
- move_backward(p, last - n, last);
|
||||
+ adobe::move_backward(p, last - n, last);
|
||||
adobe::move(f, l, p);
|
||||
} else {
|
||||
I m = f;
|
||||
@@ -406,7 +406,7 @@ void vector<T, A>::reserve(size_type n)
|
||||
if (capacity() < n) {
|
||||
vector tmp;
|
||||
|
|
@ -54,3 +131,12 @@ index 2d23e59..8968b59 100644
|
|||
swap(tmp);
|
||||
}
|
||||
}
|
||||
@@ -430,7 +430,7 @@ typename vector<T, A>::iterator vector<T, A>::insert(iterator p, size_type n, co
|
||||
|
||||
if (n < after) {
|
||||
append_move(last - n, last);
|
||||
- move_backward(p, last - n, last);
|
||||
+ adobe::move_backward(p, last - n, last);
|
||||
std::fill_n(p, n, x);
|
||||
} else {
|
||||
std::uninitialized_fill_n(last, n - after, x);
|
||||
|
|
|
|||
48
tmp/source_release/adobe/array.hpp
Normal file
48
tmp/source_release/adobe/array.hpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
|
||||
or a copy at http://stlab.adobe.com/licenses.html)
|
||||
*/
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
#ifndef ADOBE_ARRAY_HPP
|
||||
#define ADOBE_ARRAY_HPP
|
||||
|
||||
#include <adobe/config.hpp>
|
||||
|
||||
#include <adobe/array_fwd.hpp>
|
||||
|
||||
#include <adobe/any_regular.hpp>
|
||||
#include <adobe/typeinfo.hpp>
|
||||
#include <adobe/vector.hpp>
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
namespace adobe {
|
||||
namespace version_1 {
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
template <typename T> // T models Regular
|
||||
inline void push_back(array_t& v, T x)
|
||||
{ v.push_back(any_regular_t(adobe::move(x))); }
|
||||
|
||||
inline void push_back(array_t& v, any_regular_t x)
|
||||
{ v.push_back(adobe::move(x)); }
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
} // namespace version_1
|
||||
|
||||
using version_1::push_back;
|
||||
|
||||
} // namespace adobe
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
ADOBE_SHORT_NAME_TYPE('a','r','r','y', adobe::array_t)
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
#endif
|
||||
491
tmp/source_release/adobe/move.hpp
Normal file
491
tmp/source_release/adobe/move.hpp
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
|
||||
or a copy at http://stlab.adobe.com/licenses.html)
|
||||
*/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef ADOBE_MOVE_HPP
|
||||
#define ADOBE_MOVE_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
/*!
|
||||
\defgroup move_related Move Library
|
||||
\ingroup utility
|
||||
\brief
|
||||
The move library is a collection of utilities for creating and using types that leverage
|
||||
return value optimization (RVO) to avoid unnecessary copies.
|
||||
|
||||
\section move_tutorial Tutorial
|
||||
User defined types often have remote parts either because they are implemented using a
|
||||
pointer-to-implementation or are variable sized. Such objects can be expensive to copy
|
||||
and are often copied unnecessarily when they are returned from functions or stored in other
|
||||
objects or containers. The \ref move_related is a collection of utilities to implement types which
|
||||
can be moved to elide copying in such situations as well as utilities to assist in moving value.
|
||||
|
||||
\par Implementing a Movable Type
|
||||
|
||||
A movable type models \ref concept_movable. There are three components of a movable type:
|
||||
- Satisfy the requirements of concept \ref concept_regular_type.
|
||||
- Implement a move-ctor using move_from<>.
|
||||
- Modify the assignment operator to take the operand by value and consume it.
|
||||
|
||||
A typical implementation of the move-ctor will simply extract the remote part, leaving the
|
||||
source in a destructible state.
|
||||
|
||||
The assignment operator takes the operand parameter by value. Typically the simplest way
|
||||
to destory the local remote part and consume the remote part of the operand is to swap
|
||||
contents with the operand. This is similar to the copy-ctor and swap idiom for implementing
|
||||
assignment.
|
||||
|
||||
Listing 1 shows an example movable class that implements a typical pointer-to-implementation
|
||||
(PiPl) idiom and shows that it can be used as any regular type.
|
||||
|
||||
\code
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <adobe/move.hpp>
|
||||
|
||||
using std::swap;
|
||||
|
||||
struct implementation : boost::equality_comparable<implementation>
|
||||
{
|
||||
explicit implementation(int x = 0) : member(x) { }
|
||||
|
||||
implementation(const implementation& x) : member(x.member)
|
||||
{ std::cout << "copy remote part: " << member << std::endl; }
|
||||
|
||||
implementation& operator=(const implementation& x)
|
||||
{
|
||||
member = x.member;
|
||||
std::cout << "assign remote part: " << member << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator==(const implementation& x, const implementation& y)
|
||||
{ return x.member == y.member; }
|
||||
|
||||
int member;
|
||||
};
|
||||
|
||||
class movable : public boost::equality_comparable<movable>
|
||||
{
|
||||
public:
|
||||
// model concept Regular
|
||||
|
||||
explicit movable(int x = 0) : member(new implementation(x)) { }
|
||||
~movable() { delete member; }
|
||||
movable(const movable& x) : member(new implementation(*x.member)) { }
|
||||
// operator=() implemented below
|
||||
|
||||
friend bool operator==(const movable& x, const movable &y)
|
||||
{ return *x.member == *y.member; }
|
||||
|
||||
friend void swap(movable& x, movable& y)
|
||||
{ swap(x.member, y.member); }
|
||||
|
||||
// model concept Movable
|
||||
|
||||
// move-ctor assumes ownership of remote part
|
||||
movable(adobe::move_from<movable> x) : member(x.source.member)
|
||||
{ x.source.member = 0; }
|
||||
|
||||
// operator=() on a movable type takes parameter by value and consumes it
|
||||
movable& operator=(movable x)
|
||||
{ swap(*this, x); return *this; }
|
||||
|
||||
private:
|
||||
implementation* member;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
movable x(10);
|
||||
movable y = x;
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
<center>Listing 1</center>
|
||||
|
||||
\verbatim
|
||||
copy remote part: 10
|
||||
\endverbatim
|
||||
<center>Output of Listing 1</center>
|
||||
|
||||
\par Returning a Movable Type
|
||||
|
||||
We can return a movable type from a function by value and unnessary copies will be avoided as
|
||||
Listing 2 illustrates:
|
||||
|
||||
\code
|
||||
//...
|
||||
movable f(int x, int y)
|
||||
{ return movable(x * y); }
|
||||
|
||||
int main()
|
||||
{
|
||||
movable x = f(10, 5);
|
||||
movable y;
|
||||
y = f(4, 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
<center>Listing 2</center>
|
||||
|
||||
\verbatim
|
||||
|
||||
\endverbatim
|
||||
<center>Ouput of Listing 2</center>
|
||||
|
||||
In this example it is not necessary to make any copies. The result of f() is constructed directly
|
||||
in place for x through a compiler optimization known as return value optimization or RVO. In the
|
||||
case of assigning to y, the same optimization allows the compiler to construct the operand for
|
||||
assignment as the result of f() which is them moved into y.
|
||||
|
||||
\par Implementing a Sink Function
|
||||
|
||||
A <em>sink</em> is any function that copies it's argument, usually for the purpose of storing it.
|
||||
A sink is often a constructor or an insert function on a container. The \c operator=() on a movable
|
||||
type is a form of a sink function. To implement a sink function pass the argument by value and then
|
||||
use \c adobe::move() to move the argument into place. Note that this technique cannot be used to
|
||||
implement \c operator=() on because it relies on assignment. Listing 3 implements an example sink
|
||||
function.
|
||||
|
||||
\code
|
||||
//...
|
||||
|
||||
struct sink
|
||||
{
|
||||
explicit sink(movable x) : member(adobe::move(x)) { }
|
||||
|
||||
movable member;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
movable x = f(10, 5);
|
||||
sink y(x); // must copy.
|
||||
sink z(f(20, 2)); // no copy.
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
<center>Listing 3</center>
|
||||
|
||||
\verbatim
|
||||
copy remote part: 50
|
||||
\endverbatim
|
||||
<center>Output of Listing 3</center>
|
||||
|
||||
Here again unnessary copies are eliminated. Although adobe::move() can be used anytime to force the
|
||||
move of an object, it should only be used as part of an explicit sink function otherwise it hinders
|
||||
the understanding of code.
|
||||
|
||||
\par Utilities
|
||||
|
||||
There are many utilities as part of the move library which can be used to move elements instead of
|
||||
copying them. These are useful when building containers or dealing with sink operations which must
|
||||
manage a collection of movable objects. Generally these operations parallel the associated copying
|
||||
algorithms from STL. Examples:
|
||||
|
||||
<table>
|
||||
<tr><td><b>Move</b></td><td><b>Copy</b></td><td><b>Comment</b></td></tr>
|
||||
<tr><td>adobe::move()</td><td>std::copy</td><td>Not to be confused with the single argument adobe::move()</td></tr>
|
||||
<tr><td>adobe::move_backward()</td><td>std::copy_backward</td></tr>
|
||||
<tr><td>adobe::back_move_iterator()</td><td>std::back_insert_iterator</td></tr>
|
||||
<tr><td>adobe::back_mover()</td><td>std::back_inserter</td></tr>
|
||||
<tr><td>adobe::move_construct()</td><td>std::construct</td></tr>
|
||||
<tr><td>adobe::uninitialized_move()</td><td>std::uninitialized_copy</td></tr>
|
||||
</table>
|
||||
|
||||
\par Advanced Topics
|
||||
|
||||
The \c adobe::move() function is a NOP if the argument is not movable, however, when a non-movable
|
||||
item is passed to a sink this may still result in an unnecessary copy - one to the sink and one to
|
||||
copy the argument of the sink into place. To avoid the additional copy, two forms of a sink function
|
||||
can be provided, one for movable types and one for copyable types. The \c adobe::move_sink<> and
|
||||
\c adobe::copy_sink<> tags can be used to select between the two functions. See the
|
||||
implementation of \c adobe::move_construct() as an example.
|
||||
|
||||
If a sink function is a member of a template class, the same issue with regard to unnecessary copies
|
||||
can occur. In this case, it is desirable to distinguish between the a copy and move sink as above
|
||||
but also to allow implicit conversions to the type stored in the container. To allow this use the
|
||||
two argument form of \c adobe::move_sink<> and \c adobe::copy_sink<>. See the implementation of
|
||||
\c adobe::vector::push_back() as an example.
|
||||
|
||||
\par Theory of Operation
|
||||
|
||||
<em>to be written</em>
|
||||
|
||||
\par Acknowledgments:
|
||||
The move library was inspired by the move library written by Dave Abrahams and the work on move
|
||||
done by Dave Abrahams and Howard Hinnant.
|
||||
*/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
namespace adobe {
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
namespace implementation {
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
template <typename T>
|
||||
struct class_has_move_assign {
|
||||
class type {
|
||||
typedef T& (T::*E)(T t);
|
||||
typedef char (&no_type)[1];
|
||||
typedef char (&yes_type)[2];
|
||||
template <E e> struct sfinae { typedef yes_type type; };
|
||||
template <class U>
|
||||
static typename sfinae<&U::operator=>::type test(int);
|
||||
template <class U>
|
||||
static no_type test(...);
|
||||
public:
|
||||
enum {value = sizeof(test<T>(1)) == sizeof(yes_type)};
|
||||
};
|
||||
};
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
template<typename T>
|
||||
struct has_move_assign : boost::mpl::and_<boost::is_class<T>, class_has_move_assign<T> > {};
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
class test_can_convert_anything { };
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
} //namespace implementation
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*
|
||||
REVISIT (sparent@adobe.com): This is a work around for Boost 1.34.1 and VC++ 2008 where
|
||||
boost::is_convertible<T, T> fails to compile.
|
||||
*/
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_convertible : boost::mpl::or_<
|
||||
boost::is_same<T, U>,
|
||||
boost::is_convertible<T, U>
|
||||
> { };
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief move_from is used for move_ctors.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
struct move_from
|
||||
{
|
||||
explicit move_from(T& x) : source(x) { }
|
||||
T& source;
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief The is_movable trait can be used to identify movable types.
|
||||
*/
|
||||
template <typename T>
|
||||
struct is_movable : boost::mpl::and_<
|
||||
boost::is_convertible<move_from<T>, T>,
|
||||
implementation::has_move_assign<T>,
|
||||
boost::mpl::not_<boost::is_convertible<implementation::test_can_convert_anything, T> >
|
||||
> { };
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief copy_sink and move_sink are used to select between overloaded operations according to
|
||||
whether type T is movable and convertible to type U.
|
||||
\sa move
|
||||
*/
|
||||
|
||||
template <typename T,
|
||||
typename U = T,
|
||||
typename R = void*>
|
||||
struct copy_sink : boost::enable_if<
|
||||
boost::mpl::and_<
|
||||
adobe::is_convertible<T, U>,
|
||||
boost::mpl::not_<is_movable<T> >
|
||||
>,
|
||||
R
|
||||
>
|
||||
{ };
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief move_sink and copy_sink are used to select between overloaded operations according to
|
||||
whether type T is movable and convertible to type U.
|
||||
\sa move
|
||||
*/
|
||||
|
||||
template <typename T,
|
||||
typename U = T,
|
||||
typename R = void*>
|
||||
struct move_sink : boost::enable_if<
|
||||
boost::mpl::and_<
|
||||
adobe::is_convertible<T, U>,
|
||||
is_movable<T>
|
||||
>,
|
||||
R
|
||||
>
|
||||
{ };
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief This version of move is selected when T is_movable . It in turn calls the move
|
||||
constructor. This call, with the help of the return value optimization, will cause x to be moved
|
||||
instead of copied to its destination. See adobe/test/move/main.cpp for examples.
|
||||
|
||||
*/
|
||||
template <typename T>
|
||||
T move(T& x, typename move_sink<T>::type = 0) { return T(move_from<T>(x)); }
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief This version of move is selected when T is not movable . The net result will be that
|
||||
x gets copied.
|
||||
*/
|
||||
template <typename T>
|
||||
T& move(T& x, typename copy_sink<T>::type = 0) { return x; }
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief Iterator pair version of move. Similar to std::copy but with move semantics,
|
||||
for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
template <typename I, // I models InputIterator
|
||||
typename O> // O models OutputIterator
|
||||
O move(I f, I l, O result)
|
||||
{
|
||||
while (f != l) {
|
||||
*result = adobe::move(*f);
|
||||
++f; ++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief \ref concept_convertible_to_range version of move. Similar to copy but with move semantics,
|
||||
for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
template <typename I, // I models InputRange
|
||||
typename O> // O models OutputIterator
|
||||
inline O move(I& in, O out) { return adobe::move(boost::begin(in), boost::end(in), out); }
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief Iterator pair version of move_backwards. Similar to std::copy_backwards but with move semantics,
|
||||
for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
template <typename I, // I models BidirectionalIterator
|
||||
typename O> // O models BidirectionalIterator
|
||||
O move_backward(I f, I l, O result)
|
||||
{
|
||||
while (f != l) {
|
||||
--l; --result;
|
||||
*result = adobe::move(*l);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief \ref concept_convertible_to_range version of move_backwards. Similar to std::copy_backwards but
|
||||
with move semantics, for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
template <typename I, // I models BidirectionalRange
|
||||
typename O> // O models BidirectionalIterator
|
||||
inline O move_backward(I& in, O out)
|
||||
{ return adobe::move_backward(boost::begin(in), boost::end(in), out); }
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief Similar to std::back_insert_iterator but
|
||||
with move semantics, for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
|
||||
template <typename C> // C models Container
|
||||
class back_move_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
|
||||
{
|
||||
C* container_m;
|
||||
|
||||
public:
|
||||
typedef C container_type;
|
||||
|
||||
explicit back_move_iterator(C& x) : container_m(&x) { }
|
||||
|
||||
back_move_iterator& operator=(typename C::value_type x)
|
||||
{ container_m->push_back(adobe::move(x)); return *this; }
|
||||
|
||||
back_move_iterator& operator*() { return *this; }
|
||||
back_move_iterator& operator++() { return *this; }
|
||||
back_move_iterator& operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup move_related
|
||||
\brief Similar to std::back_inserter but
|
||||
with move semantics, for movable types, otherwise with copy semantics.
|
||||
*/
|
||||
|
||||
template <typename C> // C models Container
|
||||
inline back_move_iterator<C> back_mover(C& x) { return back_move_iterator<C>(x); }
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
} // namespace adobe
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
176
tmp/source_release/adobe/once.hpp
Normal file
176
tmp/source_release/adobe/once.hpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
|
||||
or a copy at http://stlab.adobe.com/licenses.html)
|
||||
*/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef ADOBE_ONCE_HPP
|
||||
#define ADOBE_ONCE_HPP
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
#include <boost/thread.hpp>
|
||||
#endif
|
||||
|
||||
#include <adobe/config.hpp>
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
namespace adobe {
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
typedef boost::once_flag once_flag;
|
||||
#define ADOBE_ONCE_INIT BOOST_ONCE_INIT
|
||||
|
||||
inline void call_once(void (*func)(), adobe::once_flag& flag)
|
||||
{
|
||||
boost::call_once(func, flag);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#else
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
typedef bool once_flag;
|
||||
#define ADOBE_ONCE_INIT false
|
||||
|
||||
inline void call_once(void (*func)(), adobe::once_flag& flag)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
(*func)();
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
} // namespace adobe
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#define ADOBE_ONCE_DECLARATION(signature) \
|
||||
struct adobe_initialize_constants_##signature##_t \
|
||||
{ \
|
||||
adobe_initialize_constants_##signature##_t(); \
|
||||
};
|
||||
|
||||
#define ADOBE_ONCE_DEFINITION(signature, func) \
|
||||
namespace { \
|
||||
adobe::once_flag adobe_once_flag_##signature##_s = ADOBE_ONCE_INIT; \
|
||||
} \
|
||||
adobe_initialize_constants_##signature##_t::adobe_initialize_constants_##signature##_t() \
|
||||
{ \
|
||||
adobe::call_once(&func, adobe_once_flag_##signature##_s); \
|
||||
}
|
||||
|
||||
#define ADOBE_ONCE_INSTANCE(signature) \
|
||||
adobe_initialize_constants_##signature##_t adobe_initialize_constants_##signature##_s
|
||||
|
||||
#define ADOBE_ONCE_STATIC_INSTANCE(signature) \
|
||||
namespace { ADOBE_ONCE_INSTANCE(signature); }
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
#define ADOBE_GLOBAL_MUTEX_DEFINITION(signature) \
|
||||
namespace { \
|
||||
adobe::once_flag adobe_once_flag_##signature##_s = ADOBE_ONCE_INIT; \
|
||||
boost::mutex* adobe_mutex_ptr_##signature##_s = 0; \
|
||||
void adobe_init_once_##signature() \
|
||||
{ \
|
||||
static boost::mutex mutex_s; \
|
||||
adobe_mutex_ptr_##signature##_s = &mutex_s; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ADOBE_GLOBAL_MUTEX_INSTANCE(signature) \
|
||||
boost::call_once(&adobe_init_once_##signature, adobe_once_flag_##signature##_s); \
|
||||
boost::mutex::scoped_lock lock(*adobe_mutex_ptr_##signature##_s)
|
||||
|
||||
#else
|
||||
|
||||
#define ADOBE_GLOBAL_MUTEX_DEFINITION(signature)
|
||||
#define ADOBE_GLOBAL_MUTEX_INSTANCE(signature)
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE_1(type, signature, ctor_p1) \
|
||||
namespace { \
|
||||
typedef boost::thread_specific_ptr< type > adobe_thread_local_storage_##signature##_t; \
|
||||
adobe_thread_local_storage_##signature##_t* adobe_thread_local_storage_##signature##_g = 0;\
|
||||
type& adobe_thread_local_storage_##signature##_access(); \
|
||||
type& adobe_thread_local_storage_##signature##_access() \
|
||||
{ \
|
||||
type* result = adobe_thread_local_storage_##signature##_g->get(); \
|
||||
if (result) return *result; \
|
||||
result = new type(ctor_p1); \
|
||||
adobe_thread_local_storage_##signature##_g->reset(result); \
|
||||
return *result; \
|
||||
} }
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE(type, signature) \
|
||||
namespace { \
|
||||
typedef boost::thread_specific_ptr< type > adobe_thread_local_storage_##signature##_t; \
|
||||
adobe_thread_local_storage_##signature##_t* adobe_thread_local_storage_##signature##_g = 0;\
|
||||
type& adobe_thread_local_storage_##signature##_access(); \
|
||||
type& adobe_thread_local_storage_##signature##_access() \
|
||||
{ \
|
||||
type* result = adobe_thread_local_storage_##signature##_g->get(); \
|
||||
if (result) return *result; \
|
||||
result = new type(); \
|
||||
adobe_thread_local_storage_##signature##_g->reset(result); \
|
||||
return *result; \
|
||||
} }
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE_INITIALIZE(signature) \
|
||||
static adobe_thread_local_storage_##signature##_t adobe_thread_local_storage_##signature##_s; \
|
||||
adobe_thread_local_storage_##signature##_g = &adobe_thread_local_storage_##signature##_s
|
||||
|
||||
#else
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE_1(type, signature, ctor_p1) \
|
||||
type& adobe_thread_local_storage_##signature##_access(); \
|
||||
type& adobe_thread_local_storage_##signature##_access() \
|
||||
{ \
|
||||
static type adobe_thread_local_storage_##signature##_s(ctor_p1); \
|
||||
return adobe_thread_local_storage_##signature##_s; \
|
||||
}
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE(type, signature) \
|
||||
type& adobe_thread_local_storage_##signature##_access(); \
|
||||
type& adobe_thread_local_storage_##signature##_access() \
|
||||
{ \
|
||||
static type adobe_thread_local_storage_##signature##_s; \
|
||||
return adobe_thread_local_storage_##signature##_s; \
|
||||
}
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE_INITIALIZE(signature)
|
||||
|
||||
#endif
|
||||
|
||||
#define ADOBE_THREAD_LOCAL_STORAGE_ACCESS(signature) \
|
||||
adobe_thread_local_storage_##signature##_access()
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#endif // ADOBE_ONCE_HPP
|
||||
|
||||
/*************************************************************************************************/
|
||||
520
tmp/source_release/adobe/vector.hpp
Normal file
520
tmp/source_release/adobe/vector.hpp
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
Copyright 2005-2007 Adobe Systems Incorporated
|
||||
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
|
||||
or a copy at http://stlab.adobe.com/licenses.html)
|
||||
*/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef ADOBE_VECTOR_HPP
|
||||
#define ADOBE_VECTOR_HPP
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <adobe/config.hpp>
|
||||
|
||||
#include <adobe/vector_fwd.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/has_nothrow_constructor.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#include <adobe/empty.hpp>
|
||||
#include <adobe/typeinfo.hpp>
|
||||
#include <adobe/memory.hpp>
|
||||
#include <adobe/algorithm/minmax.hpp>
|
||||
|
||||
#include <adobe/move.hpp>
|
||||
#include <adobe/implementation/swap.hpp>
|
||||
|
||||
#ifdef ADOBE_STD_SERIALIZATION
|
||||
#include <adobe/iomanip.hpp>
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
namespace adobe {
|
||||
namespace version_1 {
|
||||
|
||||
/*!
|
||||
\defgroup container Containers
|
||||
\ingroup asl_libraries
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
//!\ingroup abi_container
|
||||
template <typename T, // T models Regular
|
||||
typename A> // A models Allocator(T)
|
||||
class vector : boost::totally_ordered<vector<T, A>, vector<T, A> >
|
||||
{
|
||||
public:
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef A allocator_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef std::reverse_iterator<T*> reverse_iterator;
|
||||
typedef std::reverse_iterator<const T*> const_reverse_iterator;
|
||||
|
||||
private:
|
||||
struct header_t
|
||||
{
|
||||
struct compact_header_t
|
||||
{
|
||||
boost::compressed_pair<A, T*> allocate_finish_m;
|
||||
T* end_of_storage_m;
|
||||
};
|
||||
aligned_storage<compact_header_t> header_m;
|
||||
T storage_m[1];
|
||||
|
||||
allocator_type& allocator() { return header_m.get().allocate_finish_m.first(); }
|
||||
const allocator_type& allocator() const { return header_m.get().allocate_finish_m.first(); }
|
||||
|
||||
pointer& finish() { return header_m.get().allocate_finish_m.second(); }
|
||||
const pointer& finish() const { return header_m.get().allocate_finish_m.second(); }
|
||||
|
||||
pointer& end_of_storage() { return header_m.get().end_of_storage_m; }
|
||||
const pointer& end_of_storage() const { return header_m.get().end_of_storage_m; }
|
||||
};
|
||||
|
||||
header_t* header_m;
|
||||
|
||||
void set_finish(T* x)
|
||||
{
|
||||
assert(header_m != 0 || x == 0);
|
||||
if (header_m) header_m->finish() = x;
|
||||
}
|
||||
|
||||
const T* end_of_storage() const { return header_m ? header_m->end_of_storage() : 0; }
|
||||
|
||||
static header_t* allocate(allocator_type, std::size_t);
|
||||
|
||||
size_type remaining() const { return end_of_storage() - end(); }
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
void append(I f, I l) { append(f, l, typename std::iterator_traits<I>::iterator_category()); }
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
void append(I f, I l, std::input_iterator_tag);
|
||||
|
||||
template <typename I> // I models ForwardIterator
|
||||
void append(I f, I l, std::forward_iterator_tag);
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
void append_move(I f, I l)
|
||||
{ append_move(f, l, typename std::iterator_traits<I>::iterator_category()); }
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
void append_move(I f, I l, std::input_iterator_tag);
|
||||
|
||||
template <typename I> // I models ForwardIterator
|
||||
void append_move(I f, I l, std::forward_iterator_tag);
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
iterator insert(iterator p, I f, I l, std::input_iterator_tag);
|
||||
|
||||
template <typename I> // I models ForwardIterator
|
||||
iterator insert(iterator p, I f, I l, std::forward_iterator_tag);
|
||||
|
||||
public:
|
||||
// 23.2.4.1 construct/copy/destroy
|
||||
|
||||
explicit vector(const allocator_type& a) : header_m(allocate(a, 0)) { }
|
||||
vector() : header_m(0) { }
|
||||
|
||||
explicit vector(size_type n) : header_m(allocate(allocator_type(), n))
|
||||
{
|
||||
std::uninitialized_fill_n(end(), n, value_type());
|
||||
set_finish(end() + n);
|
||||
}
|
||||
|
||||
vector(size_type n, const value_type& x) : header_m(allocate(allocator_type(), n))
|
||||
{
|
||||
std::uninitialized_fill_n(end(), n, x);
|
||||
set_finish(end() + n);
|
||||
}
|
||||
|
||||
vector(size_type n, const value_type& x, const allocator_type& a) : header_m(allocate(a, n))
|
||||
{
|
||||
std::uninitialized_fill_n(end(), n, x);
|
||||
set_finish(end() + n);
|
||||
}
|
||||
|
||||
vector(const vector& x) : header_m(allocate(x.get_allocator(), x.size()))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
/* REVISIT (sparent) : MS stupid "safety check" doesn't known about empty ranges. */
|
||||
set_finish(x.begin() == x.end() ? end() : std::uninitialized_copy(x.begin(), x.end(), end()));
|
||||
#else
|
||||
set_finish(std::uninitialized_copy(x.begin(), x.end(), end()));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
vector(I f, I l, typename boost::disable_if<boost::is_integral<I> >::type* = 0) : header_m(0)
|
||||
{ append(f, l); }
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
vector(I f, I l, const allocator_type& a,
|
||||
typename boost::disable_if<boost::is_integral<I> >::type* = 0) : header_m(allocate(a), 0)
|
||||
{ append(f, l); }
|
||||
|
||||
~vector() {
|
||||
if (header_m) {
|
||||
clear();
|
||||
|
||||
typename allocator_type::template rebind<char>::other alloc(get_allocator());
|
||||
alloc.deallocate(reinterpret_cast<char*>(header_m),
|
||||
(end_of_storage() - begin()) * sizeof(T) + (sizeof(header_t) - sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
// adobe addition
|
||||
|
||||
vector(move_from<vector> x) : header_m(x.source.header_m) { x.source.header_m = 0; }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{ return header_m ? header_m->allocator() : allocator_type(); }
|
||||
|
||||
iterator begin() { return header_m ? &header_m->storage_m[0] : 0; }
|
||||
iterator end() { return header_m ? header_m->finish() : 0; }
|
||||
|
||||
const_iterator begin() const { return header_m ? &header_m->storage_m[0] : 0; }
|
||||
const_iterator end() const { return header_m ? header_m->finish() : 0; }
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
size_type size() const { return size_type(end() - begin()); }
|
||||
size_type max_size() const { return size_type(-1) / sizeof(value_type); }
|
||||
|
||||
size_type capacity() const { return size_type(end_of_storage() - begin()); }
|
||||
bool empty() const { return begin() == end(); }
|
||||
|
||||
reference operator[](size_type n) { assert(n < size()); return *(begin() + n); }
|
||||
const_reference operator[](size_type n) const { assert(n < size()); return *(begin() + n); }
|
||||
|
||||
/*
|
||||
REVISIT (sparent@adobe.com): at() explicitly omitted because it pulls in out_of_range
|
||||
which inherits from logic_error and uses std::string.
|
||||
*/
|
||||
|
||||
vector& operator=(vector x) { swap(x); return *this; }
|
||||
|
||||
void reserve(size_type n);
|
||||
|
||||
reference front() { assert(!empty()); return *begin(); }
|
||||
const_reference front() const { assert(!empty()); return *begin(); }
|
||||
|
||||
reference back() { assert(!empty()); return *(end() - 1); }
|
||||
const_reference back() const { assert(!empty()); return *(end() - 1); }
|
||||
|
||||
void push_back(value_type x)
|
||||
{ append_move(&x, &x + 1); }
|
||||
|
||||
void pop_back() { assert(!empty()); resize(size() - 1); }
|
||||
|
||||
void swap(vector& x) { std::swap(header_m, x.header_m); }
|
||||
|
||||
iterator insert(iterator p, value_type x)
|
||||
{ return insert_move(p, &x, &x + 1); }
|
||||
|
||||
template <typename I> // I models InputIterator
|
||||
iterator insert(iterator p, I f, I l, typename boost::disable_if<boost::is_integral<I> >::type* = 0)
|
||||
{ return insert(p, f, l, typename std::iterator_traits<I>::iterator_category()); }
|
||||
|
||||
template <typename I> // I models ForwardIterator
|
||||
iterator insert_move(iterator p, I f, I l);
|
||||
|
||||
iterator insert(iterator p, size_type n, const T& x);
|
||||
|
||||
iterator erase(iterator pos) { assert(pos != end()); return erase(pos, pos + 1); }
|
||||
|
||||
iterator erase(iterator f, iterator l);
|
||||
|
||||
void clear() { erase(begin(), end()); }
|
||||
|
||||
void resize(size_type n);
|
||||
|
||||
void resize(size_type n, const value_type& x);
|
||||
|
||||
friend inline bool operator==(const vector& x, const vector& y)
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1600 && _ITERATOR_DEBUG_LEVEL != 0
|
||||
return (x.size() == y.size()) && std::_Equal1(x.begin(), x.end(),
|
||||
y.begin(), std::tr1::false_type());
|
||||
#else
|
||||
return (x.size() == y.size()) && std::equal(x.begin(), x.end(), y.begin());
|
||||
#endif
|
||||
}
|
||||
|
||||
friend inline bool operator<(const vector& x, const vector& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
friend inline void swap(vector& x, vector& y) { x.swap(y); }
|
||||
};
|
||||
|
||||
template <typename T, typename A>
|
||||
typename vector<T, A>::header_t* vector<T, A>::allocate(allocator_type a, std::size_t n)
|
||||
{
|
||||
if (n == 0) {
|
||||
if (a == allocator_type()) return 0;
|
||||
n = 1;
|
||||
}
|
||||
|
||||
typename allocator_type::template rebind<char>::other alloc(a);
|
||||
|
||||
header_t* result = reinterpret_cast<header_t*>(alloc.allocate(sizeof(header_t) - sizeof(T)
|
||||
+ n * sizeof(T)));
|
||||
construct(&result->allocator(), a);
|
||||
result->finish() = &result->storage_m[0];
|
||||
result->end_of_storage() = result->finish() + n;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models InputIterator
|
||||
void vector<T, A>::append(I f, I l, std::input_iterator_tag) { while (f != l) { push_back(*f); ++f; } }
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models InputIterator
|
||||
void vector<T, A>::append_move(I f, I l, std::input_iterator_tag)
|
||||
{ while (f != l) { push_back(adobe::move(*f)); ++f; } }
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models ForwardIterator
|
||||
void vector<T, A>::append(I f, I l, std::forward_iterator_tag)
|
||||
{
|
||||
size_type n(std::distance(f, l));
|
||||
|
||||
if (remaining() < n) reserve((adobe::max)(size() + n, 2 * size()));
|
||||
set_finish(std::uninitialized_copy(f, l, end()));
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models ForwardIterator
|
||||
void vector<T, A>::append_move(I f, I l, std::forward_iterator_tag)
|
||||
{
|
||||
size_type n(std::distance(f, l));
|
||||
|
||||
if (remaining() < n) reserve((adobe::max)(size() + n, 2 * size()));
|
||||
set_finish(adobe::uninitialized_move(f, l, end()));
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models InputIterator
|
||||
typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l, std::input_iterator_tag)
|
||||
{
|
||||
size_type o(p - begin());
|
||||
size_type s = size();
|
||||
append(f, l);
|
||||
// REVISIT (sparent) : This could be a move based rotate
|
||||
std::rotate(begin() + o, begin() + s, end());
|
||||
return end() - s + o;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models ForwardIterator
|
||||
typename vector<T, A>::iterator vector<T, A>::insert(iterator p, I f, I l, std::forward_iterator_tag)
|
||||
{
|
||||
size_type n(std::distance(f, l));
|
||||
iterator last = end();
|
||||
size_type before = p - begin();
|
||||
|
||||
if (remaining() < n) {
|
||||
vector tmp;
|
||||
tmp.reserve((adobe::max)(size() + n, 2 * size()));
|
||||
tmp.append_move(begin(), p);
|
||||
tmp.append(f, l);
|
||||
tmp.append_move(p, last);
|
||||
swap(tmp);
|
||||
} else {
|
||||
size_type after(last - p);
|
||||
|
||||
if (n < after) {
|
||||
append_move(last - n, last);
|
||||
adobe::move_backward(p, last - n, last);
|
||||
std::copy(f, l, p);
|
||||
} else {
|
||||
I m = f;
|
||||
std::advance(m, after);
|
||||
append(m, l);
|
||||
append_move(p, last);
|
||||
std::copy(f, m, p);
|
||||
}
|
||||
}
|
||||
return begin() + before + n;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
template <typename I> // I models ForwardIterator
|
||||
typename vector<T, A>::iterator vector<T, A>::insert_move(iterator p, I f, I l)
|
||||
{
|
||||
size_type n(std::distance(f, l));
|
||||
iterator last = end();
|
||||
size_type before = p - begin();
|
||||
|
||||
if (remaining() < n) {
|
||||
vector tmp;
|
||||
tmp.reserve((adobe::max)(size() + n, 2 * size()));
|
||||
tmp.append_move(begin(), p);
|
||||
tmp.append_move(f, l);
|
||||
tmp.append_move(p, last);
|
||||
swap(tmp);
|
||||
} else {
|
||||
size_type after(last - p);
|
||||
|
||||
if (n < after) {
|
||||
append_move(last - n, last);
|
||||
adobe::move_backward(p, last - n, last);
|
||||
adobe::move(f, l, p);
|
||||
} else {
|
||||
I m = f;
|
||||
std::advance(m, after);
|
||||
append_move(m, l);
|
||||
append_move(p, last);
|
||||
adobe::move(f, m, p);
|
||||
}
|
||||
}
|
||||
return begin() + before + n;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
void vector<T, A>::reserve(size_type n)
|
||||
{
|
||||
if (capacity() < n) {
|
||||
vector tmp;
|
||||
tmp.header_m = allocate(get_allocator(), n);
|
||||
tmp.header_m->finish() = adobe::uninitialized_move(begin(), end(), tmp.end());
|
||||
swap(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
typename vector<T, A>::iterator vector<T, A>::insert(iterator p, size_type n, const T& x)
|
||||
{
|
||||
iterator last = end();
|
||||
size_type before = p - begin();
|
||||
|
||||
if (remaining() < n) {
|
||||
vector tmp;
|
||||
tmp.reserve((adobe::max)(size() + n, 2 * size()));
|
||||
tmp.append_move(begin(), p);
|
||||
std::uninitialized_fill_n(tmp.end(), n, x);
|
||||
tmp.set_finish(tmp.end() + n);
|
||||
tmp.append_move(p, last);
|
||||
swap(tmp);
|
||||
} else {
|
||||
size_type after(last - p);
|
||||
|
||||
if (n < after) {
|
||||
append_move(last - n, last);
|
||||
adobe::move_backward(p, last - n, last);
|
||||
std::fill_n(p, n, x);
|
||||
} else {
|
||||
std::uninitialized_fill_n(last, n - after, x);
|
||||
set_finish(last + (n - after));
|
||||
append_move(p, last);
|
||||
std::fill_n(p, after, x);
|
||||
}
|
||||
}
|
||||
return begin() + before + n;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
typename vector<T, A>::iterator vector<T, A>::erase(iterator f, iterator l)
|
||||
{
|
||||
iterator i = adobe::move(l, end(), f);
|
||||
for (iterator b(i), e(end()); b != e; ++b) {
|
||||
b->~value_type();
|
||||
}
|
||||
set_finish(i);
|
||||
return f;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
void vector<T, A>::resize(size_type n)
|
||||
{
|
||||
if (n < size()) erase(begin() + n, end());
|
||||
else insert(end(), n - size(), value_type());
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
void vector<T, A>::resize(size_type n, const value_type& x)
|
||||
{
|
||||
if (n < size()) erase(begin() + n, end());
|
||||
else insert(end(), n - size(), x);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifdef ADOBE_STD_SERIALIZATION
|
||||
|
||||
template <typename T, typename A>
|
||||
std::ostream& operator<<(std::ostream& out, const vector<T, A>& x)
|
||||
{
|
||||
out << begin_sequence;
|
||||
|
||||
for (typename vector<T, A>::const_iterator first(x.begin()), last(x.end()); first != last; ++first)
|
||||
{
|
||||
out << format(*first);
|
||||
}
|
||||
|
||||
out << end_sequence;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(vector<int>) == sizeof(void*));
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
} // namespace version_1
|
||||
} // namespace adobe
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
ADOBE_NAME_TYPE_1("vector:version_1:adobe", adobe::version_1::vector<T0,
|
||||
adobe::capture_allocator<T0> >)
|
||||
ADOBE_NAME_TYPE_2("vector:version_1:adobe", adobe::version_1::vector<T0, T1>)
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename T, typename A>
|
||||
struct has_nothrow_constructor<adobe::version_1::vector<T, A> > : boost::mpl::true_ { };
|
||||
|
||||
} // namespace boost
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#endif
|
||||
Reference in a new issue