diff --git a/autowrap/CodeGenerator.py b/autowrap/CodeGenerator.py index e6add1e9..e441da2d 100644 --- a/autowrap/CodeGenerator.py +++ b/autowrap/CodeGenerator.py @@ -1327,6 +1327,7 @@ def create_default_cimports(self): |from libcpp.vector cimport vector as libcpp_vector |from libcpp.pair cimport pair as libcpp_pair |from libcpp.map cimport map as libcpp_map + |from libcpp.utility cimport move as libcpp_move |from libcpp cimport bool |from libc.string cimport const_char |from cython.operator cimport dereference as deref, @@ -1340,11 +1341,11 @@ def create_default_cimports(self): """) if self.include_shared_ptr == "boost": code.add(""" - |from smart_ptr cimport shared_ptr + |from smart_ptr cimport shared_ptr, make_shared """) elif self.include_shared_ptr == "std": code.add(""" - |from libcpp.memory cimport shared_ptr + |from libcpp.memory cimport shared_ptr, make_shared """) if self.include_numpy: code.add(""" diff --git a/autowrap/ConversionProvider.py b/autowrap/ConversionProvider.py index ea514eb9..86ffbebf 100644 --- a/autowrap/ConversionProvider.py +++ b/autowrap/ConversionProvider.py @@ -193,7 +193,6 @@ def input_conversion(self, cpp_type, argument_var, arg_num): def output_conversion(self, cpp_type, input_cpp_var, output_py_var): raise NotImplementedError() - def _codeForInstantiateObjectFromIter(self, cpp_type, it): """ Code for new object instantation from iterator (double deref for iterator-ptr) @@ -216,6 +215,65 @@ def _codeForInstantiateObjectFromIter(self, cpp_type, it): else: return string.Template("shared_ptr[$cpp_type](new $cpp_type(deref($it)))").substitute(locals()) + def _codeForMakeSharedPtrFromIter(self, cpp_type, it): + """ + Code for creation of a shared_ptr from the same memory location as the iterator (double deref for iterator-ptr) + Note that if cpp_type is a pointer and the iterator therefore refers to + a STL object of std::vector< _FooObject* >, then we need the base type + to instantate a new object and dereference twice. + Example output: + make_shared[ _FooObject ] (*foo_iter) + make_shared[ _FooObject ] (**foo_iter_ptr) + """ + tmp_cpp_type = cpp_type + if tmp_cpp_type.is_ref: + tmp_cpp_type = tmp_cpp_type.base_type + + if tmp_cpp_type.is_ptr: + cpp_type_base = tmp_cpp_type.base_type + return string.Template("make_shared[$cpp_type_base](deref(deref($it)))").substitute(locals()) + else: + return string.Template("make_shared[$cpp_type](deref($it))").substitute(locals()) + + def _codeForDerefFromIter(self, cpp_type, it): + """ + Code for creation of correct dereferencing code from an iterator (i.e. double deref for iterator-ptr) + Note that if cpp_type is a pointer and the iterator therefore refers to + a STL object of std::vector< _FooObject* >, then we need the base type + to instantate a new object and dereference twice. + Example output: + *foo_iter + **foo_iter_ptr + """ + + tmp_cpp_type = cpp_type + if tmp_cpp_type.is_ref: + tmp_cpp_type = tmp_cpp_type.base_type + + if tmp_cpp_type.is_ptr: + cpp_type_base = tmp_cpp_type.base_type + return string.Template("deref(deref($it))").substitute(locals()) + else: + return string.Template("deref($it)").substitute(locals()) + + def _codeForPtrType(self, cpp_type): + """ + Code for creation of a pointer type from the inner type + Example output: + foo * + """ + + tmp_cpp_type = cpp_type + if tmp_cpp_type.is_ref: + tmp_cpp_type = tmp_cpp_type.base_type + + if tmp_cpp_type.is_ptr: + cpp_type_base = tmp_cpp_type.base_type + return string.Template("$cpp_type_base *").substitute(locals()) + else: + return string.Template("$cpp_type *").substitute(locals()) + + class VoidConverter(TypeConverterBase): def get_base_types(self): @@ -1066,11 +1124,15 @@ def _prepare_nonrecursive_cleanup(self, cpp_type, bottommost_code, it_prev, temp # If we are inside a recursion, we have to dereference the # _previous_ iterator. a[0]["temp_var_used"] = "deref(%s)" % it_prev - tp_add = "$it = $temp_var_used.begin()" + tp_add = """ + |$it = $temp_var_used.begin() + """ else: - tp_add = "cdef libcpp_vector[$inner].iterator $it = $temp_var.begin()" + tp_add = """ + |cdef libcpp_vector[$inner].iterator $it = $temp_var.begin() + |cdef $ptrtype address_$item + """ btm_add = """ - |$argument_var[:] = replace_$recursion_cnt |del $temp_var """ a[0]["temp_var_used"] = temp_var @@ -1078,11 +1140,17 @@ def _prepare_nonrecursive_cleanup(self, cpp_type, bottommost_code, it_prev, temp # Add cleanup code (loop through the temporary vector C++ and # add items to the python replace_n list). cleanup_code = Code().add(tp_add + """ - |replace_$recursion_cnt = [] - |while $it != $temp_var_used.end(): - | $item = $cy_tt.__new__($cy_tt) - | $item.inst = $instantiation - | replace_$recursion_cnt.append($item) + |oldlen = len($argument_var) + |tmpnewlen = $temp_var_used.size() + |newlen = max(oldlen, tmpnewlen) + |if newlen > oldlen: $argument_var.extend([$cy_tt.__new__($cy_tt) for i in range(0,tmpnewlen-oldlen)]) + |else: del $argument_var[newlen:] + |for $item in $argument_var: + | if $item.inst.get() != NULL: + | address_$item = $item.inst.get() + | address_$item[0] = libcpp_move($address) + | else: + | $item.inst = $make_shared | inc($it) """ + btm_add, *a, **kw) else: @@ -1110,8 +1178,12 @@ def _prepare_recursive_cleanup(self, cpp_type, bottommost_code, it_prev, temp_va tp_add = "cdef libcpp_vector[$inner].iterator $it = $temp_var.begin()" a[0]["temp_var_used"] = temp_var cleanup_code = Code().add(tp_add + """ - |replace_$recursion_cnt = [] - |while $it != $temp_var_used.end(): + |oldlen = len($argument_var) + |tmpnewlen = $temp_var_used.size() + |newlen = max(oldlen, tmpnewlen) + |if newlen > oldlen: $argument_var.extend([[] for i in range(0,tmpnewlen-oldlen)]) + |else: del $argument_var[newlen:] + |for $item in $argument_var: """, *a, **kw) else: if recursion_cnt == 0: @@ -1133,7 +1205,7 @@ def _prepare_nonrecursive_precall(self, topmost_code, cpp_type, code_top, do_der # Now prepare the loop itself code = Code().add(code_top + """ |for $item in $argument_var: - | $temp_var.push_back($do_deref($item.inst.get())) + | $temp_var.push_back(libcpp_move($do_deref($item.inst.get()))) """, *a, **kw) return code @@ -1212,7 +1284,6 @@ def _perform_recursion(self, cpp_type, tt, arg_num, item, topmost_code, # if cpp_type.topmost_is_ref and not cpp_type.topmost_is_const: cleanup_code.add(""" - | replace_$recursion_cnt.append(replace_$recursion_cnt_next) | inc($it) """, *a, **kw) @@ -1225,7 +1296,6 @@ def _perform_recursion(self, cpp_type, tt, arg_num, item, topmost_code, cleanup_code.content.extend(bottommost_code_callback.content) if cpp_type.topmost_is_ref and not cpp_type.topmost_is_const: cleanup_code.add(""" - |$argument_var[:] = replace_$recursion_cnt |del $temp_var """, *a, **kw) else: @@ -1312,6 +1382,9 @@ def input_conversion(self, cpp_type, argument_var, arg_num, topmost_code=None, b do_deref = "" instantiation = self._codeForInstantiateObjectFromIter(inner, it) + make_shared = self._codeForMakeSharedPtrFromIter(inner, it) + address = self._codeForDerefFromIter(inner, it) + ptrtype = self._codeForPtrType(inner) code = self._prepare_nonrecursive_precall(topmost_code, cpp_type, code_top, do_deref, locals()) cleanup_code = self._prepare_nonrecursive_cleanup( cpp_type, bottommost_code, it_prev, temp_var, recursion_cnt, locals()) @@ -1498,7 +1571,7 @@ def matches(self, cpp_type): return not cpp_type.is_ptr def matching_python_type(self, cpp_type): - return "bytes" + return "str" def input_conversion(self, cpp_type, argument_var, arg_num): code = "" @@ -1507,7 +1580,7 @@ def input_conversion(self, cpp_type, argument_var, arg_num): return code, call_as, cleanup def type_check_expression(self, cpp_type, argument_var): - return "isinstance(%s, bytes)" % argument_var + return "isinstance(%s, str)" % argument_var def output_conversion(self, cpp_type, input_cpp_var, output_py_var): return "%s = %s" % (output_py_var, input_cpp_var) diff --git a/autowrap/Utils.py b/autowrap/Utils.py index 2860f80b..51611c40 100644 --- a/autowrap/Utils.py +++ b/autowrap/Utils.py @@ -84,9 +84,12 @@ def compile_and_import(name, source_files, include_dirs=None, **kws): link_args = [] if sys.platform == "darwin": - compile_args += ["-stdlib=libc++"] + compile_args += ["-stdlib=libc++", "-std=c++11"] link_args += ["-stdlib=libc++"] + if sys.platform == "linux" or sys.platform == "linux2": + compile_args += ["-std=c++11"] + if sys.platform != "win32": compile_args += ["-Wno-unused-but-set-variable"] diff --git a/autowrap/data_files/autowrap/AutowrapStrHandling.pxd b/autowrap/data_files/autowrap/AutowrapStrHandling.pxd new file mode 100644 index 00000000..acfe0260 --- /dev/null +++ b/autowrap/data_files/autowrap/AutowrapStrHandling.pxd @@ -0,0 +1,91 @@ + +######################################################################## +######################################################################## +######################################################################## +## Python 3 compatibility functions +######################################################################## +from cpython.version cimport PY_MAJOR_VERSION, PY_MINOR_VERSION +from cpython cimport PyBytes_Check, PyUnicode_Check +from cpython cimport array as c_array +from libcpp.string cimport string as libcpp_string + +cdef bint IS_PYTHON3 = PY_MAJOR_VERSION >= 3 + +cdef from_string_and_size(const char* s, size_t length): + if IS_PYTHON3: + return s[:length].decode("utf8") + else: + return s[:length] + + +# filename encoding +cdef str FILENAME_ENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() or 'ascii' +cdef str TEXT_ENCODING = 'utf-8' + +cdef bytes encode_filename(object filename): + """Make sure a filename is 8-bit encoded (or None).""" + if filename is None: + return None + elif PY_MAJOR_VERSION >= 3 and PY_MINOR_VERSION >= 2: + # Added to support path-like objects + return os.fsencode(filename) + elif PyBytes_Check(filename): + return filename + elif PyUnicode_Check(filename): + return filename.encode(FILENAME_ENCODING) + else: + raise TypeError("Argument must be string or unicode.") + + +cdef bytes force_bytes(object s, encoding=TEXT_ENCODING): + """convert string or unicode object to bytes, assuming + utf8 encoding. + """ + if s is None: + return None + elif PyBytes_Check(s): + return s + elif PyUnicode_Check(s): + return s.encode(encoding) + else: + raise TypeError("Argument must be string, bytes or unicode.") + + +cdef charptr_to_str(const char* s, encoding=TEXT_ENCODING): + if s == NULL: + return None + if PY_MAJOR_VERSION < 3: + return s + else: + return s.decode(encoding) + + +cdef charptr_to_str_w_len(const char* s, size_t n, encoding=TEXT_ENCODING): + if s == NULL: + return None + if PY_MAJOR_VERSION < 3: + return s[:n] + else: + return s[:n].decode(encoding) + + +cdef bytes charptr_to_bytes(const char* s, encoding=TEXT_ENCODING): + if s == NULL: + return None + else: + return s + + +cdef force_str(object s, encoding=TEXT_ENCODING): + """Return s converted to str type of current Python + (bytes in Py2, unicode in Py3)""" + if s is None: + return None + if PY_MAJOR_VERSION < 3: + return s + elif PyBytes_Check(s): + return s.decode(encoding) + else: + # assume unicode + return s + diff --git a/autowrap/data_files/autowrap/smart_ptr.pxd b/autowrap/data_files/autowrap/smart_ptr.pxd index 167272b4..9aa7233e 100644 --- a/autowrap/data_files/autowrap/smart_ptr.pxd +++ b/autowrap/data_files/autowrap/smart_ptr.pxd @@ -4,7 +4,11 @@ cdef extern from "boost/smart_ptr/shared_ptr.hpp" namespace "boost": cdef cppclass shared_ptr[T]: shared_ptr() shared_ptr(T*) + void swap(shared_ptr&) void reset() T* get() nogil int unique() int use_count() + +cdef extern from "boost/smart_ptr/make_shared.hpp" namespace "boost": + shared_ptr[T] make_shared[T](...) except + \ No newline at end of file diff --git a/autowrap/data_files/boost/move/adl_move_swap.hpp b/autowrap/data_files/boost/move/adl_move_swap.hpp new file mode 100644 index 00000000..d9096e36 --- /dev/null +++ b/autowrap/data_files/boost/move/adl_move_swap.hpp @@ -0,0 +1,272 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker +// (C) Copyright Ion Gaztanaga 2005-2013. 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_MOVE_ADL_MOVE_SWAP_HPP +#define BOOST_MOVE_ADL_MOVE_SWAP_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//Based on Boost.Core's swap. +//Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker. +#include //for std::size_t +#include //forceinline + +//Try to avoid including , as it's quite big +#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB) + #include //Dinkum libraries define std::swap in utility which is lighter than algorithm +#elif defined(BOOST_GNU_STDLIB) + //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions + //use the good old stl_algobase header, which is quite lightweight + #if !defined(BOOST_GCC) || ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3))) + #include + #elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) + //In GCC 4.3 a tiny stl_move.h was created with swap and move utilities + #include + #else + //In GCC 4.4 stl_move.h was renamed to move.h + #include + #endif +#elif defined(_LIBCPP_VERSION) + #include //The initial import of libc++ defines std::swap and still there +#elif __cplusplus >= 201103L + #include //Fallback for C++ >= 2011 +#else + #include //Fallback for C++98/03 +#endif + +#include //for boost::move + +#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +namespace boost_move_member_swap { + +struct dont_care +{ + dont_care(...); +}; + +struct private_type +{ + static private_type p; + private_type const &operator,(int) const; +}; + +typedef char yes_type; +struct no_type{ char dummy[2]; }; + +template +no_type is_private_type(T const &); + +yes_type is_private_type(private_type const &); + +template +class has_member_function_named_swap +{ + struct BaseMixin + { + void swap(); + }; + + struct Base : public Type, public BaseMixin { Base(); }; + template class Helper{}; + + template + static no_type deduce(U*, Helper* = 0); + static yes_type deduce(...); + + public: + static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0))); +}; + +template +struct has_member_swap_impl +{ + static const bool value = false; +}; + +template +struct has_member_swap_impl +{ + struct FunWrap : Fun + { + FunWrap(); + + using Fun::swap; + private_type swap(dont_care) const; + }; + + static Fun &declval_fun(); + static FunWrap declval_wrap(); + + static bool const value = + sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) ); +}; + +template +struct has_member_swap : public has_member_swap_impl + ::value> +{}; + +} //namespace boost_move_member_swap + +namespace boost_move_adl_swap{ + +template +struct and_op_impl +{ static const bool value = false; }; + +template +struct and_op_impl +{ static const bool value = P2::value; }; + +template +struct and_op + : and_op_impl +{}; + +////// + +template +struct and_op_not_impl +{ static const bool value = false; }; + +template +struct and_op_not_impl +{ static const bool value = !P2::value; }; + +template +struct and_op_not + : and_op_not_impl +{}; + +template +BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c::value>::type* = 0) +{ + //use std::swap if argument dependent lookup fails + //Use using directive ("using namespace xxx;") instead as some older compilers + //don't do ADL with using declarations ("using ns::func;"). + using namespace std; + swap(x, y); +} + +template +BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y + , typename boost::move_detail::enable_if< and_op_not_impl + , boost_move_member_swap::has_member_swap > + >::type* = 0) +{ T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t); } + +template +BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y + , typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl + , boost_move_member_swap::has_member_swap > + >::type* = 0) +{ x.swap(y); } + +} //namespace boost_move_adl_swap{ + +#else + +namespace boost_move_adl_swap{ + +template +BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y) +{ + using std::swap; + swap(x, y); +} + +} //namespace boost_move_adl_swap{ + +#endif //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +namespace boost_move_adl_swap{ + +template +void swap_proxy(T (& x)[N], T (& y)[N]) +{ + for (std::size_t i = 0; i < N; ++i){ + ::boost_move_adl_swap::swap_proxy(x[i], y[i]); + } +} + +} //namespace boost_move_adl_swap { + +#endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED) + +namespace boost{ + +//! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a +//! specialized swap function if available. If no specialized swap function is available, +//! std::swap is used. +//! +//! Exception: If T uses Boost.Move's move emulation and the compiler has +//! no rvalue references then: +//! +//! - If T has a T::swap(T&) member, that member is called. +//! - Otherwise a move-based swap is called, equivalent to: +//! T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);. +template +BOOST_MOVE_FORCEINLINE void adl_move_swap(T& x, T& y) +{ + ::boost_move_adl_swap::swap_proxy(x, y); +} + +//! Exchanges elements between range [first1, last1) and another range starting at first2 +//! using boost::adl_move_swap. +//! +//! Parameters: +//! first1, last1 - the first range of elements to swap +//! first2 - beginning of the second range of elements to swap +//! +//! Type requirements: +//! - ForwardIt1, ForwardIt2 must meet the requirements of ForwardIterator. +//! - The types of dereferenced ForwardIt1 and ForwardIt2 must meet the +//! requirements of Swappable +//! +//! Return value: Iterator to the element past the last element exchanged in the range +//! beginning with first2. +template +ForwardIt2 adl_move_swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2) +{ + while (first1 != last1) { + ::boost::adl_move_swap(*first1, *first2); + ++first1; + ++first2; + } + return first2; +} + +template +BidirIt2 adl_move_swap_ranges_backward(BidirIt1 first1, BidirIt1 last1, BidirIt2 last2) +{ + while (first1 != last1) { + ::boost::adl_move_swap(*(--last1), *(--last2)); + } + return last2; +} + +template +void adl_move_iter_swap(ForwardIt1 a, ForwardIt2 b) +{ + boost::adl_move_swap(*a, *b); +} + +} //namespace boost{ + +#endif //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP diff --git a/autowrap/data_files/boost/move/algo/adaptive_merge.hpp b/autowrap/data_files/boost/move/algo/adaptive_merge.hpp new file mode 100644 index 00000000..21698433 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/adaptive_merge.hpp @@ -0,0 +1,352 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_ADAPTIVE_MERGE_HPP +#define BOOST_MOVE_ADAPTIVE_MERGE_HPP + +#include +#include + +namespace boost { +namespace movelib { + +///@cond +namespace detail_adaptive { + +template +inline void adaptive_merge_combine_blocks( RandIt first + , typename iterator_traits::size_type len1 + , typename iterator_traits::size_type len2 + , typename iterator_traits::size_type collected + , typename iterator_traits::size_type n_keys + , typename iterator_traits::size_type l_block + , bool use_internal_buf + , bool xbuf_used + , Compare comp + , XBuf & xbuf + ) +{ + typedef typename iterator_traits::size_type size_type; + size_type const len = len1+len2; + size_type const l_combine = len-collected; + size_type const l_combine1 = len1-collected; + + if(n_keys){ + RandIt const first_data = first+collected; + RandIt const keys = first; + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combine: ", len); + if(xbuf_used){ + if(xbuf.size() < l_block){ + xbuf.initialize_until(l_block, *first); + } + BOOST_ASSERT(xbuf.size() >= l_block); + size_type n_block_a, n_block_b, l_irreg1, l_irreg2; + combine_params( keys, comp, l_combine + , l_combine1, l_block, xbuf + , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs + op_merge_blocks_with_buf + (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, move_op(), xbuf.data()); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A mrg xbf: ", len); + } + else{ + size_type n_block_a, n_block_b, l_irreg1, l_irreg2; + combine_params( keys, comp, l_combine + , l_combine1, l_block, xbuf + , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs + if(use_internal_buf){ + op_merge_blocks_with_buf + (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, swap_op(), first_data-l_block); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A mrg buf: ", len); + } + else{ + merge_blocks_bufferless + (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A mrg nbf: ", len); + } + } + } + else{ + xbuf.shrink_to_fit(l_block); + if(xbuf.size() < l_block){ + xbuf.initialize_until(l_block, *first); + } + size_type *const uint_keys = xbuf.template aligned_trailing(l_block); + size_type n_block_a, n_block_b, l_irreg1, l_irreg2; + combine_params( uint_keys, less(), l_combine + , l_combine1, l_block, xbuf + , n_block_a, n_block_b, l_irreg1, l_irreg2, true); //Outputs + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combine: ", len); + BOOST_ASSERT(xbuf.size() >= l_block); + op_merge_blocks_with_buf + (uint_keys, less(), first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, move_op(), xbuf.data()); + xbuf.clear(); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A mrg buf: ", len); + } +} + +template +inline void adaptive_merge_final_merge( RandIt first + , typename iterator_traits::size_type len1 + , typename iterator_traits::size_type len2 + , typename iterator_traits::size_type collected + , typename iterator_traits::size_type l_intbuf + , typename iterator_traits::size_type l_block + , bool use_internal_buf + , bool xbuf_used + , Compare comp + , XBuf & xbuf + ) +{ + typedef typename iterator_traits::size_type size_type; + (void)l_block; + (void)use_internal_buf; + size_type n_keys = collected-l_intbuf; + size_type len = len1+len2; + if (!xbuf_used || n_keys) { + xbuf.clear(); + const size_type middle = xbuf_used && n_keys ? n_keys: collected; + unstable_sort(first, first + middle, comp, xbuf); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len); + stable_merge(first, first + middle, first + len, comp, xbuf); + } + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A fin mrg: ", len); +} + +template +inline static SizeType adaptive_merge_n_keys_without_external_keys(SizeType l_block, SizeType len1, SizeType len2, SizeType l_intbuf) +{ + typedef SizeType size_type; + //This is the minimum number of keys to implement the ideal algorithm + size_type n_keys = len1/l_block+len2/l_block; + const size_type second_half_blocks = len2/l_block; + const size_type first_half_aux = len1-l_intbuf; + while(n_keys >= ((first_half_aux-n_keys)/l_block + second_half_blocks)){ + --n_keys; + } + ++n_keys; + return n_keys; +} + +template +inline static SizeType adaptive_merge_n_keys_with_external_keys(SizeType l_block, SizeType len1, SizeType len2, SizeType l_intbuf) +{ + typedef SizeType size_type; + //This is the minimum number of keys to implement the ideal algorithm + size_type n_keys = (len1-l_intbuf)/l_block + len2/l_block; + return n_keys; +} + +template +inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1, SizeType len2, Xbuf & xbuf, SizeType &l_intbuf_inout) +{ + typedef SizeType size_type; + size_type l_block = rl_block; + size_type l_intbuf = xbuf.capacity() >= l_block ? 0u : l_block; + + if (xbuf.capacity() > l_block){ + l_block = xbuf.capacity(); + } + + //This is the minimum number of keys to implement the ideal algorithm + size_type n_keys = adaptive_merge_n_keys_without_external_keys(l_block, len1, len2, l_intbuf); + BOOST_ASSERT(n_keys >= ((len1-l_intbuf-n_keys)/l_block + len2/l_block)); + + if(xbuf.template supports_aligned_trailing + ( l_block + , adaptive_merge_n_keys_with_external_keys(l_block, len1, len2, l_intbuf))) + { + n_keys = 0u; + } + l_intbuf_inout = l_intbuf; + rl_block = l_block; + return n_keys; +} + +// Main explanation of the merge algorithm. +// +// csqrtlen = ceil(sqrt(len)); +// +// * First, csqrtlen [to be used as buffer] + (len/csqrtlen - 1) [to be used as keys] => to_collect +// unique elements are extracted from elements to be sorted and placed in the beginning of the range. +// +// * Step "combine_blocks": the leading (len1-to_collect) elements plus trailing len2 elements +// are merged with a non-trivial ("smart") algorithm to form an ordered range trailing "len-to_collect" elements. +// +// Explanation of the "combine_blocks" step: +// +// * Trailing [first+to_collect, first+len1) elements are divided in groups of cqrtlen elements. +// Remaining elements that can't form a group are grouped in front of those elements. +// * Trailing [first+len1, first+len1+len2) elements are divided in groups of cqrtlen elements. +// Remaining elements that can't form a group are grouped in the back of those elements. +// * In parallel the following two steps are performed: +// * Groups are selection-sorted by first or last element (depending whether they are going +// to be merged to left or right) and keys are reordered accordingly as an imitation-buffer. +// * Elements of each block pair are merged using the csqrtlen buffer taking into account +// if they belong to the first half or second half (marked by the key). +// +// * In the final merge step leading "to_collect" elements are merged with rotations +// with the rest of merged elements in the "combine_blocks" step. +// +// Corner cases: +// +// * If no "to_collect" elements can be extracted: +// +// * If more than a minimum number of elements is extracted +// then reduces the number of elements used as buffer and keys in the +// and "combine_blocks" steps. If "combine_blocks" has no enough keys due to this reduction +// then uses a rotation based smart merge. +// +// * If the minimum number of keys can't be extracted, a rotation-based merge is performed. +// +// * If auxiliary memory is more or equal than min(len1, len2), a buffered merge is performed. +// +// * If the len1 or len2 are less than 2*csqrtlen then a rotation-based merge is performed. +// +// * If auxiliary memory is more than csqrtlen+n_keys*sizeof(std::size_t), +// then no csqrtlen need to be extracted and "combine_blocks" will use integral +// keys to combine blocks. +template +void adaptive_merge_impl + ( RandIt first + , typename iterator_traits::size_type len1 + , typename iterator_traits::size_type len2 + , Compare comp + , XBuf & xbuf + ) +{ + typedef typename iterator_traits::size_type size_type; + + if(xbuf.capacity() >= min_value(len1, len2)){ + buffered_merge(first, first+len1, first+(len1+len2), comp, xbuf); + } + else{ + const size_type len = len1+len2; + //Calculate ideal parameters and try to collect needed unique keys + size_type l_block = size_type(ceil_sqrt(len)); + + //One range is not big enough to extract keys and the internal buffer so a + //rotation-based based merge will do just fine + if(len1 <= l_block*2 || len2 <= l_block*2){ + merge_bufferless(first, first+len1, first+len1+len2, comp); + return; + } + + //Detail the number of keys and internal buffer. If xbuf has enough memory, no + //internal buffer is needed so l_intbuf will remain 0. + size_type l_intbuf = 0; + size_type n_keys = adaptive_merge_n_keys_intbuf(l_block, len1, len2, xbuf, l_intbuf); + size_type const to_collect = l_intbuf+n_keys; + //Try to extract needed unique values from the first range + size_type const collected = collect_unique(first, first+len1, to_collect, comp, xbuf); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n A collect: ", len); + + //Not the minimum number of keys is not available on the first range, so fallback to rotations + if(collected != to_collect && collected < 4){ + merge_bufferless(first, first+collected, first+len1, comp); + merge_bufferless(first, first + len1, first + len1 + len2, comp); + return; + } + + //If not enough keys but more than minimum, adjust the internal buffer and key count + bool use_internal_buf = collected == to_collect; + if (!use_internal_buf){ + l_intbuf = 0u; + n_keys = collected; + l_block = lblock_for_combine(l_intbuf, n_keys, len, use_internal_buf); + //If use_internal_buf is false, then then internal buffer will be zero and rotation-based combination will be used + l_intbuf = use_internal_buf ? l_block : 0u; + } + + bool const xbuf_used = collected == to_collect && xbuf.capacity() >= l_block; + //Merge trailing elements using smart merges + adaptive_merge_combine_blocks(first, len1, len2, collected, n_keys, l_block, use_internal_buf, xbuf_used, comp, xbuf); + //Merge buffer and keys with the rest of the values + adaptive_merge_final_merge (first, len1, len2, collected, l_intbuf, l_block, use_internal_buf, xbuf_used, comp, xbuf); + } +} + +} //namespace detail_adaptive { + +///@endcond + +//! Effects: Merges two consecutive sorted ranges [first, middle) and [middle, last) +//! into one sorted range [first, last) according to the given comparison function comp. +//! The algorithm is stable (if there are equivalent elements in the original two ranges, +//! the elements from the first range (preserving their original order) precede the elements +//! from the second range (preserving their original order). +//! +//! Requires: +//! - RandIt must meet the requirements of ValueSwappable and RandomAccessIterator. +//! - The type of dereferenced RandIt must meet the requirements of MoveAssignable and MoveConstructible. +//! +//! Parameters: +//! - first: the beginning of the first sorted range. +//! - middle: the end of the first sorted range and the beginning of the second +//! - last: the end of the second sorted range +//! - comp: comparison function object which returns true if the first argument is is ordered before the second. +//! - uninitialized, uninitialized_len: raw storage starting on "uninitialized", able to hold "uninitialized_len" +//! elements of type iterator_traits::value_type. Maximum performance is achieved when uninitialized_len +//! is min(std::distance(first, middle), std::distance(middle, last)). +//! +//! Throws: If comp throws or the move constructor, move assignment or swap of the type +//! of dereferenced RandIt throws. +//! +//! Complexity: Always K x O(N) comparisons and move assignments/constructors/swaps. +//! Constant factor for comparisons and data movement is minimized when uninitialized_len +//! is min(std::distance(first, middle), std::distance(middle, last)). +//! Pretty good enough performance is achieved when uninitialized_len is +//! ceil(sqrt(std::distance(first, last)))*2. +//! +//! Caution: Experimental implementation, not production-ready. +template +void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp + , typename iterator_traits::value_type* uninitialized = 0 + , typename iterator_traits::size_type uninitialized_len = 0) +{ + typedef typename iterator_traits::size_type size_type; + typedef typename iterator_traits::value_type value_type; + + if (first == middle || middle == last){ + return; + } + + //Reduce ranges to merge if possible + do { + if (comp(*middle, *first)){ + break; + } + ++first; + if (first == middle) + return; + } while(1); + + RandIt first_high(middle); + --first_high; + do { + --last; + if (comp(*last, *first_high)){ + ++last; + break; + } + if (last == middle) + return; + } while(1); + + ::boost::movelib::adaptive_xbuf xbuf(uninitialized, size_type(uninitialized_len)); + ::boost::movelib::detail_adaptive::adaptive_merge_impl(first, size_type(middle - first), size_type(last - middle), comp, xbuf); +} + +} //namespace movelib { +} //namespace boost { + +#include + +#endif //#define BOOST_MOVE_ADAPTIVE_MERGE_HPP diff --git a/autowrap/data_files/boost/move/algo/adaptive_sort.hpp b/autowrap/data_files/boost/move/algo/adaptive_sort.hpp new file mode 100644 index 00000000..cdffa2e9 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/adaptive_sort.hpp @@ -0,0 +1,637 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_ADAPTIVE_SORT_HPP +#define BOOST_MOVE_ADAPTIVE_SORT_HPP + +#include +#include + +namespace boost { +namespace movelib { + +///@cond +namespace detail_adaptive { + +template +void move_data_backward( RandIt cur_pos + , typename iterator_traits::size_type const l_data + , RandIt new_pos + , bool const xbuf_used) +{ + //Move buffer to the total combination right + if(xbuf_used){ + boost::move_backward(cur_pos, cur_pos+l_data, new_pos+l_data); + } + else{ + boost::adl_move_swap_ranges_backward(cur_pos, cur_pos+l_data, new_pos+l_data); + //Rotate does less moves but it seems slower due to cache issues + //rotate_gcd(first-l_block, first+len-l_block, first+len); + } +} + +template +void move_data_forward( RandIt cur_pos + , typename iterator_traits::size_type const l_data + , RandIt new_pos + , bool const xbuf_used) +{ + //Move buffer to the total combination right + if(xbuf_used){ + boost::move(cur_pos, cur_pos+l_data, new_pos); + } + else{ + boost::adl_move_swap_ranges(cur_pos, cur_pos+l_data, new_pos); + //Rotate does less moves but it seems slower due to cache issues + //rotate_gcd(first-l_block, first+len-l_block, first+len); + } +} + +// build blocks of length 2*l_build_buf. l_build_buf is power of two +// input: [0, l_build_buf) elements are buffer, rest unsorted elements +// output: [0, l_build_buf) elements are buffer, blocks 2*l_build_buf and last subblock sorted +// +// First elements are merged from right to left until elements start +// at first. All old elements [first, first + l_build_buf) are placed at the end +// [first+len-l_build_buf, first+len). To achieve this: +// - If we have external memory to merge, we save elements from the buffer +// so that a non-swapping merge is used. Buffer elements are restored +// at the end of the buffer from the external memory. +// +// - When the external memory is not available or it is insufficient +// for a merge operation, left swap merging is used. +// +// Once elements are merged left to right in blocks of l_build_buf, then a single left +// to right merge step is performed to achieve merged blocks of size 2K. +// If external memory is available, usual merge is used, swap merging otherwise. +// +// As a last step, if auxiliary memory is available in-place merge is performed. +// until all is merged or auxiliary memory is not large enough. +template +typename iterator_traits::size_type + adaptive_sort_build_blocks + ( RandIt const first + , typename iterator_traits::size_type const len + , typename iterator_traits::size_type const l_base + , typename iterator_traits::size_type const l_build_buf + , XBuf & xbuf + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + BOOST_ASSERT(l_build_buf <= len); + BOOST_ASSERT(0 == ((l_build_buf / l_base)&(l_build_buf/l_base-1))); + + //Place the start pointer after the buffer + RandIt first_block = first + l_build_buf; + size_type const elements_in_blocks = len - l_build_buf; + + ////////////////////////////////// + // Start of merge to left step + ////////////////////////////////// + size_type l_merged = 0u; + + BOOST_ASSERT(l_build_buf); + //If there is no enough buffer for the insertion sort step, just avoid the external buffer + size_type kbuf = min_value(l_build_buf, size_type(xbuf.capacity())); + kbuf = kbuf < l_base ? 0 : kbuf; + + if(kbuf){ + //Backup internal buffer values in external buffer so they can be overwritten + xbuf.move_assign(first+l_build_buf-kbuf, kbuf); + l_merged = op_insertion_sort_step_left(first_block, elements_in_blocks, l_base, comp, move_op()); + + //Now combine them using the buffer. Elements from buffer can be + //overwritten since they've been saved to xbuf + l_merged = op_merge_left_step_multiple + ( first_block - l_merged, elements_in_blocks, l_merged, l_build_buf, kbuf - l_merged, comp, move_op()); + + //Restore internal buffer from external buffer unless kbuf was l_build_buf, + //in that case restoration will happen later + if(kbuf != l_build_buf){ + boost::move(xbuf.data()+kbuf-l_merged, xbuf.data() + kbuf, first_block-l_merged+elements_in_blocks); + } + } + else{ + l_merged = insertion_sort_step(first_block, elements_in_blocks, l_base, comp); + rotate_gcd(first_block - l_merged, first_block, first_block+elements_in_blocks); + } + + //Now combine elements using the buffer. Elements from buffer can't be + //overwritten since xbuf was not big enough, so merge swapping elements. + l_merged = op_merge_left_step_multiple + (first_block - l_merged, elements_in_blocks, l_merged, l_build_buf, l_build_buf - l_merged, comp, swap_op()); + + BOOST_ASSERT(l_merged == l_build_buf); + + ////////////////////////////////// + // Start of merge to right step + ////////////////////////////////// + + //If kbuf is l_build_buf then we can merge right without swapping + //Saved data is still in xbuf + if(kbuf && kbuf == l_build_buf){ + op_merge_right_step_once(first, elements_in_blocks, l_build_buf, comp, move_op()); + //Restore internal buffer from external buffer if kbuf was l_build_buf. + //as this operation was previously delayed. + boost::move(xbuf.data(), xbuf.data() + kbuf, first); + } + else{ + op_merge_right_step_once(first, elements_in_blocks, l_build_buf, comp, swap_op()); + } + xbuf.clear(); + //2*l_build_buf or total already merged + return min_value(elements_in_blocks, 2*l_build_buf); +} + +template +void adaptive_sort_combine_blocks + ( RandItKeys const keys + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const len + , typename iterator_traits::size_type const l_prev_merged + , typename iterator_traits::size_type const l_block + , bool const use_buf + , bool const xbuf_used + , XBuf & xbuf + , Compare comp + , bool merge_left) +{ + (void)xbuf; + typedef typename iterator_traits::size_type size_type; + + size_type const l_reg_combined = 2*l_prev_merged; + size_type l_irreg_combined = 0; + size_type const l_total_combined = calculate_total_combined(len, l_prev_merged, &l_irreg_combined); + size_type const n_reg_combined = len/l_reg_combined; + RandIt combined_first = first; + + (void)l_total_combined; + BOOST_ASSERT(l_total_combined <= len); + + size_type const max_i = n_reg_combined + (l_irreg_combined != 0); + + if(merge_left || !use_buf) { + for( size_type combined_i = 0; combined_i != max_i; ) { + //Now merge blocks + bool const is_last = combined_i==n_reg_combined; + size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined; + + range_xbuf rbuf( (use_buf && xbuf_used) ? (combined_first-l_block) : combined_first, combined_first); + size_type n_block_a, n_block_b, l_irreg1, l_irreg2; + combine_params( keys, key_comp, l_cur_combined + , l_prev_merged, l_block, rbuf + , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combpar: ", len + l_block); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(combined_first, combined_first + n_block_a*l_block+l_irreg1, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(combined_first + n_block_a*l_block+l_irreg1, combined_first + n_block_a*l_block+l_irreg1+n_block_b*l_block+l_irreg2, comp)); + if(!use_buf){ + merge_blocks_bufferless + (keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp); + } + else{ + merge_blocks_left + (keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp, xbuf_used); + } + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After merge_blocks_L: ", len + l_block); + ++combined_i; + if(combined_i != max_i) + combined_first += l_reg_combined; + } + } + else{ + combined_first += l_reg_combined*(max_i-1); + for( size_type combined_i = max_i; combined_i; ) { + --combined_i; + bool const is_last = combined_i==n_reg_combined; + size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined; + + RandIt const combined_last(combined_first+l_cur_combined); + range_xbuf rbuf(combined_last, xbuf_used ? (combined_last+l_block) : combined_last); + size_type n_block_a, n_block_b, l_irreg1, l_irreg2; + combine_params( keys, key_comp, l_cur_combined + , l_prev_merged, l_block, rbuf + , n_block_a, n_block_b, l_irreg1, l_irreg2); //Outputs + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A combpar: ", len + l_block); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(combined_first, combined_first + n_block_a*l_block+l_irreg1, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(combined_first + n_block_a*l_block+l_irreg1, combined_first + n_block_a*l_block+l_irreg1+n_block_b*l_block+l_irreg2, comp)); + merge_blocks_right + (keys, key_comp, combined_first, l_block, n_block_a, n_block_b, l_irreg2, comp, xbuf_used); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After merge_blocks_R: ", len + l_block); + if(combined_i) + combined_first -= l_reg_combined; + } + } +} + +//Returns true if buffer is placed in +//[buffer+len-l_intbuf, buffer+len). Otherwise, buffer is +//[buffer,buffer+l_intbuf) +template +bool adaptive_sort_combine_all_blocks + ( RandIt keys + , typename iterator_traits::size_type &n_keys + , RandIt const buffer + , typename iterator_traits::size_type const l_buf_plus_data + , typename iterator_traits::size_type l_merged + , typename iterator_traits::size_type &l_intbuf + , XBuf & xbuf + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + RandIt const first = buffer + l_intbuf; + size_type const l_data = l_buf_plus_data - l_intbuf; + size_type const l_unique = l_intbuf+n_keys; + //Backup data to external buffer once if possible + bool const common_xbuf = l_data > l_merged && l_intbuf && l_intbuf <= xbuf.capacity(); + if(common_xbuf){ + xbuf.move_assign(buffer, l_intbuf); + } + + bool prev_merge_left = true; + size_type l_prev_total_combined = l_merged, l_prev_block = 0; + bool prev_use_internal_buf = true; + + for( size_type n = 0; l_data > l_merged + ; l_merged*=2 + , ++n){ + //If l_intbuf is non-zero, use that internal buffer. + // Implies l_block == l_intbuf && use_internal_buf == true + //If l_intbuf is zero, see if half keys can be reused as a reduced emergency buffer, + // Implies l_block == n_keys/2 && use_internal_buf == true + //Otherwise, just give up and and use all keys to merge using rotations (use_internal_buf = false) + bool use_internal_buf = false; + size_type const l_block = lblock_for_combine(l_intbuf, n_keys, size_type(2*l_merged), use_internal_buf); + BOOST_ASSERT(!l_intbuf || (l_block == l_intbuf)); + BOOST_ASSERT(n == 0 || (!use_internal_buf || prev_use_internal_buf) ); + BOOST_ASSERT(n == 0 || (!use_internal_buf || l_prev_block == l_block) ); + + bool const is_merge_left = (n&1) == 0; + size_type const l_total_combined = calculate_total_combined(l_data, l_merged); + if(n && prev_use_internal_buf && prev_merge_left){ + if(is_merge_left || !use_internal_buf){ + move_data_backward(first-l_prev_block, l_prev_total_combined, first, common_xbuf); + } + else{ + //Put the buffer just after l_total_combined + RandIt const buf_end = first+l_prev_total_combined; + RandIt const buf_beg = buf_end-l_block; + if(l_prev_total_combined > l_total_combined){ + size_type const l_diff = l_prev_total_combined - l_total_combined; + move_data_backward(buf_beg-l_diff, l_diff, buf_end-l_diff, common_xbuf); + } + else if(l_prev_total_combined < l_total_combined){ + size_type const l_diff = l_total_combined - l_prev_total_combined; + move_data_forward(buf_end, l_diff, buf_beg, common_xbuf); + } + } + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" After move_data : ", l_data + l_intbuf); + } + + //Combine to form l_merged*2 segments + if(n_keys){ + size_type upper_n_keys_this_iter = 2*l_merged/l_block; + if(upper_n_keys_this_iter > 256){ + adaptive_sort_combine_blocks + ( keys, comp, !use_internal_buf || is_merge_left ? first : first-l_block + , l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left); + } + else{ + unsigned char uint_keys[256]; + adaptive_sort_combine_blocks + ( uint_keys, less(), !use_internal_buf || is_merge_left ? first : first-l_block + , l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left); + } + } + else{ + size_type *const uint_keys = xbuf.template aligned_trailing(); + adaptive_sort_combine_blocks + ( uint_keys, less(), !use_internal_buf || is_merge_left ? first : first-l_block + , l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left); + } + + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(is_merge_left ? " After comb blocks L: " : " After comb blocks R: ", l_data + l_intbuf); + prev_merge_left = is_merge_left; + l_prev_total_combined = l_total_combined; + l_prev_block = l_block; + prev_use_internal_buf = use_internal_buf; + } + BOOST_ASSERT(l_prev_total_combined == l_data); + bool const buffer_right = prev_use_internal_buf && prev_merge_left; + + l_intbuf = prev_use_internal_buf ? l_prev_block : 0u; + n_keys = l_unique - l_intbuf; + //Restore data from to external common buffer if used + if(common_xbuf){ + if(buffer_right){ + boost::move(xbuf.data(), xbuf.data() + l_intbuf, buffer+l_data); + } + else{ + boost::move(xbuf.data(), xbuf.data() + l_intbuf, buffer); + } + } + return buffer_right; +} + + +template +void adaptive_sort_final_merge( bool buffer_right + , RandIt const first + , typename iterator_traits::size_type const l_intbuf + , typename iterator_traits::size_type const n_keys + , typename iterator_traits::size_type const len + , XBuf & xbuf + , Compare comp) +{ + //BOOST_ASSERT(n_keys || xbuf.size() == l_intbuf); + xbuf.clear(); + + typedef typename iterator_traits::size_type size_type; + size_type const n_key_plus_buf = l_intbuf+n_keys; + if(buffer_right){ + //Use stable sort as some buffer elements might not be unique (see non_unique_buf) + stable_sort(first+len-l_intbuf, first+len, comp, xbuf); + stable_merge(first+n_keys, first+len-l_intbuf, first+len, antistable(comp), xbuf); + unstable_sort(first, first+n_keys, comp, xbuf); + stable_merge(first, first+n_keys, first+len, comp, xbuf); + } + else{ + //Use stable sort as some buffer elements might not be unique (see non_unique_buf) + stable_sort(first, first+n_key_plus_buf, comp, xbuf); + if(xbuf.capacity() >= n_key_plus_buf){ + buffered_merge(first, first+n_key_plus_buf, first+len, comp, xbuf); + } + else if(xbuf.capacity() >= min_value(l_intbuf, n_keys)){ + stable_merge(first+n_keys, first+n_key_plus_buf, first+len, comp, xbuf); + stable_merge(first, first+n_keys, first+len, comp, xbuf); + } + else{ + stable_merge(first, first+n_key_plus_buf, first+len, comp, xbuf); + } + } + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" After final_merge : ", len); +} + +template +bool adaptive_sort_build_params + (RandIt first, Unsigned const len, Compare comp + , Unsigned &n_keys, Unsigned &l_intbuf, Unsigned &l_base, Unsigned &l_build_buf + , XBuf & xbuf + ) +{ + typedef Unsigned size_type; + + //Calculate ideal parameters and try to collect needed unique keys + l_base = 0u; + + //Try to find a value near sqrt(len) that is 2^N*l_base where + //l_base <= AdaptiveSortInsertionSortThreshold. This property is important + //as build_blocks merges to the left iteratively duplicating the + //merged size and all the buffer must be used just before the final + //merge to right step. This guarantees "build_blocks" produces + //segments of size l_build_buf*2, maximizing the classic merge phase. + l_intbuf = size_type(ceil_sqrt_multiple(len, &l_base)); + + //The internal buffer can be expanded if there is enough external memory + while(xbuf.capacity() >= l_intbuf*2){ + l_intbuf *= 2; + } + + //This is the minimum number of keys to implement the ideal algorithm + // + //l_intbuf is used as buffer plus the key count + size_type n_min_ideal_keys = l_intbuf-1; + while(n_min_ideal_keys >= (len-l_intbuf-n_min_ideal_keys)/l_intbuf){ + --n_min_ideal_keys; + } + n_min_ideal_keys += 1; + BOOST_ASSERT(n_min_ideal_keys <= l_intbuf); + + if(xbuf.template supports_aligned_trailing(l_intbuf, (len-l_intbuf-1)/l_intbuf+1)){ + n_keys = 0u; + l_build_buf = l_intbuf; + } + else{ + //Try to achieve a l_build_buf of length l_intbuf*2, so that we can merge with that + //l_intbuf*2 buffer in "build_blocks" and use half of them as buffer and the other half + //as keys in combine_all_blocks. In that case n_keys >= n_min_ideal_keys but by a small margin. + // + //If available memory is 2*sqrt(l), then only sqrt(l) unique keys are needed, + //(to be used for keys in combine_all_blocks) as the whole l_build_buf + //will be backuped in the buffer during build_blocks. + bool const non_unique_buf = xbuf.capacity() >= l_intbuf; + size_type const to_collect = non_unique_buf ? n_min_ideal_keys : l_intbuf*2; + size_type collected = collect_unique(first, first+len, to_collect, comp, xbuf); + + //If available memory is 2*sqrt(l), then for "build_params" + //the situation is the same as if 2*l_intbuf were collected. + if(non_unique_buf && collected == n_min_ideal_keys){ + l_build_buf = l_intbuf; + n_keys = n_min_ideal_keys; + } + else if(collected == 2*l_intbuf){ + //l_intbuf*2 elements found. Use all of them in the build phase + l_build_buf = l_intbuf*2; + n_keys = l_intbuf; + } + else if(collected == (n_min_ideal_keys+l_intbuf)){ + l_build_buf = l_intbuf; + n_keys = n_min_ideal_keys; + } + //If collected keys are not enough, try to fix n_keys and l_intbuf. If no fix + //is possible (due to very low unique keys), then go to a slow sort based on rotations. + else{ + BOOST_ASSERT(collected < (n_min_ideal_keys+l_intbuf)); + if(collected < 4){ //No combination possible with less that 4 keys + return false; + } + n_keys = l_intbuf; + while(n_keys&(n_keys-1)){ + n_keys &= n_keys-1; // make it power or 2 + } + while(n_keys > collected){ + n_keys/=2; + } + //AdaptiveSortInsertionSortThreshold is always power of two so the minimum is power of two + l_base = min_value(n_keys, AdaptiveSortInsertionSortThreshold); + l_intbuf = 0; + l_build_buf = n_keys; + } + BOOST_ASSERT((n_keys+l_intbuf) >= l_build_buf); + } + + return true; +} + +// Main explanation of the sort algorithm. +// +// csqrtlen = ceil(sqrt(len)); +// +// * First, 2*csqrtlen unique elements elements are extracted from elements to be +// sorted and placed in the beginning of the range. +// +// * Step "build_blocks": In this nearly-classic merge step, 2*csqrtlen unique elements +// will be used as auxiliary memory, so trailing len-2*csqrtlen elements are +// are grouped in blocks of sorted 4*csqrtlen elements. At the end of the step +// 2*csqrtlen unique elements are again the leading elements of the whole range. +// +// * Step "combine_blocks": pairs of previously formed blocks are merged with a different +// ("smart") algorithm to form blocks of 8*csqrtlen elements. This step is slower than the +// "build_blocks" step and repeated iteratively (forming blocks of 16*csqrtlen, 32*csqrtlen +// elements, etc) of until all trailing (len-2*csqrtlen) elements are merged. +// +// In "combine_blocks" len/csqrtlen elements used are as "keys" (markers) to +// know if elements belong to the first or second block to be merged and another +// leading csqrtlen elements are used as buffer. Explanation of the "combine_blocks" step: +// +// Iteratively until all trailing (len-2*csqrtlen) elements are merged: +// Iteratively for each pair of previously merged block: +// * Blocks are divided groups of csqrtlen elements and +// 2*merged_block/csqrtlen keys are sorted to be used as markers +// * Groups are selection-sorted by first or last element (depending whether they are going +// to be merged to left or right) and keys are reordered accordingly as an imitation-buffer. +// * Elements of each block pair are merged using the csqrtlen buffer taking into account +// if they belong to the first half or second half (marked by the key). +// +// * In the final merge step leading elements (2*csqrtlen) are sorted and merged with +// rotations with the rest of sorted elements in the "combine_blocks" step. +// +// Corner cases: +// +// * If no 2*csqrtlen elements can be extracted: +// +// * If csqrtlen+len/csqrtlen are extracted, then only csqrtlen elements are used +// as buffer in the "build_blocks" step forming blocks of 2*csqrtlen elements. This +// means that an additional "combine_blocks" step will be needed to merge all elements. +// +// * If no csqrtlen+len/csqrtlen elements can be extracted, but still more than a minimum, +// then reduces the number of elements used as buffer and keys in the "build_blocks" +// and "combine_blocks" steps. If "combine_blocks" has no enough keys due to this reduction +// then uses a rotation based smart merge. +// +// * If the minimum number of keys can't be extracted, a rotation-based sorting is performed. +// +// * If auxiliary memory is more or equal than ceil(len/2), half-copying mergesort is used. +// +// * If auxiliary memory is more than csqrtlen+n_keys*sizeof(std::size_t), +// then only csqrtlen elements need to be extracted and "combine_blocks" will use integral +// keys to combine blocks. +// +// * If auxiliary memory is available, the "build_blocks" will be extended to build bigger blocks +// using classic merge and "combine_blocks" will use bigger blocks when merging. +template +void adaptive_sort_impl + ( RandIt first + , typename iterator_traits::size_type const len + , Compare comp + , XBuf & xbuf + ) +{ + typedef typename iterator_traits::size_type size_type; + + //Small sorts go directly to insertion sort + if(len <= size_type(AdaptiveSortInsertionSortThreshold)){ + insertion_sort(first, first + len, comp); + } + else if((len-len/2) <= xbuf.capacity()){ + merge_sort(first, first+len, comp, xbuf.data()); + } + else{ + //Make sure it is at least four + BOOST_STATIC_ASSERT(AdaptiveSortInsertionSortThreshold >= 4); + + size_type l_base = 0; + size_type l_intbuf = 0; + size_type n_keys = 0; + size_type l_build_buf = 0; + + //Calculate and extract needed unique elements. If a minimum is not achieved + //fallback to a slow stable sort + if(!adaptive_sort_build_params(first, len, comp, n_keys, l_intbuf, l_base, l_build_buf, xbuf)){ + stable_sort(first, first+len, comp, xbuf); + } + else{ + BOOST_ASSERT(l_build_buf); + //Otherwise, continue the adaptive_sort + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n After collect_unique: ", len); + size_type const n_key_plus_buf = l_intbuf+n_keys; + //l_build_buf is always power of two if l_intbuf is zero + BOOST_ASSERT(l_intbuf || (0 == (l_build_buf & (l_build_buf-1)))); + + //Classic merge sort until internal buffer and xbuf are exhausted + size_type const l_merged = adaptive_sort_build_blocks + (first+n_key_plus_buf-l_build_buf, len-n_key_plus_buf+l_build_buf, l_base, l_build_buf, xbuf, comp); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" After build_blocks: ", len); + + //Non-trivial merge + bool const buffer_right = adaptive_sort_combine_all_blocks + (first, n_keys, first+n_keys, len-n_keys, l_merged, l_intbuf, xbuf, comp); + + //Sort keys and buffer and merge the whole sequence + adaptive_sort_final_merge(buffer_right, first, l_intbuf, n_keys, len, xbuf, comp); + } + } +} + +} //namespace detail_adaptive { + +///@endcond + +//! Effects: Sorts the elements in the range [first, last) in ascending order according +//! to comparison functor "comp". The sort is stable (order of equal elements +//! is guaranteed to be preserved). Performance is improved if additional raw storage is +//! provided. +//! +//! Requires: +//! - RandIt must meet the requirements of ValueSwappable and RandomAccessIterator. +//! - The type of dereferenced RandIt must meet the requirements of MoveAssignable and MoveConstructible. +//! +//! Parameters: +//! - first, last: the range of elements to sort +//! - comp: comparison function object which returns true if the first argument is is ordered before the second. +//! - uninitialized, uninitialized_len: raw storage starting on "uninitialized", able to hold "uninitialized_len" +//! elements of type iterator_traits::value_type. Maximum performance is achieved when uninitialized_len +//! is ceil(std::distance(first, last)/2). +//! +//! Throws: If comp throws or the move constructor, move assignment or swap of the type +//! of dereferenced RandIt throws. +//! +//! Complexity: Always K x O(Nxlog(N)) comparisons and move assignments/constructors/swaps. +//! Comparisons are close to minimum even with no additional memory. Constant factor for data movement is minimized +//! when uninitialized_len is ceil(std::distance(first, last)/2). Pretty good enough performance is achieved when +//! ceil(sqrt(std::distance(first, last)))*2. +//! +//! Caution: Experimental implementation, not production-ready. +template +void adaptive_sort( RandIt first, RandIt last, Compare comp + , RandRawIt uninitialized + , typename iterator_traits::size_type uninitialized_len) +{ + typedef typename iterator_traits::size_type size_type; + typedef typename iterator_traits::value_type value_type; + + ::boost::movelib::adaptive_xbuf xbuf(uninitialized, uninitialized_len); + ::boost::movelib::detail_adaptive::adaptive_sort_impl(first, size_type(last - first), comp, xbuf); +} + +template +void adaptive_sort( RandIt first, RandIt last, Compare comp) +{ + typedef typename iterator_traits::value_type value_type; + adaptive_sort(first, last, comp, (value_type*)0, 0u); +} + +} //namespace movelib { +} //namespace boost { + +#include + +#endif //#define BOOST_MOVE_ADAPTIVE_SORT_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/adaptive_sort_merge.hpp b/autowrap/data_files/boost/move/algo/detail/adaptive_sort_merge.hpp new file mode 100644 index 00000000..60ef24a3 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/adaptive_sort_merge.hpp @@ -0,0 +1,1475 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// Stable sorting that works in O(N*log(N)) worst time +// and uses O(1) extra memory +// +////////////////////////////////////////////////////////////////////////////// +// +// The main idea of the adaptive_sort algorithm was developed by Andrey Astrelin +// and explained in the article from the russian collaborative blog +// Habrahabr (http://habrahabr.ru/post/205290/). The algorithm is based on +// ideas from B-C. Huang and M. A. Langston explained in their article +// "Fast Stable Merging and Sorting in Constant Extra Space (1989-1992)" +// (http://comjnl.oxfordjournals.org/content/35/6/643.full.pdf). +// +// This implementation by Ion Gaztanaga uses previous ideas with additional changes: +// +// - Use of GCD-based rotation. +// - Non power of two buffer-sizes. +// - Tries to find sqrt(len)*2 unique keys, so that the merge sort +// phase can form up to sqrt(len)*4 segments if enough keys are found. +// - The merge-sort phase can take advantage of external memory to +// save some additional combination steps. +// - Combination phase: Blocks are selection sorted and merged in parallel. +// - The combination phase is performed alternating merge to left and merge +// to right phases minimizing swaps due to internal buffer repositioning. +// - When merging blocks special optimizations are made to avoid moving some +// elements twice. +// +// The adaptive_merge algorithm was developed by Ion Gaztanaga reusing some parts +// from the sorting algorithm and implementing an additional block merge algorithm +// without moving elements to left or right. +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP +#define BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL + #define BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL 1 +#endif + +#ifdef BOOST_MOVE_ADAPTIVE_SORT_STATS + #if BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL == 2 + #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) \ + print_stats(STR, L)\ + // + + #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L) \ + print_stats(STR, L)\ + // + #else + #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) \ + print_stats(STR, L)\ + // + + #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L) + #endif +#else + #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) + #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L) +#endif + +#ifdef BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS + #define BOOST_MOVE_ADAPTIVE_SORT_INVARIANT BOOST_ASSERT +#else + #define BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(L) +#endif + +namespace boost { +namespace movelib { + +#if defined(BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS) + +bool is_sorted(::order_perf_type *first, ::order_perf_type *last, ::order_type_less) +{ + if (first != last) { + const order_perf_type *next = first, *cur(first); + while (++next != last) { + if (!(cur->key < next->key || (cur->key == next->key && cur->val < next->val))) + return false; + cur = next; + } + } + return true; +} + +#endif //BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS + +namespace detail_adaptive { + +static const std::size_t AdaptiveSortInsertionSortThreshold = 16; +//static const std::size_t AdaptiveSortInsertionSortThreshold = 4; +BOOST_STATIC_ASSERT((AdaptiveSortInsertionSortThreshold&(AdaptiveSortInsertionSortThreshold-1)) == 0); + +#if defined BOOST_HAS_INTPTR_T + typedef ::boost::uintptr_t uintptr_t; +#else + typedef std::size_t uintptr_t; +#endif + +template +const T &min_value(const T &a, const T &b) +{ + return a < b ? a : b; +} + +template +const T &max_value(const T &a, const T &b) +{ + return a > b ? a : b; +} + +template +typename iterator_traits::size_type + count_if_with(ForwardIt first, ForwardIt last, Pred pred, const V &v) +{ + typedef typename iterator_traits::size_type size_type; + size_type count = 0; + while(first != last) { + count += static_cast(0 != pred(*first, v)); + ++first; + } + return count; +} + + +template +RandIt skip_until_merge + ( RandIt first1, RandIt const last1 + , const typename iterator_traits::value_type &next_key, Compare comp) +{ + while(first1 != last1 && !comp(next_key, *first1)){ + ++first1; + } + return first1; +} + + +template +void swap_and_update_key + ( RandItKeys const key_next + , RandItKeys const key_range2 + , RandItKeys &key_mid + , RandIt const begin + , RandIt const end + , RandIt const with) +{ + if(begin != with){ + ::boost::adl_move_swap_ranges(begin, end, with); + ::boost::adl_move_swap(*key_next, *key_range2); + if(key_next == key_mid){ + key_mid = key_range2; + } + else if(key_mid == key_range2){ + key_mid = key_next; + } + } +} + +template +void update_key +(RandItKeys const key_next + , RandItKeys const key_range2 + , RandItKeys &key_mid) +{ + if (key_next != key_range2) { + ::boost::adl_move_swap(*key_next, *key_range2); + if (key_next == key_mid) { + key_mid = key_range2; + } + else if (key_mid == key_range2) { + key_mid = key_next; + } + } +} + +template +RandIt2 buffer_and_update_key +(RandItKeys const key_next + , RandItKeys const key_range2 + , RandItKeys &key_mid + , RandIt begin + , RandIt end + , RandIt with + , RandIt2 buffer + , Op op) +{ + if (begin != with) { + while(begin != end) { + op(three_way_t(), begin++, with++, buffer++); + } + ::boost::adl_move_swap(*key_next, *key_range2); + if (key_next == key_mid) { + key_mid = key_range2; + } + else if (key_mid == key_range2) { + key_mid = key_next; + } + } + return buffer; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// MERGE BUFFERLESS +// +/////////////////////////////////////////////////////////////////////////////// + +// [first1, last1) merge [last1,last2) -> [first1,last2) +template +RandIt partial_merge_bufferless_impl + (RandIt first1, RandIt last1, RandIt const last2, bool *const pis_range1_A, Compare comp) +{ + if(last1 == last2){ + return first1; + } + bool const is_range1_A = *pis_range1_A; + if(first1 != last1 && comp(*last1, last1[-1])){ + do{ + RandIt const old_last1 = last1; + last1 = boost::movelib::lower_bound(last1, last2, *first1, comp); + first1 = rotate_gcd(first1, old_last1, last1);//old_last1 == last1 supported + if(last1 == last2){ + return first1; + } + do{ + ++first1; + } while(last1 != first1 && !comp(*last1, *first1) ); + } while(first1 != last1); + } + *pis_range1_A = !is_range1_A; + return last1; +} + +// [first1, last1) merge [last1,last2) -> [first1,last2) +template +RandIt partial_merge_bufferless + (RandIt first1, RandIt last1, RandIt const last2, bool *const pis_range1_A, Compare comp) +{ + return *pis_range1_A ? partial_merge_bufferless_impl(first1, last1, last2, pis_range1_A, comp) + : partial_merge_bufferless_impl(first1, last1, last2, pis_range1_A, antistable(comp)); +} + +template +static SizeType needed_keys_count(SizeType n_block_a, SizeType n_block_b) +{ + return n_block_a + n_block_b; +} + +template +typename iterator_traits::size_type + find_next_block + ( RandItKeys const key_first + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type const ix_first_block + , typename iterator_traits::size_type const ix_last_block + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::value_type key_type; + BOOST_ASSERT(ix_first_block <= ix_last_block); + size_type ix_min_block = 0u; + for (size_type szt_i = ix_first_block; szt_i < ix_last_block; ++szt_i) { + const value_type &min_val = first[ix_min_block*l_block]; + const value_type &cur_val = first[szt_i*l_block]; + const key_type &min_key = key_first[ix_min_block]; + const key_type &cur_key = key_first[szt_i]; + + bool const less_than_minimum = comp(cur_val, min_val) || + (!comp(min_val, cur_val) && key_comp(cur_key, min_key)); + + if (less_than_minimum) { + ix_min_block = szt_i; + } + } + return ix_min_block; +} + +template +void merge_blocks_bufferless + ( RandItKeys const key_first + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type const l_irreg1 + , typename iterator_traits::size_type const n_block_a + , typename iterator_traits::size_type const n_block_b + , typename iterator_traits::size_type const l_irreg2 + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count; + //BOOST_ASSERT(n_block_a || n_block_b); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a])); + + size_type n_bef_irreg2 = 0; + bool l_irreg_pos_count = true; + RandItKeys key_mid(key_first + n_block_a); + RandIt const first_irr2 = first + l_irreg1 + (n_block_a+n_block_b)*l_block; + RandIt const last_irr2 = first_irr2 + l_irreg2; + + { //Selection sort blocks + size_type n_block_left = n_block_b + n_block_a; + RandItKeys key_range2(key_first); + + size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; + size_type max_check = min_value(min_check+1, n_block_left); + for (RandIt f = first+l_irreg1; n_block_left; --n_block_left, ++key_range2, f += l_block, min_check -= min_check != 0, max_check -= max_check != 0) { + size_type const next_key_idx = find_next_block(key_range2, key_comp, f, l_block, min_check, max_check, comp); + RandItKeys const key_next(key_range2 + next_key_idx); + max_check = min_value(max_value(max_check, next_key_idx+size_type(2)), n_block_left); + + RandIt const first_min = f + next_key_idx*l_block; + + //Check if irregular b block should go here. + //If so, break to the special code handling the irregular block + if (l_irreg_pos_count && l_irreg2 && comp(*first_irr2, *first_min)){ + l_irreg_pos_count = false; + } + n_bef_irreg2 += l_irreg_pos_count; + + swap_and_update_key(key_next, key_range2, key_mid, f, f + l_block, first_min); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(f, f+l_block, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, first_min + l_block, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((f == (first+l_irreg1)) || !comp(*f, *(f-l_block))); + } + } + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first+l_irreg1+n_bef_irreg2*l_block, first_irr2, comp)); + + RandIt first1 = first; + RandIt last1 = first+l_irreg1; + RandItKeys const key_end (key_first+n_bef_irreg2); + bool is_range1_A = true; + + for(RandItKeys key_next = key_first; key_next != key_end; ++key_next){ + bool is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_next, *key_mid); + first1 = is_range1_A == is_range2_A + ? last1 : partial_merge_bufferless(first1, last1, last1 + l_block, &is_range1_A, comp); + last1 += l_block; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, first1, comp)); + } + + merge_bufferless(is_range1_A ? first1 : last1, first_irr2, last_irr2, comp); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last_irr2, comp)); +} + +// Complexity: 2*distance(first, last)+max_collected^2/2 +// +// Tries to collect at most n_keys unique elements from [first, last), +// in the begining of the range, and ordered according to comp +// +// Returns the number of collected keys +template +typename iterator_traits::size_type + collect_unique + ( RandIt const first, RandIt const last + , typename iterator_traits::size_type const max_collected, Compare comp + , XBuf & xbuf) +{ + typedef typename iterator_traits::size_type size_type; + size_type h = 0; + if(max_collected){ + ++h; // first key is always here + RandIt h0 = first; + RandIt u = first; ++u; + RandIt search_end = u; + + if(xbuf.capacity() >= max_collected){ + typename XBuf::iterator const ph0 = xbuf.add(first); + while(u != last && h < max_collected){ + typename XBuf::iterator const r = boost::movelib::lower_bound(ph0, xbuf.end(), *u, comp); + //If key not found add it to [h, h+h0) + if(r == xbuf.end() || comp(*u, *r) ){ + RandIt const new_h0 = boost::move(search_end, u, h0); + search_end = u; + ++search_end; + ++h; + xbuf.insert(r, u); + h0 = new_h0; + } + ++u; + } + boost::move_backward(first, h0, h0+h); + boost::move(xbuf.data(), xbuf.end(), first); + } + else{ + while(u != last && h < max_collected){ + RandIt const r = boost::movelib::lower_bound(h0, search_end, *u, comp); + //If key not found add it to [h, h+h0) + if(r == search_end || comp(*u, *r) ){ + RandIt const new_h0 = rotate_gcd(h0, search_end, u); + search_end = u; + ++search_end; + ++h; + rotate_gcd(r+(new_h0-h0), u, search_end); + h0 = new_h0; + } + ++u; + } + rotate_gcd(first, h0, h0+h); + } + } + return h; +} + +template +Unsigned floor_sqrt(Unsigned const n) +{ + Unsigned x = n; + Unsigned y = x/2 + (x&1); + while (y < x){ + x = y; + y = (x + n / x)/2; + } + return x; +} + +template +Unsigned ceil_sqrt(Unsigned const n) +{ + Unsigned r = floor_sqrt(n); + return r + Unsigned((n%r) != 0); +} + +template +Unsigned floor_merge_multiple(Unsigned const n, Unsigned &base, Unsigned &pow) +{ + Unsigned s = n; + Unsigned p = 0; + while(s > AdaptiveSortInsertionSortThreshold){ + s /= 2; + ++p; + } + base = s; + pow = p; + return s << p; +} + +template +Unsigned ceil_merge_multiple(Unsigned const n, Unsigned &base, Unsigned &pow) +{ + Unsigned fm = floor_merge_multiple(n, base, pow); + + if(fm != n){ + if(base < AdaptiveSortInsertionSortThreshold){ + ++base; + } + else{ + base = AdaptiveSortInsertionSortThreshold/2 + 1; + ++pow; + } + } + return base << pow; +} + +template +Unsigned ceil_sqrt_multiple(Unsigned const n, Unsigned *pbase = 0) +{ + Unsigned const r = ceil_sqrt(n); + Unsigned pow = 0; + Unsigned base = 0; + Unsigned const res = ceil_merge_multiple(r, base, pow); + if(pbase) *pbase = base; + return res; +} + +struct less +{ + template + bool operator()(const T &l, const T &r) + { return l < r; } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// MERGE BLOCKS +// +/////////////////////////////////////////////////////////////////////////////// + +//#define ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN + +#if defined ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN +template +void slow_stable_sort + ( RandIt const first, RandIt const last, Compare comp) +{ + boost::movelib::inplace_stable_sort(first, last, comp); +} + +#else //ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN + +template +void slow_stable_sort + ( RandIt const first, RandIt const last, Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + size_type L = size_type(last - first); + { //Use insertion sort to merge first elements + size_type m = 0; + while((L - m) > size_type(AdaptiveSortInsertionSortThreshold)){ + insertion_sort(first+m, first+m+size_type(AdaptiveSortInsertionSortThreshold), comp); + m += AdaptiveSortInsertionSortThreshold; + } + insertion_sort(first+m, last, comp); + } + + size_type h = AdaptiveSortInsertionSortThreshold; + for(bool do_merge = L > h; do_merge; h*=2){ + do_merge = (L - h) > h; + size_type p0 = 0; + if(do_merge){ + size_type const h_2 = 2*h; + while((L-p0) > h_2){ + merge_bufferless(first+p0, first+p0+h, first+p0+h_2, comp); + p0 += h_2; + } + } + if((L-p0) > h){ + merge_bufferless(first+p0, first+p0+h, last, comp); + } + } +} + +#endif //ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN + +//Returns new l_block and updates use_buf +template +Unsigned lblock_for_combine + (Unsigned const l_block, Unsigned const n_keys, Unsigned const l_data, bool &use_buf) +{ + BOOST_ASSERT(l_data > 1); + + //We need to guarantee lblock >= l_merged/(n_keys/2) keys for the combination. + //We have at least 4 keys guaranteed (which are the minimum to merge 2 ranges) + //If l_block != 0, then n_keys is already enough to merge all blocks in all + //phases as we've found all needed keys for that buffer and length before. + //If l_block == 0 then see if half keys can be used as buffer and the rest + //as keys guaranteeing that n_keys >= (2*l_merged)/lblock = + if(!l_block){ + //If l_block == 0 then n_keys is power of two + //(guaranteed by build_params(...)) + BOOST_ASSERT(n_keys >= 4); + //BOOST_ASSERT(0 == (n_keys &(n_keys-1))); + + //See if half keys are at least 4 and if half keys fulfill + Unsigned const new_buf = n_keys/2; + Unsigned const new_keys = n_keys-new_buf; + use_buf = new_keys >= 4 && new_keys >= l_data/new_buf; + if(use_buf){ + return new_buf; + } + else{ + return l_data/n_keys; + } + } + else{ + use_buf = true; + return l_block; + } +} + +template +void stable_sort( RandIt first, RandIt last, Compare comp, XBuf & xbuf) +{ + typedef typename iterator_traits::size_type size_type; + size_type const len = size_type(last - first); + size_type const half_len = len/2 + (len&1); + if(std::size_t(xbuf.capacity() - xbuf.size()) >= half_len) { + merge_sort(first, last, comp, xbuf.data()+xbuf.size()); + } + else{ + slow_stable_sort(first, last, comp); + } +} + +template +void unstable_sort( RandIt first, RandIt last + , Comp comp + , XBuf & xbuf) +{ + heap_sort(first, last, comp);(void)xbuf; +} + +template +void stable_merge + ( RandIt first, RandIt const middle, RandIt last + , Compare comp + , XBuf &xbuf) +{ + BOOST_ASSERT(xbuf.empty()); + typedef typename iterator_traits::size_type size_type; + size_type const len1 = size_type(middle-first); + size_type const len2 = size_type(last-middle); + size_type const l_min = min_value(len1, len2); + if(xbuf.capacity() >= l_min){ + buffered_merge(first, middle, last, comp, xbuf); + xbuf.clear(); + } + else{ + //merge_bufferless(first, middle, last, comp); + merge_adaptive_ONlogN(first, middle, last, comp, xbuf.begin(), xbuf.capacity()); + } + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last, boost::movelib::unantistable(comp))); +} + +template +void initialize_keys( RandIt first, RandIt last + , Comp comp + , XBuf & xbuf) +{ + unstable_sort(first, last, comp, xbuf); + BOOST_ASSERT(boost::movelib::is_sorted_and_unique(first, last, comp)); +} + +template +void initialize_keys( RandIt first, RandIt last + , less + , U &) +{ + typedef typename iterator_traits::value_type value_type; + std::size_t count = std::size_t(last - first); + for(std::size_t i = 0; i != count; ++i){ + *first = static_cast(i); + ++first; + } +} + +template +Unsigned calculate_total_combined(Unsigned const len, Unsigned const l_prev_merged, Unsigned *pl_irreg_combined = 0) +{ + typedef Unsigned size_type; + + size_type const l_combined = 2*l_prev_merged; + size_type l_irreg_combined = len%l_combined; + size_type l_total_combined = len; + if(l_irreg_combined <= l_prev_merged){ + l_total_combined -= l_irreg_combined; + l_irreg_combined = 0; + } + if(pl_irreg_combined) + *pl_irreg_combined = l_irreg_combined; + return l_total_combined; +} + +template +void combine_params + ( RandItKeys const keys + , KeyCompare key_comp + , SizeType l_combined + , SizeType const l_prev_merged + , SizeType const l_block + , XBuf & xbuf + //Output + , SizeType &n_block_a + , SizeType &n_block_b + , SizeType &l_irreg1 + , SizeType &l_irreg2 + //Options + , bool do_initialize_keys = true) +{ + typedef SizeType size_type; + + //Initial parameters for selection sort blocks + l_irreg1 = l_prev_merged%l_block; + l_irreg2 = (l_combined-l_irreg1)%l_block; + BOOST_ASSERT(((l_combined-l_irreg1-l_irreg2)%l_block) == 0); + size_type const n_reg_block = (l_combined-l_irreg1-l_irreg2)/l_block; + n_block_a = l_prev_merged/l_block; + n_block_b = n_reg_block - n_block_a; + BOOST_ASSERT(n_reg_block>=n_block_a); + + //Key initialization + if (do_initialize_keys) { + initialize_keys(keys, keys + needed_keys_count(n_block_a, n_block_b), key_comp, xbuf); + } +} + + + +////////////////////////////////// +// +// partial_merge +// +////////////////////////////////// +template +OutputIt op_partial_merge_impl + (InputIt1 &r_first1, InputIt1 const last1, InputIt2 &r_first2, InputIt2 const last2, OutputIt d_first, Compare comp, Op op) +{ + InputIt1 first1(r_first1); + InputIt2 first2(r_first2); + if(first2 != last2 && last1 != first1) + while(1){ + if(comp(*first2, *first1)) { + op(first2++, d_first++); + if(first2 == last2){ + break; + } + } + else{ + op(first1++, d_first++); + if(first1 == last1){ + break; + } + } + } + r_first1 = first1; + r_first2 = first2; + return d_first; +} + +template +OutputIt op_partial_merge + (InputIt1 &r_first1, InputIt1 const last1, InputIt2 &r_first2, InputIt2 const last2, OutputIt d_first, Compare comp, Op op, bool is_stable) +{ + return is_stable ? op_partial_merge_impl(r_first1, last1, r_first2, last2, d_first, comp, op) + : op_partial_merge_impl(r_first1, last1, r_first2, last2, d_first, antistable(comp), op); +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// op_partial_merge_and_save +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +template +OutputIt op_partial_merge_and_swap_impl + (InputIt1 &r_first1, InputIt1 const last1, InputIt2 &r_first2, InputIt2 const last2, InputIt2 &r_first_min, OutputIt d_first, Compare comp, Op op) +{ + InputIt1 first1(r_first1); + InputIt2 first2(r_first2); + + if(first2 != last2 && last1 != first1) { + InputIt2 first_min(r_first_min); + bool non_empty_ranges = true; + do{ + if(comp(*first_min, *first1)) { + op(three_way_t(), first2++, first_min++, d_first++); + non_empty_ranges = first2 != last2; + } + else{ + op(first1++, d_first++); + non_empty_ranges = first1 != last1; + } + } while(non_empty_ranges); + r_first_min = first_min; + r_first1 = first1; + r_first2 = first2; + } + return d_first; +} + +template +OutputIt op_partial_merge_and_swap + (RandIt &r_first1, RandIt const last1, InputIt2 &r_first2, InputIt2 const last2, InputIt2 &r_first_min, OutputIt d_first, Compare comp, Op op, bool is_stable) +{ + return is_stable ? op_partial_merge_and_swap_impl(r_first1, last1, r_first2, last2, r_first_min, d_first, comp, op) + : op_partial_merge_and_swap_impl(r_first1, last1, r_first2, last2, r_first_min, d_first, antistable(comp), op); +} + +template +RandItB op_buffered_partial_merge_and_swap_to_range1_and_buffer + ( RandIt1 first1, RandIt1 const last1 + , RandIt2 &rfirst2, RandIt2 const last2, RandIt2 &rfirst_min + , RandItB &rfirstb, Compare comp, Op op ) +{ + RandItB firstb = rfirstb; + RandItB lastb = firstb; + RandIt2 first2 = rfirst2; + + //Move to buffer while merging + //Three way moves need less moves when op is swap_op so use it + //when merging elements from range2 to the destination occupied by range1 + if(first1 != last1 && first2 != last2){ + RandIt2 first_min = rfirst_min; + op(four_way_t(), first2++, first_min++, first1++, lastb++); + + while(first1 != last1){ + if(first2 == last2){ + lastb = op(forward_t(), first1, last1, firstb); + break; + } + + if(comp(*first_min, *firstb)){ + op( four_way_t(), first2++, first_min++, first1++, lastb++); + } + else{ + op(three_way_t(), firstb++, first1++, lastb++); + } + } + rfirst2 = first2; + rfirstb = firstb; + rfirst_min = first_min; + } + + return lastb; +} + +template +RandItB op_buffered_partial_merge_to_range1_and_buffer + ( RandIt1 first1, RandIt1 const last1 + , RandIt2 &rfirst2, RandIt2 const last2 + , RandItB &rfirstb, Compare comp, Op op ) +{ + RandItB firstb = rfirstb; + RandItB lastb = firstb; + RandIt2 first2 = rfirst2; + + //Move to buffer while merging + //Three way moves need less moves when op is swap_op so use it + //when merging elements from range2 to the destination occupied by range1 + if(first1 != last1 && first2 != last2){ + op(three_way_t(), first2++, first1++, lastb++); + + while(true){ + if(first1 == last1){ + break; + } + if(first2 == last2){ + lastb = op(forward_t(), first1, last1, firstb); + break; + } + if (comp(*first2, *firstb)) { + op(three_way_t(), first2++, first1++, lastb++); + } + else { + op(three_way_t(), firstb++, first1++, lastb++); + } + } + rfirst2 = first2; + rfirstb = firstb; + } + + return lastb; +} + +template +RandIt op_partial_merge_and_save_impl + ( RandIt first1, RandIt const last1, RandIt &rfirst2, RandIt last2, RandIt first_min + , RandItBuf &buf_first1_in_out, RandItBuf &buf_last1_in_out + , Compare comp, Op op + ) +{ + RandItBuf buf_first1 = buf_first1_in_out; + RandItBuf buf_last1 = buf_last1_in_out; + RandIt first2(rfirst2); + + bool const do_swap = first2 != first_min; + if(buf_first1 == buf_last1){ + //Skip any element that does not need to be moved + RandIt new_first1 = skip_until_merge(first1, last1, *first_min, comp); + buf_first1 += (new_first1-first1); + first1 = new_first1; + buf_last1 = do_swap ? op_buffered_partial_merge_and_swap_to_range1_and_buffer(first1, last1, first2, last2, first_min, buf_first1, comp, op) + : op_buffered_partial_merge_to_range1_and_buffer (first1, last1, first2, last2, buf_first1, comp, op); + first1 = last1; + } + else{ + BOOST_ASSERT((last1-first1) == (buf_last1 - buf_first1)); + } + + //Now merge from buffer + first1 = do_swap ? op_partial_merge_and_swap_impl(buf_first1, buf_last1, first2, last2, first_min, first1, comp, op) + : op_partial_merge_impl (buf_first1, buf_last1, first2, last2, first1, comp, op); + buf_first1_in_out = buf_first1; + buf_last1_in_out = buf_last1; + rfirst2 = first2; + return first1; +} + +template +RandIt op_partial_merge_and_save + ( RandIt first1, RandIt const last1, RandIt &rfirst2, RandIt last2, RandIt first_min + , RandItBuf &buf_first1_in_out + , RandItBuf &buf_last1_in_out + , Compare comp + , Op op + , bool is_stable) +{ + return is_stable + ? op_partial_merge_and_save_impl + (first1, last1, rfirst2, last2, first_min, buf_first1_in_out, buf_last1_in_out, comp, op) + : op_partial_merge_and_save_impl + (first1, last1, rfirst2, last2, first_min, buf_first1_in_out, buf_last1_in_out, antistable(comp), op) + ; +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// op_merge_blocks_with_irreg +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// + +template +OutputIt op_merge_blocks_with_irreg + ( RandItKeys key_first + , RandItKeys key_mid + , KeyCompare key_comp + , RandIt first_reg + , RandIt2 &first_irr + , RandIt2 const last_irr + , OutputIt dest + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type n_block_left + , typename iterator_traits::size_type min_check + , typename iterator_traits::size_type max_check + , Compare comp, bool const is_stable, Op op) +{ + typedef typename iterator_traits::size_type size_type; + + for(; n_block_left; --n_block_left, ++key_first, min_check -= min_check != 0, max_check -= max_check != 0){ + size_type next_key_idx = find_next_block(key_first, key_comp, first_reg, l_block, min_check, max_check, comp); + max_check = min_value(max_value(max_check, next_key_idx+size_type(2)), n_block_left); + RandIt const last_reg = first_reg + l_block; + RandIt first_min = first_reg + next_key_idx*l_block; + RandIt const last_min = first_min + l_block; (void)last_min; + + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_reg, last_reg, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!next_key_idx || boost::movelib::is_sorted(first_min, last_min, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((!next_key_idx || !comp(*first_reg, *first_min ))); + + OutputIt orig_dest = dest; (void)orig_dest; + dest = next_key_idx ? op_partial_merge_and_swap(first_irr, last_irr, first_reg, last_reg, first_min, dest, comp, op, is_stable) + : op_partial_merge (first_irr, last_irr, first_reg, last_reg, dest, comp, op, is_stable); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(orig_dest, dest, comp)); + + if(first_reg == dest){ + dest = next_key_idx ? ::boost::adl_move_swap_ranges(first_min, last_min, first_reg) + : last_reg; + } + else{ + dest = next_key_idx ? op(three_way_forward_t(), first_reg, last_reg, first_min, dest) + : op(forward_t(), first_reg, last_reg, dest); + } + + RandItKeys const key_next(key_first + next_key_idx); + swap_and_update_key(key_next, key_first, key_mid, last_reg, last_reg, first_min); + + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(orig_dest, dest, comp)); + first_reg = last_reg; + } + return dest; +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// op_merge_blocks_left/right +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// + +template +void op_merge_blocks_left + ( RandItKeys const key_first + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type const l_irreg1 + , typename iterator_traits::size_type const n_block_a + , typename iterator_traits::size_type const n_block_b + , typename iterator_traits::size_type const l_irreg2 + , Compare comp, Op op) +{ + typedef typename iterator_traits::size_type size_type; + size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count; +// BOOST_ASSERT(n_block_a || n_block_b); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a])); + + size_type n_block_b_left = n_block_b; + size_type n_block_a_left = n_block_a; + size_type n_block_left = n_block_b + n_block_a; + RandItKeys key_mid(key_first + n_block_a); + + RandIt buffer = first - l_block; + RandIt first1 = first; + RandIt last1 = first1 + l_irreg1; + RandIt first2 = last1; + RandIt const irreg2 = first2 + n_block_left*l_block; + bool is_range1_A = true; + + RandItKeys key_range2(key_first); + + //////////////////////////////////////////////////////////////////////////// + //Process all regular blocks before the irregular B block + //////////////////////////////////////////////////////////////////////////// + size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; + size_type max_check = min_value(min_check+size_type(1), n_block_left); + for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) { + size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp); + max_check = min_value(max_value(max_check, next_key_idx+size_type(2)), n_block_left); + RandIt const first_min = first2 + next_key_idx*l_block; + RandIt const last_min = first_min + l_block; (void)last_min; + RandIt const last2 = first2 + l_block; + + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first1, last1, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || boost::movelib::is_sorted(first_min, last_min, comp)); + + //Check if irregular b block should go here. + //If so, break to the special code handling the irregular block + if (!n_block_b_left && + ( (l_irreg2 && comp(*irreg2, *first_min)) || (!l_irreg2 && is_range1_A)) ){ + break; + } + + RandItKeys const key_next(key_range2 + next_key_idx); + bool const is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_next, *key_mid); + + bool const is_buffer_middle = last1 == buffer; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT( ( is_buffer_middle && size_type(first2-buffer) == l_block && buffer == last1) || + (!is_buffer_middle && size_type(first1-buffer) == l_block && first2 == last1)); + + if(is_range1_A == is_range2_A){ + BOOST_ASSERT((first1 == last1) || !comp(*first_min, last1[-1])); + if(!is_buffer_middle){ + buffer = op(forward_t(), first1, last1, buffer); + } + swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + first1 = first2; + last1 = last2; + } + else { + RandIt unmerged; + RandIt buf_beg; + RandIt buf_end; + if(is_buffer_middle){ + buf_end = buf_beg = first2 - (last1-first1); + unmerged = op_partial_merge_and_save( first1, last1, first2, last2, first_min + , buf_beg, buf_end, comp, op, is_range1_A); + } + else{ + buf_beg = first1; + buf_end = last1; + unmerged = op_partial_merge_and_save + (buffer, buffer+(last1-first1), first2, last2, first_min, buf_beg, buf_end, comp, op, is_range1_A); + } + (void)unmerged; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, unmerged, comp)); + + swap_and_update_key( key_next, key_range2, key_mid, first2, last2 + , last_min - size_type(last2 - first2)); + + if(buf_beg != buf_end){ //range2 exhausted: is_buffer_middle for the next iteration + first1 = buf_beg; + last1 = buf_end; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buf_end == (last2-l_block)); + buffer = last1; + } + else{ //range1 exhausted: !is_buffer_middle for the next iteration + first1 = first2; + last1 = last2; + buffer = first2 - l_block; + is_range1_A = is_range2_A; + } + } + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left)); + is_range2_A ? --n_block_a_left : --n_block_b_left; + first2 = last2; + } + + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_range2 + n_block_left, key_comp, *key_mid)); + BOOST_ASSERT(!n_block_b_left); + + //////////////////////////////////////////////////////////////////////////// + //Process remaining range 1 left before the irregular B block + //////////////////////////////////////////////////////////////////////////// + bool const is_buffer_middle = last1 == buffer; + RandIt first_irr2 = irreg2; + RandIt const last_irr2 = first_irr2 + l_irreg2; + if(l_irreg2 && is_range1_A){ + if(is_buffer_middle){ + first1 = skip_until_merge(first1, last1, *first_irr2, comp); + //Even if we copy backward, no overlapping occurs so use forward copy + //that can be faster specially with trivial types + RandIt const new_first1 = first2 - (last1 - first1); + op(forward_t(), first1, last1, new_first1); + first1 = new_first1; + last1 = first2; + buffer = first1 - l_block; + } + buffer = op_partial_merge_impl(first1, last1, first_irr2, last_irr2, buffer, comp, op); + buffer = op(forward_t(), first1, last1, buffer); + } + else if(!is_buffer_middle){ + buffer = op(forward_t(), first1, last1, buffer); + } + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, buffer, comp)); + + //////////////////////////////////////////////////////////////////////////// + //Process irregular B block and remaining A blocks + //////////////////////////////////////////////////////////////////////////// + buffer = op_merge_blocks_with_irreg + ( key_range2, key_mid, key_comp, first2, first_irr2, last_irr2 + , buffer, l_block, n_block_left, min_check, max_check, comp, false, op); + buffer = op(forward_t(), first_irr2, last_irr2, buffer);(void)buffer; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first-l_block, buffer, comp)); +} + +// first - first element to merge. +// first[-l_block, 0) - buffer (if use_buf == true) +// l_block - length of regular blocks. First nblocks are stable sorted by 1st elements and key-coded +// keys - sequence of keys, in same order as blocks. key +void merge_blocks_left + ( RandItKeys const key_first + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type const l_irreg1 + , typename iterator_traits::size_type const n_block_a + , typename iterator_traits::size_type const n_block_b + , typename iterator_traits::size_type const l_irreg2 + , Compare comp + , bool const xbuf_used) +{ + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + needed_keys_count(n_block_a, n_block_b), key_comp, key_first[n_block_a])); + if(xbuf_used){ + op_merge_blocks_left + (key_first, key_comp, first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, move_op()); + } + else{ + op_merge_blocks_left + (key_first, key_comp, first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, swap_op()); + } +} + +// first - first element to merge. +// [first+l_block*(n_bef_irreg2+n_aft_irreg2)+l_irreg2, first+l_block*(n_bef_irreg2+n_aft_irreg2+1)+l_irreg2) - buffer +// l_block - length of regular blocks. First nblocks are stable sorted by 1st elements and key-coded +// keys - sequence of keys, in same order as blocks. key +void merge_blocks_right + ( RandItKeys const key_first + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type const n_block_a + , typename iterator_traits::size_type const n_block_b + , typename iterator_traits::size_type const l_irreg2 + , Compare comp + , bool const xbuf_used) +{ + merge_blocks_left + ( (make_reverse_iterator)(key_first + needed_keys_count(n_block_a, n_block_b)) + , inverse(key_comp) + , (make_reverse_iterator)(first + ((n_block_a+n_block_b)*l_block+l_irreg2)) + , l_block + , l_irreg2 + , n_block_b + , n_block_a + , 0 + , inverse(comp), xbuf_used); +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// op_merge_blocks_with_buf +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +template +void op_merge_blocks_with_buf + ( RandItKeys key_first + , KeyCompare key_comp + , RandIt const first + , typename iterator_traits::size_type const l_block + , typename iterator_traits::size_type const l_irreg1 + , typename iterator_traits::size_type const n_block_a + , typename iterator_traits::size_type const n_block_b + , typename iterator_traits::size_type const l_irreg2 + , Compare comp + , Op op + , RandItBuf const buf_first) +{ + typedef typename iterator_traits::size_type size_type; + size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count; + //BOOST_ASSERT(n_block_a || n_block_b); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a])); + + size_type n_block_b_left = n_block_b; + size_type n_block_a_left = n_block_a; + size_type n_block_left = n_block_b + n_block_a; + RandItKeys key_mid(key_first + n_block_a); + + RandItBuf buffer = buf_first; + RandItBuf buffer_end = buffer; + RandIt first1 = first; + RandIt last1 = first1 + l_irreg1; + RandIt first2 = last1; + RandIt const first_irr2 = first2 + n_block_left*l_block; + bool is_range1_A = true; + const size_type len = l_block * n_block_a + l_block * n_block_b + l_irreg1 + l_irreg2; (void)len; + + RandItKeys key_range2(key_first); + + //////////////////////////////////////////////////////////////////////////// + //Process all regular blocks before the irregular B block + //////////////////////////////////////////////////////////////////////////// + size_type min_check = n_block_a == n_block_left ? 0u : n_block_a; + size_type max_check = min_value(min_check+size_type(1), n_block_left); + for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) { + size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp); + max_check = min_value(max_value(max_check, next_key_idx+size_type(2)), n_block_left); + RandIt first_min = first2 + next_key_idx*l_block; + RandIt const last_min = first_min + l_block; (void)last_min; + RandIt const last2 = first2 + l_block; + + bool const buffer_empty = buffer == buffer_end; (void)buffer_empty; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buffer_empty ? boost::movelib::is_sorted(first1, last1, comp) : boost::movelib::is_sorted(buffer, buffer_end, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || boost::movelib::is_sorted(first_min, last_min, comp)); + + //Check if irregular b block should go here. + //If so, break to the special code handling the irregular block + if (!n_block_b_left && + ( (l_irreg2 && comp(*first_irr2, *first_min)) || (!l_irreg2 && is_range1_A)) ){ + break; + } + + RandItKeys const key_next(key_range2 + next_key_idx); + bool const is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_next, *key_mid); + + if(is_range1_A == is_range2_A){ + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((first1 == last1) || (buffer_empty ? !comp(*first_min, last1[-1]) : !comp(*first_min, buffer_end[-1]))); + //If buffered, put those elements in place + RandIt res = op(forward_t(), buffer, buffer_end, first1); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwd: ", len); + buffer = buffer_end = buf_first; + BOOST_ASSERT(buffer_empty || res == last1); (void)res; + //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + buffer_end = buffer_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min, buffer = buf_first, op); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first2, last2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp)); + first1 = first2; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, first1, comp)); + } + else { + RandIt const unmerged = op_partial_merge_and_save(first1, last1, first2, last2, first_min, buffer, buffer_end, comp, op, is_range1_A); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_mrs: ", len); + bool const is_range_1_empty = buffer == buffer_end; + BOOST_ASSERT(is_range_1_empty || (buffer_end-buffer) == (last1+l_block-unmerged)); + if(is_range_1_empty){ + buffer = buffer_end = buf_first; + first_min = last_min - (last2 - first2); + //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + buffer_end = buffer_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min, buf_first, op); + } + else{ + first_min = last_min; + //swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min); + update_key(key_next, key_range2, key_mid); + } + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!is_range_1_empty || (last_min-first_min) == (last2-unmerged)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_swp: ", len); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first_min, last_min, comp)); + is_range1_A ^= is_range_1_empty; + first1 = unmerged; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, unmerged, comp)); + } + BOOST_ASSERT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left)); + is_range2_A ? --n_block_a_left : --n_block_b_left; + last1 += l_block; + first2 = last2; + } + RandIt res = op(forward_t(), buffer, buffer_end, first1); (void)res; + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, res, comp)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwd: ", len); + + //////////////////////////////////////////////////////////////////////////// + //Process irregular B block and remaining A blocks + //////////////////////////////////////////////////////////////////////////// + RandIt const last_irr2 = first_irr2 + l_irreg2; + op(forward_t(), first_irr2, first_irr2+l_irreg2, buf_first); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_fwir:", len); + buffer = buf_first; + buffer_end = buffer+l_irreg2; + + reverse_iterator rbuf_beg(buffer_end); + RandIt dest = op_merge_blocks_with_irreg + ((make_reverse_iterator)(key_first + n_block_b + n_block_a), (make_reverse_iterator)(key_mid), inverse(key_comp) + , (make_reverse_iterator)(first_irr2), rbuf_beg, (make_reverse_iterator)(buffer), (make_reverse_iterator)(last_irr2) + , l_block, n_block_left, 0, n_block_left + , inverse(comp), true, op).base(); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(dest, last_irr2, comp)); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_blocks_w_irg: ", len); + + buffer_end = rbuf_beg.base(); + BOOST_ASSERT((dest-last1) == (buffer_end-buffer)); + op_merge_with_left_placed(is_range1_A ? first1 : last1, last1, dest, buffer, buffer_end, comp, op); + BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" merge_with_left_plc:", len); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(first, last_irr2, comp)); +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// op_insertion_sort_step_left/right +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// + +template +typename iterator_traits::size_type + op_insertion_sort_step_left + ( RandIt const first + , typename iterator_traits::size_type const length + , typename iterator_traits::size_type const step + , Compare comp, Op op) +{ + typedef typename iterator_traits::size_type size_type; + size_type const s = min_value(step, AdaptiveSortInsertionSortThreshold); + size_type m = 0; + + while((length - m) > s){ + insertion_sort_op(first+m, first+m+s, first+m-s, comp, op); + m += s; + } + insertion_sort_op(first+m, first+length, first+m-s, comp, op); + return s; +} + +template +void op_merge_right_step_once + ( RandIt first_block + , typename iterator_traits::size_type const elements_in_blocks + , typename iterator_traits::size_type const l_build_buf + , Compare comp + , Op op) +{ + typedef typename iterator_traits::size_type size_type; + size_type restk = elements_in_blocks%(2*l_build_buf); + size_type p = elements_in_blocks - restk; + BOOST_ASSERT(0 == (p%(2*l_build_buf))); + + if(restk <= l_build_buf){ + op(backward_t(),first_block+p, first_block+p+restk, first_block+p+restk+l_build_buf); + } + else{ + op_merge_right(first_block+p, first_block+p+l_build_buf, first_block+p+restk, first_block+p+restk+l_build_buf, comp, op); + } + while(p>0){ + p -= 2*l_build_buf; + op_merge_right(first_block+p, first_block+p+l_build_buf, first_block+p+2*l_build_buf, first_block+p+3*l_build_buf, comp, op); + } +} + + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// insertion_sort_step +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +template +typename iterator_traits::size_type + insertion_sort_step + ( RandIt const first + , typename iterator_traits::size_type const length + , typename iterator_traits::size_type const step + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + size_type const s = min_value(step, AdaptiveSortInsertionSortThreshold); + size_type m = 0; + + while((length - m) > s){ + insertion_sort(first+m, first+m+s, comp); + m += s; + } + insertion_sort(first+m, first+length, comp); + return s; +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +// +// op_merge_left_step_multiple +// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +template +typename iterator_traits::size_type + op_merge_left_step_multiple + ( RandIt first_block + , typename iterator_traits::size_type const elements_in_blocks + , typename iterator_traits::size_type l_merged + , typename iterator_traits::size_type const l_build_buf + , typename iterator_traits::size_type l_left_space + , Compare comp + , Op op) +{ + typedef typename iterator_traits::size_type size_type; + for(; l_merged < l_build_buf && l_left_space >= l_merged; l_merged*=2){ + size_type p0=0; + RandIt pos = first_block; + while((elements_in_blocks - p0) > 2*l_merged) { + op_merge_left(pos-l_merged, pos, pos+l_merged, pos+2*l_merged, comp, op); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, pos+l_merged, comp)); + p0 += 2*l_merged; + pos = first_block+p0; + } + if((elements_in_blocks-p0) > l_merged) { + op_merge_left(pos-l_merged, pos, pos+l_merged, first_block+elements_in_blocks, comp, op); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, pos-l_merged+(first_block+elements_in_blocks-pos), comp)); + } + else { + op(forward_t(), pos, first_block+elements_in_blocks, pos-l_merged); + BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted(pos-l_merged, first_block+elements_in_blocks-l_merged, comp)); + } + first_block -= l_merged; + l_left_space -= l_merged; + } + return l_merged; +} + + +} //namespace detail_adaptive { +} //namespace movelib { +} //namespace boost { + +#include + +#endif //#define BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/basic_op.hpp b/autowrap/data_files/boost/move/algo/detail/basic_op.hpp new file mode 100644 index 00000000..ea5faf0e --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/basic_op.hpp @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_ALGO_BASIC_OP +#define BOOST_MOVE_ALGO_BASIC_OP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace movelib { + +struct forward_t{}; +struct backward_t{}; +struct three_way_t{}; +struct three_way_forward_t{}; +struct four_way_t{}; + +struct move_op +{ + template + BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest) + { *dest = ::boost::move(*source); } + + template + BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin) + { return ::boost::move(first, last, dest_begin); } + + template + BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_last) + { return ::boost::move_backward(first, last, dest_last); } + + template + BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it) + { + *dest2it = boost::move(*dest1it); + *dest1it = boost::move(*srcit); + } + + template + DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it) + { + //Destination2 range can overlap SourceIt range so avoid boost::move + while(srcit != srcitend){ + this->operator()(three_way_t(), srcit++, dest1it++, dest2it++); + } + return dest2it; + } + + template + BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it) + { + *dest3it = boost::move(*dest2it); + *dest2it = boost::move(*dest1it); + *dest1it = boost::move(*srcit); + } +}; + +struct swap_op +{ + template + BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest) + { boost::adl_move_swap(*dest, *source); } + + template + BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin) + { return boost::adl_move_swap_ranges(first, last, dest_begin); } + + template + BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_begin) + { return boost::adl_move_swap_ranges_backward(first, last, dest_begin); } + + template + BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it) + { + typename ::boost::movelib::iterator_traits::value_type tmp(boost::move(*dest2it)); + *dest2it = boost::move(*dest1it); + *dest1it = boost::move(*srcit); + *srcit = boost::move(tmp); + } + + template + DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it) + { + while(srcit != srcitend){ + this->operator()(three_way_t(), srcit++, dest1it++, dest2it++); + } + return dest2it; + } + + template + BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it) + { + typename ::boost::movelib::iterator_traits::value_type tmp(boost::move(*dest3it)); + *dest3it = boost::move(*dest2it); + *dest2it = boost::move(*dest1it); + *dest1it = boost::move(*srcit); + *srcit = boost::move(tmp); + } +}; + + +}} //namespace boost::movelib + +#endif //BOOST_MOVE_ALGO_BASIC_OP diff --git a/autowrap/data_files/boost/move/algo/detail/heap_sort.hpp b/autowrap/data_files/boost/move/algo/detail/heap_sort.hpp new file mode 100644 index 00000000..5474d9f5 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/heap_sort.hpp @@ -0,0 +1,111 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2018. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_HEAP_SORT_HPP +#define BOOST_MOVE_DETAIL_HEAP_SORT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { namespace movelib{ + +template +class heap_sort_helper +{ + typedef typename boost::movelib::iterator_traits::size_type size_type; + typedef typename boost::movelib::iterator_traits::value_type value_type; + + static void adjust_heap(RandomAccessIterator first, size_type hole_index, size_type const len, value_type &value, Compare comp) + { + size_type const top_index = hole_index; + size_type second_child = 2 * (hole_index + 1); + + while (second_child < len) { + if (comp(*(first + second_child), *(first + (second_child - 1)))) + second_child--; + *(first + hole_index) = boost::move(*(first + second_child)); + hole_index = second_child; + second_child = 2 * (second_child + 1); + } + if (second_child == len) { + *(first + hole_index) = boost::move(*(first + (second_child - 1))); + hole_index = second_child - 1; + } + + { //push_heap-like ending + size_type parent = (hole_index - 1) / 2; + while (hole_index > top_index && comp(*(first + parent), value)) { + *(first + hole_index) = boost::move(*(first + parent)); + hole_index = parent; + parent = (hole_index - 1) / 2; + } + *(first + hole_index) = boost::move(value); + } + } + + static void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) + { + size_type const len = size_type(last - first); + if (len > 1) { + size_type parent = len/2u - 1u; + + do { + value_type v(boost::move(*(first + parent))); + adjust_heap(first, parent, len, v, comp); + }while (parent--); + } + } + + static void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) + { + size_type len = size_type(last - first); + while (len > 1) { + //move biggest to the safe zone + --last; + value_type v(boost::move(*last)); + *last = boost::move(*first); + adjust_heap(first, size_type(0), --len, v, comp); + } + } + + public: + static void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) + { + make_heap(first, last, comp); + sort_heap(first, last, comp); + BOOST_ASSERT(boost::movelib::is_sorted(first, last, comp)); + } +}; + +template +BOOST_MOVE_FORCEINLINE void heap_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + heap_sort_helper::sort(first, last, comp); +} + +}} //namespace boost { namespace movelib{ + +#include + +#endif //#ifndef BOOST_MOVE_DETAIL_HEAP_SORT_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/insertion_sort.hpp b/autowrap/data_files/boost/move/algo/detail/insertion_sort.hpp new file mode 100644 index 00000000..5c378c3e --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/insertion_sort.hpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP +#define BOOST_MOVE_DETAIL_INSERT_SORT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace movelib{ + +// @cond + +template +void insertion_sort_op(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp, Op op) +{ + if (first1 != last1){ + BirdirectionalIterator last2 = first2; + op(first1, last2); + for (++last2; ++first1 != last1; ++last2){ + BirdirectionalIterator j2 = last2; + BirdirectionalIterator i2 = j2; + if (comp(*first1, *--i2)){ + op(i2, j2); + for (--j2; i2 != first2 && comp(*first1, *--i2); --j2) { + op(i2, j2); + } + } + op(first1, j2); + } + } +} + +template +void insertion_sort_swap(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp) +{ + insertion_sort_op(first1, last1, first2, comp, swap_op()); +} + + +template +void insertion_sort_copy(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp) +{ + insertion_sort_op(first1, last1, first2, comp, move_op()); +} + +// @endcond + +template +void insertion_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp) +{ + typedef typename boost::movelib::iterator_traits::value_type value_type; + if (first != last){ + BirdirectionalIterator i = first; + for (++i; i != last; ++i){ + BirdirectionalIterator j = i; + if (comp(*i, *--j)) { + value_type tmp(::boost::move(*i)); + *i = ::boost::move(*j); + for (BirdirectionalIterator k = j; k != first && comp(tmp, *--k); --j) { + *j = ::boost::move(*k); + } + *j = ::boost::move(tmp); + } + } + } +} + +template +void insertion_sort_uninitialized_copy + (BirdirectionalIterator first1, BirdirectionalIterator const last1 + , BirdirectionalRawIterator const first2 + , Compare comp) +{ + typedef typename iterator_traits::value_type value_type; + if (first1 != last1){ + BirdirectionalRawIterator last2 = first2; + ::new((iterator_to_raw_pointer)(last2), boost_move_new_t()) value_type(::boost::move(*first1)); + destruct_n d(first2); + d.incr(); + for (++last2; ++first1 != last1; ++last2){ + BirdirectionalRawIterator j2 = last2; + BirdirectionalRawIterator k2 = j2; + if (comp(*first1, *--k2)){ + ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*k2)); + d.incr(); + for (--j2; k2 != first2 && comp(*first1, *--k2); --j2) + *j2 = ::boost::move(*k2); + *j2 = ::boost::move(*first1); + } + else{ + ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*first1)); + d.incr(); + } + } + d.release(); + } +} + +}} //namespace boost { namespace movelib{ + +#endif //#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/is_sorted.hpp b/autowrap/data_files/boost/move/algo/detail/is_sorted.hpp new file mode 100644 index 00000000..d3dccfc2 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/is_sorted.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_MOVE_DETAIL_IS_SORTED_HPP +#define BOOST_MOVE_DETAIL_IS_SORTED_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2018. 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_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace movelib { + +template +bool is_sorted(ForwardIt const first, ForwardIt last, Pred pred) +{ + if (first != last) { + ForwardIt next = first, cur(first); + while (++next != last) { + if (pred(*next, *cur)) + return false; + cur = next; + } + } + return true; +} + +template +bool is_sorted_and_unique(ForwardIt first, ForwardIt last, Pred pred) +{ + if (first != last) { + ForwardIt next = first; + while (++next != last) { + if (!pred(*first, *next)) + return false; + first = next; + } + } + return true; +} + +} //namespace movelib { +} //namespace boost { + +#endif //BOOST_MOVE_DETAIL_IS_SORTED_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/merge.hpp b/autowrap/data_files/boost/move/algo/detail/merge.hpp new file mode 100644 index 00000000..58df0616 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/merge.hpp @@ -0,0 +1,980 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_MERGE_HPP +#define BOOST_MOVE_MERGE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace movelib { + +template::size_type> +class adaptive_xbuf +{ + adaptive_xbuf(const adaptive_xbuf &); + adaptive_xbuf & operator=(const adaptive_xbuf &); + + #if !defined(UINTPTR_MAX) + typedef std::size_t uintptr_t; + #endif + + public: + typedef RandRawIt iterator; + typedef SizeType size_type; + + adaptive_xbuf() + : m_ptr(), m_size(0), m_capacity(0) + {} + + adaptive_xbuf(RandRawIt raw_memory, size_type capacity) + : m_ptr(raw_memory), m_size(0), m_capacity(capacity) + {} + + template + void move_assign(RandIt first, size_type n) + { + if(n <= m_size){ + boost::move(first, first+n, m_ptr); + size_type size = m_size; + while(size-- != n){ + m_ptr[size].~T(); + } + m_size = n; + } + else{ + RandRawIt result = boost::move(first, first+m_size, m_ptr); + boost::uninitialized_move(first+m_size, first+n, result); + m_size = n; + } + } + + template + void push_back(RandIt first, size_type n) + { + BOOST_ASSERT(m_capacity - m_size >= n); + boost::uninitialized_move(first, first+n, m_ptr+m_size); + m_size += n; + } + + template + iterator add(RandIt it) + { + BOOST_ASSERT(m_size < m_capacity); + RandRawIt p_ret = m_ptr + m_size; + ::new(&*p_ret) T(::boost::move(*it)); + ++m_size; + return p_ret; + } + + template + void insert(iterator pos, RandIt it) + { + if(pos == (m_ptr + m_size)){ + this->add(it); + } + else{ + this->add(m_ptr+m_size-1); + //m_size updated + boost::move_backward(pos, m_ptr+m_size-2, m_ptr+m_size-1); + *pos = boost::move(*it); + } + } + + void set_size(size_type size) + { + m_size = size; + } + + void shrink_to_fit(size_type const size) + { + if(m_size > size){ + for(size_type szt_i = size; szt_i != m_size; ++szt_i){ + m_ptr[szt_i].~T(); + } + m_size = size; + } + } + + void initialize_until(size_type const size, T &t) + { + BOOST_ASSERT(m_size < m_capacity); + if(m_size < size){ + BOOST_TRY + { + ::new((void*)&m_ptr[m_size]) T(::boost::move(t)); + ++m_size; + for(; m_size != size; ++m_size){ + ::new((void*)&m_ptr[m_size]) T(::boost::move(m_ptr[m_size-1])); + } + t = ::boost::move(m_ptr[m_size-1]); + } + BOOST_CATCH(...) + { + while(m_size) + { + --m_size; + m_ptr[m_size].~T(); + } + } + BOOST_CATCH_END + } + } + + private: + template + static bool is_raw_ptr(RIt) + { + return false; + } + + static bool is_raw_ptr(T*) + { + return true; + } + + public: + template + bool supports_aligned_trailing(size_type size, size_type trail_count) const + { + if(this->is_raw_ptr(this->data()) && m_capacity){ + uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size)); + uintptr_t u_addr_cp = uintptr_t(&*(this->data()+this->capacity())); + u_addr_sz = ((u_addr_sz + sizeof(U)-1)/sizeof(U))*sizeof(U); + return (u_addr_cp >= u_addr_sz) && ((u_addr_cp - u_addr_sz)/sizeof(U) >= trail_count); + } + return false; + } + + template + U *aligned_trailing() const + { + return this->aligned_trailing(this->size()); + } + + template + U *aligned_trailing(size_type pos) const + { + uintptr_t u_addr = uintptr_t(&*(this->data()+pos)); + u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U); + return (U*)u_addr; + } + + ~adaptive_xbuf() + { + this->clear(); + } + + size_type capacity() const + { return m_capacity; } + + iterator data() const + { return m_ptr; } + + iterator begin() const + { return m_ptr; } + + iterator end() const + { return m_ptr+m_size; } + + size_type size() const + { return m_size; } + + bool empty() const + { return !m_size; } + + void clear() + { + this->shrink_to_fit(0u); + } + + private: + RandRawIt m_ptr; + size_type m_size; + size_type m_capacity; +}; + +template +class range_xbuf +{ + range_xbuf(const range_xbuf &); + range_xbuf & operator=(const range_xbuf &); + + public: + typedef SizeType size_type; + typedef Iterator iterator; + + range_xbuf(Iterator first, Iterator last) + : m_first(first), m_last(first), m_cap(last) + {} + + template + void move_assign(RandIt first, size_type n) + { + BOOST_ASSERT(size_type(n) <= size_type(m_cap-m_first)); + m_last = Op()(forward_t(), first, first+n, m_first); + } + + ~range_xbuf() + {} + + size_type capacity() const + { return m_cap-m_first; } + + Iterator data() const + { return m_first; } + + Iterator end() const + { return m_last; } + + size_type size() const + { return m_last-m_first; } + + bool empty() const + { return m_first == m_last; } + + void clear() + { + m_last = m_first; + } + + template + iterator add(RandIt it) + { + Iterator pos(m_last); + *pos = boost::move(*it); + ++m_last; + return pos; + } + + void set_size(size_type size) + { + m_last = m_first; + m_last += size; + } + + private: + Iterator const m_first; + Iterator m_last; + Iterator const m_cap; +}; + + + +// @cond + +/* +template +inline Unsigned gcd(Unsigned x, Unsigned y) +{ + if(0 == ((x &(x-1)) | (y & (y-1)))){ + return x < y ? x : y; + } + else{ + do + { + Unsigned t = x % y; + x = y; + y = t; + } while (y); + return x; + } +} +*/ + +//Modified version from "An Optimal In-Place Array Rotation Algorithm", Ching-Kuang Shene +template +Unsigned gcd(Unsigned x, Unsigned y) +{ + if(0 == ((x &(x-1)) | (y & (y-1)))){ + return x < y ? x : y; + } + else{ + Unsigned z = 1; + while((!(x&1)) & (!(y&1))){ + z <<=1, x>>=1, y>>=1; + } + while(x && y){ + if(!(x&1)) + x >>=1; + else if(!(y&1)) + y >>=1; + else if(x >=y) + x = (x-y) >> 1; + else + y = (y-x) >> 1; + } + return z*(x+y); + } +} + +template +RandIt rotate_gcd(RandIt first, RandIt middle, RandIt last) +{ + typedef typename iterator_traits::size_type size_type; + typedef typename iterator_traits::value_type value_type; + + if(first == middle) + return last; + if(middle == last) + return first; + const size_type middle_pos = size_type(middle - first); + RandIt ret = last - middle_pos; + if (middle == ret){ + boost::adl_move_swap_ranges(first, middle, middle); + } + else{ + const size_type length = size_type(last - first); + for( RandIt it_i(first), it_gcd(it_i + gcd(length, middle_pos)) + ; it_i != it_gcd + ; ++it_i){ + value_type temp(boost::move(*it_i)); + RandIt it_j = it_i; + RandIt it_k = it_j+middle_pos; + do{ + *it_j = boost::move(*it_k); + it_j = it_k; + size_type const left = size_type(last - it_j); + it_k = left > middle_pos ? it_j + middle_pos : first + (middle_pos - left); + } while(it_k != it_i); + *it_j = boost::move(temp); + } + } + return ret; +} + +template +RandIt lower_bound + (RandIt first, const RandIt last, const T& key, Compare comp) +{ + typedef typename iterator_traits + ::size_type size_type; + size_type len = size_type(last - first); + RandIt middle; + + while (len) { + size_type step = len >> 1; + middle = first; + middle += step; + + if (comp(*middle, key)) { + first = ++middle; + len -= step + 1; + } + else{ + len = step; + } + } + return first; +} + +template +RandIt upper_bound + (RandIt first, const RandIt last, const T& key, Compare comp) +{ + typedef typename iterator_traits + ::size_type size_type; + size_type len = size_type(last - first); + RandIt middle; + + while (len) { + size_type step = len >> 1; + middle = first; + middle += step; + + if (!comp(key, *middle)) { + first = ++middle; + len -= step + 1; + } + else{ + len = step; + } + } + return first; +} + + +template +void op_merge_left( RandIt buf_first + , RandIt first1 + , RandIt const last1 + , RandIt const last2 + , Compare comp + , Op op) +{ + for(RandIt first2=last1; first2 != last2; ++buf_first){ + if(first1 == last1){ + op(forward_t(), first2, last2, buf_first); + return; + } + else if(comp(*first2, *first1)){ + op(first2, buf_first); + ++first2; + } + else{ + op(first1, buf_first); + ++first1; + } + } + if(buf_first != first1){//In case all remaining elements are in the same place + //(e.g. buffer is exactly the size of the second half + //and all elements from the second half are less) + op(forward_t(), first1, last1, buf_first); + } +} + +// [buf_first, first1) -> buffer +// [first1, last1) merge [last1,last2) -> [buf_first,buf_first+(last2-first1)) +// Elements from buffer are moved to [last2 - (first1-buf_first), last2) +// Note: distance(buf_first, first1) >= distance(last1, last2), so no overlapping occurs +template +void merge_left + (RandIt buf_first, RandIt first1, RandIt const last1, RandIt const last2, Compare comp) +{ + op_merge_left(buf_first, first1, last1, last2, comp, move_op()); +} + +// [buf_first, first1) -> buffer +// [first1, last1) merge [last1,last2) -> [buf_first,buf_first+(last2-first1)) +// Elements from buffer are swapped to [last2 - (first1-buf_first), last2) +// Note: distance(buf_first, first1) >= distance(last1, last2), so no overlapping occurs +template +void swap_merge_left + (RandIt buf_first, RandIt first1, RandIt const last1, RandIt const last2, Compare comp) +{ + op_merge_left(buf_first, first1, last1, last2, comp, swap_op()); +} + +template +void op_merge_right + (RandIt const first1, RandIt last1, RandIt last2, RandIt buf_last, Compare comp, Op op) +{ + RandIt const first2 = last1; + while(first1 != last1){ + if(last2 == first2){ + op(backward_t(), first1, last1, buf_last); + return; + } + --last2; + --last1; + --buf_last; + if(comp(*last2, *last1)){ + op(last1, buf_last); + ++last2; + } + else{ + op(last2, buf_last); + ++last1; + } + } + if(last2 != buf_last){ //In case all remaining elements are in the same place + //(e.g. buffer is exactly the size of the first half + //and all elements from the second half are less) + op(backward_t(), first2, last2, buf_last); + } +} + +// [last2, buf_last) - buffer +// [first1, last1) merge [last1,last2) -> [first1+(buf_last-last2), buf_last) +// Note: distance[last2, buf_last) >= distance[first1, last1), so no overlapping occurs +template +void merge_right + (RandIt first1, RandIt last1, RandIt last2, RandIt buf_last, Compare comp) +{ + op_merge_right(first1, last1, last2, buf_last, comp, move_op()); +} + +// [last2, buf_last) - buffer +// [first1, last1) merge [last1,last2) -> [first1+(buf_last-last2), buf_last) +// Note: distance[last2, buf_last) >= distance[first1, last1), so no overlapping occurs +template +void swap_merge_right + (RandIt first1, RandIt last1, RandIt last2, RandIt buf_last, Compare comp) +{ + op_merge_right(first1, last1, last2, buf_last, comp, swap_op()); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// BUFFERED MERGE +// +/////////////////////////////////////////////////////////////////////////////// +template +void op_buffered_merge + ( RandIt first, RandIt const middle, RandIt last + , Compare comp, Op op + , Buf &xbuf) +{ + if(first != middle && middle != last && comp(*middle, middle[-1])){ + typedef typename iterator_traits::size_type size_type; + size_type const len1 = size_type(middle-first); + size_type const len2 = size_type(last-middle); + if(len1 <= len2){ + first = boost::movelib::upper_bound(first, middle, *middle, comp); + xbuf.move_assign(first, size_type(middle-first)); + op_merge_with_right_placed + (xbuf.data(), xbuf.end(), first, middle, last, comp, op); + } + else{ + last = boost::movelib::lower_bound(middle, last, middle[-1], comp); + xbuf.move_assign(middle, size_type(last-middle)); + op_merge_with_left_placed + (first, middle, last, xbuf.data(), xbuf.end(), comp, op); + } + } +} + +template +void buffered_merge + ( RandIt first, RandIt const middle, RandIt last + , Compare comp + , XBuf &xbuf) +{ + op_buffered_merge(first, middle, last, comp, move_op(), xbuf); +} + +//Complexity: min(len1,len2)^2 + max(len1,len2) +template +void merge_bufferless_ON2(RandIt first, RandIt middle, RandIt last, Compare comp) +{ + if((middle - first) < (last - middle)){ + while(first != middle){ + RandIt const old_last1 = middle; + middle = boost::movelib::lower_bound(middle, last, *first, comp); + first = rotate_gcd(first, old_last1, middle); + if(middle == last){ + break; + } + do{ + ++first; + } while(first != middle && !comp(*middle, *first)); + } + } + else{ + while(middle != last){ + RandIt p = boost::movelib::upper_bound(first, middle, last[-1], comp); + last = rotate_gcd(p, middle, last); + middle = p; + if(middle == first){ + break; + } + --p; + do{ + --last; + } while(middle != last && !comp(last[-1], *p)); + } + } +} + +static const std::size_t MergeBufferlessONLogNRotationThreshold = 16u; + +template +void merge_bufferless_ONlogN_recursive + ( RandIt first, RandIt middle, RandIt last + , typename iterator_traits::size_type len1 + , typename iterator_traits::size_type len2 + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + + while(1) { + //trivial cases + if (!len2) { + return; + } + else if (!len1) { + return; + } + else if (size_type(len1 | len2) == 1u) { + if (comp(*middle, *first)) + adl_move_swap(*first, *middle); + return; + } + else if(size_type(len1+len2) < MergeBufferlessONLogNRotationThreshold){ + merge_bufferless_ON2(first, middle, last, comp); + return; + } + + RandIt first_cut = first; + RandIt second_cut = middle; + size_type len11 = 0; + size_type len22 = 0; + if (len1 > len2) { + len11 = len1 / 2; + first_cut += len11; + second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp); + len22 = size_type(second_cut - middle); + } + else { + len22 = len2 / 2; + second_cut += len22; + first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp); + len11 = size_type(first_cut - first); + } + RandIt new_middle = rotate_gcd(first_cut, middle, second_cut); + + //Avoid one recursive call doing a manual tail call elimination on the biggest range + const size_type len_internal = len11+len22; + if( len_internal < (len1 + len2 - len_internal) ) { + merge_bufferless_ONlogN_recursive(first, first_cut, new_middle, len11, len22, comp); + first = new_middle; + middle = second_cut; + len1 -= len11; + len2 -= len22; + } + else { + merge_bufferless_ONlogN_recursive(new_middle, second_cut, last, len1 - len11, len2 - len22, comp); + middle = first_cut; + last = new_middle; + len1 = len11; + len2 = len22; + } + } +} + + +//Complexity: NlogN +template +void merge_bufferless_ONlogN(RandIt first, RandIt middle, RandIt last, Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + merge_bufferless_ONlogN_recursive + (first, middle, last, size_type(middle - first), size_type(last - middle), comp); +} + +template +void merge_bufferless(RandIt first, RandIt middle, RandIt last, Compare comp) +{ + #define BOOST_ADAPTIVE_MERGE_NLOGN_MERGE + #ifdef BOOST_ADAPTIVE_MERGE_NLOGN_MERGE + merge_bufferless_ONlogN(first, middle, last, comp); + #else + merge_bufferless_ON2(first, middle, last, comp); + #endif //BOOST_ADAPTIVE_MERGE_NLOGN_MERGE +} + +// [r_first, r_last) are already in the right part of the destination range. +template +void op_merge_with_right_placed + ( InputIterator first, InputIterator last + , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last + , Compare comp, Op op) +{ + BOOST_ASSERT((last - first) == (r_first - dest_first)); + while ( first != last ) { + if (r_first == r_last) { + InputOutIterator end = op(forward_t(), first, last, dest_first); + BOOST_ASSERT(end == r_last); + (void)end; + return; + } + else if (comp(*r_first, *first)) { + op(r_first, dest_first); + ++r_first; + } + else { + op(first, dest_first); + ++first; + } + ++dest_first; + } + // Remaining [r_first, r_last) already in the correct place +} + +template +void swap_merge_with_right_placed + ( InputIterator first, InputIterator last + , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last + , Compare comp) +{ + op_merge_with_right_placed(first, last, dest_first, r_first, r_last, comp, swap_op()); +} + +// [first, last) are already in the right part of the destination range. +template +void op_merge_with_left_placed + ( BidirOutIterator const first, BidirOutIterator last, BidirOutIterator dest_last + , BidirIterator const r_first, BidirIterator r_last + , Compare comp, Op op) +{ + BOOST_ASSERT((dest_last - last) == (r_last - r_first)); + while( r_first != r_last ) { + if(first == last) { + BidirOutIterator res = op(backward_t(), r_first, r_last, dest_last); + BOOST_ASSERT(last == res); + (void)res; + return; + } + --r_last; + --last; + if(comp(*r_last, *last)){ + ++r_last; + --dest_last; + op(last, dest_last); + } + else{ + ++last; + --dest_last; + op(r_last, dest_last); + } + } + // Remaining [first, last) already in the correct place +} + +// @endcond + +// [first, last) are already in the right part of the destination range. +template +void merge_with_left_placed + ( BidirOutIterator const first, BidirOutIterator last, BidirOutIterator dest_last + , BidirIterator const r_first, BidirIterator r_last + , Compare comp) +{ + op_merge_with_left_placed(first, last, dest_last, r_first, r_last, comp, move_op()); +} + +// [r_first, r_last) are already in the right part of the destination range. +template +void merge_with_right_placed + ( InputIterator first, InputIterator last + , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last + , Compare comp) +{ + op_merge_with_right_placed(first, last, dest_first, r_first, r_last, comp, move_op()); +} + +// [r_first, r_last) are already in the right part of the destination range. +// [dest_first, r_first) is uninitialized memory +template +void uninitialized_merge_with_right_placed + ( InputIterator first, InputIterator last + , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last + , Compare comp) +{ + BOOST_ASSERT((last - first) == (r_first - dest_first)); + typedef typename iterator_traits::value_type value_type; + InputOutIterator const original_r_first = r_first; + + destruct_n d(dest_first); + + while ( first != last && dest_first != original_r_first ) { + if (r_first == r_last) { + for(; dest_first != original_r_first; ++dest_first, ++first){ + ::new((iterator_to_raw_pointer)(dest_first)) value_type(::boost::move(*first)); + d.incr(); + } + d.release(); + InputOutIterator end = ::boost::move(first, last, original_r_first); + BOOST_ASSERT(end == r_last); + (void)end; + return; + } + else if (comp(*r_first, *first)) { + ::new((iterator_to_raw_pointer)(dest_first)) value_type(::boost::move(*r_first)); + d.incr(); + ++r_first; + } + else { + ::new((iterator_to_raw_pointer)(dest_first)) value_type(::boost::move(*first)); + d.incr(); + ++first; + } + ++dest_first; + } + d.release(); + merge_with_right_placed(first, last, original_r_first, r_first, r_last, comp); +} + +/* +// [r_first, r_last) are already in the right part of the destination range. +// [dest_first, r_first) is uninitialized memory +template +void uninitialized_merge_with_left_placed + ( BidirOutIterator dest_first, BidirOutIterator r_first, BidirOutIterator r_last + , BidirIterator first, BidirIterator last + , Compare comp) +{ + BOOST_ASSERT((last - first) == (r_last - r_first)); + typedef typename iterator_traits::value_type value_type; + BidirOutIterator const original_r_last = r_last; + + destruct_n d(&*dest_last); + + while ( first != last && dest_first != original_r_first ) { + if (r_first == r_last) { + for(; dest_first != original_r_first; ++dest_first, ++first){ + ::new(&*dest_first) value_type(::boost::move(*first)); + d.incr(); + } + d.release(); + BidirOutIterator end = ::boost::move(first, last, original_r_first); + BOOST_ASSERT(end == r_last); + (void)end; + return; + } + else if (comp(*r_first, *first)) { + ::new(&*dest_first) value_type(::boost::move(*r_first)); + d.incr(); + ++r_first; + } + else { + ::new(&*dest_first) value_type(::boost::move(*first)); + d.incr(); + ++first; + } + ++dest_first; + } + d.release(); + merge_with_right_placed(first, last, original_r_first, r_first, r_last, comp); +} +*/ + + +/// This is a helper function for the merge routines. +template + BidirectionalIterator1 + rotate_adaptive(BidirectionalIterator1 first, + BidirectionalIterator1 middle, + BidirectionalIterator1 last, + typename iterator_traits::size_type len1, + typename iterator_traits::size_type len2, + BidirectionalIterator2 buffer, + typename iterator_traits::size_type buffer_size) +{ + if (len1 > len2 && len2 <= buffer_size) + { + if(len2) //Protect against self-move ranges + { + BidirectionalIterator2 buffer_end = boost::move(middle, last, buffer); + boost::move_backward(first, middle, last); + return boost::move(buffer, buffer_end, first); + } + else + return first; + } + else if (len1 <= buffer_size) + { + if(len1) //Protect against self-move ranges + { + BidirectionalIterator2 buffer_end = boost::move(first, middle, buffer); + BidirectionalIterator1 ret = boost::move(middle, last, first); + boost::move(buffer, buffer_end, ret); + return ret; + } + else + return last; + } + else + return rotate_gcd(first, middle, last); +} + +template + void merge_adaptive_ONlogN_recursive + (BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, + typename iterator_traits::size_type len1, + typename iterator_traits::size_type len2, + Pointer buffer, + typename iterator_traits::size_type buffer_size, + Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + //trivial cases + if (!len2 || !len1) { + return; + } + else if (len1 <= buffer_size || len2 <= buffer_size) + { + range_xbuf rxbuf(buffer, buffer + buffer_size); + buffered_merge(first, middle, last, comp, rxbuf); + } + else if (size_type(len1 + len2) == 2u) { + if (comp(*middle, *first)) + adl_move_swap(*first, *middle); + return; + } + else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) { + merge_bufferless_ON2(first, middle, last, comp); + return; + } + BidirectionalIterator first_cut = first; + BidirectionalIterator second_cut = middle; + size_type len11 = 0; + size_type len22 = 0; + if (len1 > len2) //(len1 < len2) + { + len11 = len1 / 2; + first_cut += len11; + second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp); + len22 = second_cut - middle; + } + else + { + len22 = len2 / 2; + second_cut += len22; + first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp); + len11 = first_cut - first; + } + + BidirectionalIterator new_middle + = rotate_adaptive(first_cut, middle, second_cut, + size_type(len1 - len11), len22, buffer, + buffer_size); + merge_adaptive_ONlogN_recursive(first, first_cut, new_middle, len11, + len22, buffer, buffer_size, comp); + merge_adaptive_ONlogN_recursive(new_middle, second_cut, last, + len1 - len11, len2 - len22, buffer, buffer_size, comp); +} + + +template +void merge_adaptive_ONlogN(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, + Compare comp, + RandRawIt uninitialized, + typename iterator_traits::size_type uninitialized_len) +{ + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::size_type size_type; + + if (first == middle || middle == last) + return; + + if(uninitialized_len) + { + const size_type len1 = size_type(middle - first); + const size_type len2 = size_type(last - middle); + + ::boost::movelib::adaptive_xbuf xbuf(uninitialized, uninitialized_len); + xbuf.initialize_until(uninitialized_len, *first); + merge_adaptive_ONlogN_recursive(first, middle, last, len1, len2, xbuf.begin(), uninitialized_len, comp); + } + else + { + merge_bufferless(first, middle, last, comp); + } +} + + +} //namespace movelib { +} //namespace boost { + +#endif //#define BOOST_MOVE_MERGE_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/merge_sort.hpp b/autowrap/data_files/boost/move/algo/detail/merge_sort.hpp new file mode 100644 index 00000000..34bbd2e2 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/merge_sort.hpp @@ -0,0 +1,207 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_MERGE_SORT_HPP +#define BOOST_MOVE_DETAIL_MERGE_SORT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace movelib { + +// @cond + +static const unsigned MergeSortInsertionSortThreshold = 16; + +template +void inplace_stable_sort(RandIt first, RandIt last, Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + if (size_type(last - first) <= size_type(MergeSortInsertionSortThreshold)) { + insertion_sort(first, last, comp); + return; + } + RandIt middle = first + (last - first) / 2; + inplace_stable_sort(first, middle, comp); + inplace_stable_sort(middle, last, comp); + merge_bufferless_ONlogN_recursive + (first, middle, last, size_type(middle - first), size_type(last - middle), comp); +} + +// @endcond + +template +void merge_sort_copy( RandIt first, RandIt last + , RandIt2 dest, Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + + size_type const count = size_type(last - first); + if(count <= MergeSortInsertionSortThreshold){ + insertion_sort_copy(first, last, dest, comp); + } + else{ + size_type const half = count/2; + merge_sort_copy(first + half, last , dest+half , comp); + merge_sort_copy(first , first + half, first + half, comp); + merge_with_right_placed + ( first + half, first + half + half + , dest, dest+half, dest + count + , comp); + } +} + +template +void merge_sort_uninitialized_copy( RandIt first, RandIt last + , RandItRaw uninitialized + , Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + typedef typename iterator_traits::value_type value_type; + + size_type const count = size_type(last - first); + if(count <= MergeSortInsertionSortThreshold){ + insertion_sort_uninitialized_copy(first, last, uninitialized, comp); + } + else{ + size_type const half = count/2; + merge_sort_uninitialized_copy(first + half, last, uninitialized + half, comp); + destruct_n d(uninitialized+half); + d.incr(count-half); + merge_sort_copy(first, first + half, first + half, comp); + uninitialized_merge_with_right_placed + ( first + half, first + half + half + , uninitialized, uninitialized+half, uninitialized+count + , comp); + d.release(); + } +} + +template +void merge_sort( RandIt first, RandIt last, Compare comp + , RandItRaw uninitialized) +{ + typedef typename iterator_traits::size_type size_type; + typedef typename iterator_traits::value_type value_type; + + size_type const count = size_type(last - first); + if(count <= MergeSortInsertionSortThreshold){ + insertion_sort(first, last, comp); + } + else{ + size_type const half = count/2; + size_type const rest = count - half; + RandIt const half_it = first + half; + RandIt const rest_it = first + rest; + + merge_sort_uninitialized_copy(half_it, last, uninitialized, comp); + destruct_n d(uninitialized); + d.incr(rest); + merge_sort_copy(first, half_it, rest_it, comp); + merge_with_right_placed + ( uninitialized, uninitialized + rest + , first, rest_it, last, antistable(comp)); + } +} + +///@cond + +template +void merge_sort_with_constructed_buffer( RandIt first, RandIt last, Compare comp, RandItRaw buffer) +{ + typedef typename iterator_traits::size_type size_type; + + size_type const count = size_type(last - first); + if(count <= MergeSortInsertionSortThreshold){ + insertion_sort(first, last, comp); + } + else{ + size_type const half = count/2; + size_type const rest = count - half; + RandIt const half_it = first + half; + RandIt const rest_it = first + rest; + + merge_sort_copy(half_it, last, buffer, comp); + merge_sort_copy(first, half_it, rest_it, comp); + merge_with_right_placed + (buffer, buffer + rest + , first, rest_it, last, antistable(comp)); + } +} + +template +void stable_sort_ONlogN_recursive(RandIt first, RandIt last, Pointer buffer, Distance buffer_size, Compare comp) +{ + typedef typename iterator_traits::size_type size_type; + if (size_type(last - first) <= size_type(MergeSortInsertionSortThreshold)) { + insertion_sort(first, last, comp); + } + else { + const size_type len = (last - first) / 2; + const RandIt middle = first + len; + if (len > ((buffer_size+1)/2)){ + stable_sort_ONlogN_recursive(first, middle, buffer, buffer_size, comp); + stable_sort_ONlogN_recursive(middle, last, buffer, buffer_size, comp); + } + else{ + merge_sort_with_constructed_buffer(first, middle, comp, buffer); + merge_sort_with_constructed_buffer(middle, last, comp, buffer); + } + merge_adaptive_ONlogN_recursive(first, middle, last, + size_type(middle - first), + size_type(last - middle), + buffer, buffer_size, + comp); + } +} + +template +void stable_sort_adaptive_ONlogN2(BidirectionalIterator first, + BidirectionalIterator last, + Compare comp, + RandRawIt uninitialized, + std::size_t uninitialized_len) +{ + typedef typename iterator_traits::value_type value_type; + + ::boost::movelib::adaptive_xbuf xbuf(uninitialized, uninitialized_len); + xbuf.initialize_until(uninitialized_len, *first); + stable_sort_ONlogN_recursive(first, last, uninitialized, uninitialized_len, comp); +} + +///@endcond + +}} //namespace boost { namespace movelib{ + +#include + +#endif //#ifndef BOOST_MOVE_DETAIL_MERGE_SORT_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/pdqsort.hpp b/autowrap/data_files/boost/move/algo/detail/pdqsort.hpp new file mode 100644 index 00000000..b6a12789 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/pdqsort.hpp @@ -0,0 +1,334 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Orson Peters 2017. +// (C) Copyright Ion Gaztanaga 2017-2018. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This implementation of Pattern-defeating quicksort (pdqsort) was written +// by Orson Peters, and discussed in the Boost mailing list: +// http://boost.2283326.n4.nabble.com/sort-pdqsort-td4691031.html +// +// This implementation is the adaptation by Ion Gaztanaga of code originally in GitHub +// with permission from the author to relicense it under the Boost Software License +// (see the Boost mailing list for details). +// +// The original copyright statement is pasted here for completeness: +// +// pdqsort.h - Pattern-defeating quicksort. +// Copyright (c) 2015 Orson Peters +// This software is provided 'as-is', without any express or implied warranty. In no event will the +// authors be held liable for any damages arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, including commercial +// applications, and to alter it and redistribute it freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the +// original software. If you use this software in a product, an acknowledgment in the product +// documentation would be appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as +// being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_ALGO_PDQSORT_HPP +#define BOOST_MOVE_ALGO_PDQSORT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace movelib { + +namespace pdqsort_detail { + + //A simple pair implementation to avoid including + template + struct pair + { + pair() + {} + + pair(const T1 &t1, const T2 &t2) + : first(t1), second(t2) + {} + + T1 first; + T2 second; + }; + + enum { + // Partitions below this size are sorted using insertion sort. + insertion_sort_threshold = 24, + + // Partitions above this size use Tukey's ninther to select the pivot. + ninther_threshold = 128, + + // When we detect an already sorted partition, attempt an insertion sort that allows this + // amount of element moves before giving up. + partial_insertion_sort_limit = 8, + + // Must be multiple of 8 due to loop unrolling, and < 256 to fit in unsigned char. + block_size = 64, + + // Cacheline size, assumes power of two. + cacheline_size = 64 + + }; + + // Returns floor(log2(n)), assumes n > 0. + template + Unsigned log2(Unsigned n) { + Unsigned log = 0; + while (n >>= 1) ++log; + return log; + } + + // Attempts to use insertion sort on [begin, end). Will return false if more than + // partial_insertion_sort_limit elements were moved, and abort sorting. Otherwise it will + // successfully sort and return true. + template + inline bool partial_insertion_sort(Iter begin, Iter end, Compare comp) { + typedef typename boost::movelib::iterator_traits::value_type T; + typedef typename boost::movelib::iterator_traits::size_type size_type; + if (begin == end) return true; + + size_type limit = 0; + for (Iter cur = begin + 1; cur != end; ++cur) { + if (limit > partial_insertion_sort_limit) return false; + + Iter sift = cur; + Iter sift_1 = cur - 1; + + // Compare first so we can avoid 2 moves for an element already positioned correctly. + if (comp(*sift, *sift_1)) { + T tmp = boost::move(*sift); + + do { *sift-- = boost::move(*sift_1); } + while (sift != begin && comp(tmp, *--sift_1)); + + *sift = boost::move(tmp); + limit += size_type(cur - sift); + } + } + + return true; + } + + template + inline void sort2(Iter a, Iter b, Compare comp) { + if (comp(*b, *a)) boost::adl_move_iter_swap(a, b); + } + + // Sorts the elements *a, *b and *c using comparison function comp. + template + inline void sort3(Iter a, Iter b, Iter c, Compare comp) { + sort2(a, b, comp); + sort2(b, c, comp); + sort2(a, b, comp); + } + + // Partitions [begin, end) around pivot *begin using comparison function comp. Elements equal + // to the pivot are put in the right-hand partition. Returns the position of the pivot after + // partitioning and whether the passed sequence already was correctly partitioned. Assumes the + // pivot is a median of at least 3 elements and that [begin, end) is at least + // insertion_sort_threshold long. + template + pdqsort_detail::pair partition_right(Iter begin, Iter end, Compare comp) { + typedef typename boost::movelib::iterator_traits::value_type T; + + // Move pivot into local for speed. + T pivot(boost::move(*begin)); + + Iter first = begin; + Iter last = end; + + // Find the first element greater than or equal than the pivot (the median of 3 guarantees + // this exists). + while (comp(*++first, pivot)); + + // Find the first element strictly smaller than the pivot. We have to guard this search if + // there was no element before *first. + if (first - 1 == begin) while (first < last && !comp(*--last, pivot)); + else while ( !comp(*--last, pivot)); + + // If the first pair of elements that should be swapped to partition are the same element, + // the passed in sequence already was correctly partitioned. + bool already_partitioned = first >= last; + + // Keep swapping pairs of elements that are on the wrong side of the pivot. Previously + // swapped pairs guard the searches, which is why the first iteration is special-cased + // above. + while (first < last) { + boost::adl_move_iter_swap(first, last); + while (comp(*++first, pivot)); + while (!comp(*--last, pivot)); + } + + // Put the pivot in the right place. + Iter pivot_pos = first - 1; + *begin = boost::move(*pivot_pos); + *pivot_pos = boost::move(pivot); + + return pdqsort_detail::pair(pivot_pos, already_partitioned); + } + + // Similar function to the one above, except elements equal to the pivot are put to the left of + // the pivot and it doesn't check or return if the passed sequence already was partitioned. + // Since this is rarely used (the many equal case), and in that case pdqsort already has O(n) + // performance, no block quicksort is applied here for simplicity. + template + inline Iter partition_left(Iter begin, Iter end, Compare comp) { + typedef typename boost::movelib::iterator_traits::value_type T; + + T pivot(boost::move(*begin)); + Iter first = begin; + Iter last = end; + + while (comp(pivot, *--last)); + + if (last + 1 == end) while (first < last && !comp(pivot, *++first)); + else while ( !comp(pivot, *++first)); + + while (first < last) { + boost::adl_move_iter_swap(first, last); + while (comp(pivot, *--last)); + while (!comp(pivot, *++first)); + } + + Iter pivot_pos = last; + *begin = boost::move(*pivot_pos); + *pivot_pos = boost::move(pivot); + + return pivot_pos; + } + + + template + void pdqsort_loop( Iter begin, Iter end, Compare comp + , typename boost::movelib::iterator_traits::size_type bad_allowed + , bool leftmost = true) + { + typedef typename boost::movelib::iterator_traits::size_type size_type; + + // Use a while loop for tail recursion elimination. + while (true) { + size_type size = size_type(end - begin); + + // Insertion sort is faster for small arrays. + if (size < insertion_sort_threshold) { + insertion_sort(begin, end, comp); + return; + } + + // Choose pivot as median of 3 or pseudomedian of 9. + size_type s2 = size / 2; + if (size > ninther_threshold) { + sort3(begin, begin + s2, end - 1, comp); + sort3(begin + 1, begin + (s2 - 1), end - 2, comp); + sort3(begin + 2, begin + (s2 + 1), end - 3, comp); + sort3(begin + (s2 - 1), begin + s2, begin + (s2 + 1), comp); + boost::adl_move_iter_swap(begin, begin + s2); + } else sort3(begin + s2, begin, end - 1, comp); + + // If *(begin - 1) is the end of the right partition of a previous partition operation + // there is no element in [begin, end) that is smaller than *(begin - 1). Then if our + // pivot compares equal to *(begin - 1) we change strategy, putting equal elements in + // the left partition, greater elements in the right partition. We do not have to + // recurse on the left partition, since it's sorted (all equal). + if (!leftmost && !comp(*(begin - 1), *begin)) { + begin = partition_left(begin, end, comp) + 1; + continue; + } + + // Partition and get results. + pdqsort_detail::pair part_result = partition_right(begin, end, comp); + Iter pivot_pos = part_result.first; + bool already_partitioned = part_result.second; + + // Check for a highly unbalanced partition. + size_type l_size = size_type(pivot_pos - begin); + size_type r_size = size_type(end - (pivot_pos + 1)); + bool highly_unbalanced = l_size < size / 8 || r_size < size / 8; + + // If we got a highly unbalanced partition we shuffle elements to break many patterns. + if (highly_unbalanced) { + // If we had too many bad partitions, switch to heapsort to guarantee O(n log n). + if (--bad_allowed == 0) { + boost::movelib::heap_sort(begin, end, comp); + return; + } + + if (l_size >= insertion_sort_threshold) { + boost::adl_move_iter_swap(begin, begin + l_size / 4); + boost::adl_move_iter_swap(pivot_pos - 1, pivot_pos - l_size / 4); + + if (l_size > ninther_threshold) { + boost::adl_move_iter_swap(begin + 1, begin + (l_size / 4 + 1)); + boost::adl_move_iter_swap(begin + 2, begin + (l_size / 4 + 2)); + boost::adl_move_iter_swap(pivot_pos - 2, pivot_pos - (l_size / 4 + 1)); + boost::adl_move_iter_swap(pivot_pos - 3, pivot_pos - (l_size / 4 + 2)); + } + } + + if (r_size >= insertion_sort_threshold) { + boost::adl_move_iter_swap(pivot_pos + 1, pivot_pos + (1 + r_size / 4)); + boost::adl_move_iter_swap(end - 1, end - r_size / 4); + + if (r_size > ninther_threshold) { + boost::adl_move_iter_swap(pivot_pos + 2, pivot_pos + (2 + r_size / 4)); + boost::adl_move_iter_swap(pivot_pos + 3, pivot_pos + (3 + r_size / 4)); + boost::adl_move_iter_swap(end - 2, end - (1 + r_size / 4)); + boost::adl_move_iter_swap(end - 3, end - (2 + r_size / 4)); + } + } + } else { + // If we were decently balanced and we tried to sort an already partitioned + // sequence try to use insertion sort. + if (already_partitioned && partial_insertion_sort(begin, pivot_pos, comp) + && partial_insertion_sort(pivot_pos + 1, end, comp)) return; + } + + // Sort the left partition first using recursion and do tail recursion elimination for + // the right-hand partition. + pdqsort_loop(begin, pivot_pos, comp, bad_allowed, leftmost); + begin = pivot_pos + 1; + leftmost = false; + } + } +} + + +template +void pdqsort(Iter begin, Iter end, Compare comp) +{ + if (begin == end) return; + typedef typename boost::movelib::iterator_traits::size_type size_type; + pdqsort_detail::pdqsort_loop(begin, end, comp, pdqsort_detail::log2(size_type(end - begin))); +} + +} //namespace movelib { +} //namespace boost { + +#include + +#endif //BOOST_MOVE_ALGO_PDQSORT_HPP diff --git a/autowrap/data_files/boost/move/algo/detail/set_difference.hpp b/autowrap/data_files/boost/move/algo/detail/set_difference.hpp new file mode 100644 index 00000000..c988294d --- /dev/null +++ b/autowrap/data_files/boost/move/algo/detail/set_difference.hpp @@ -0,0 +1,207 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2017. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_SET_DIFFERENCE_HPP +#define BOOST_MOVE_SET_DIFFERENCE_HPP + +#include +#include +#include + +namespace boost { + +namespace move_detail{ + +template +OutputIt copy(InputIt first, InputIt last, OutputIt result) +{ + while (first != last) { + *result++ = *first; + ++result; + ++first; + } + return result; +} + +} //namespace move_detail{ + +namespace movelib { + +//Moves the elements from the sorted range [first1, last1) which are not found in the sorted +//range [first2, last2) to the range beginning at result. +//The resulting range is also sorted. Equivalent elements are treated individually, +//that is, if some element is found m times in [first1, last1) and n times in [first2, last2), +//it will be moved to result exactly max(m-n, 0) times. +//The resulting range cannot overlap with either of the input ranges. +template +OutputIt set_difference + (InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result, Compare comp) +{ + while (first1 != last1) { + if (first2 == last2) + return boost::move_detail::copy(first1, last1, result); + + if (comp(*first1, *first2)) { + *result = *first1; + ++result; + ++first1; + } + else { + if (!comp(*first2, *first1)) { + ++first1; + } + ++first2; + } + } + return result; +} + +//Moves the elements from the sorted range [first1, last1) which are not found in the sorted +//range [first2, last2) to the range beginning at first1 (in place operation in range1). +//The resulting range is also sorted. Equivalent elements are treated individually, +//that is, if some element is found m times in [first1, last1) and n times in [first2, last2), +//it will be moved to result exactly max(m-n, 0) times. +template +InputOutputIt1 inplace_set_difference + (InputOutputIt1 first1, InputOutputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp ) +{ + while (first1 != last1) { + //Skip copying from range 1 if no element has to be skipped + if (first2 == last2){ + return last1; + } + else if (comp(*first1, *first2)){ + ++first1; + } + else{ + if (!comp(*first2, *first1)) { + InputOutputIt1 result = first1; + //An element from range 1 must be skipped, no longer an inplace operation + return boost::movelib::set_difference + ( boost::make_move_iterator(++first1) + , boost::make_move_iterator(last1) + , ++first2, last2, result, comp); + } + ++first2; + } + } + return first1; +} + +//Moves the elements from the sorted range [first1, last1) which are not found in the sorted +//range [first2, last2) to the range beginning at first1. +//The resulting range is also sorted. Equivalent elements from range 1 are moved past to end +//of the result, +//that is, if some element is found m times in [first1, last1) and n times in [first2, last2), +//it will be moved to result exactly max(m-n, 0) times. +//The resulting range cannot overlap with either of the input ranges. +template +OutputIt set_unique_difference + (ForwardIt1 first1, ForwardIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result, Compare comp) +{ + while (first1 != last1) { + if (first2 == last2){ + //unique_copy-like sequence with forward iterators but don't write i + //to result before comparing as moving *i could alter the value in i. + ForwardIt1 i = first1; + while (++first1 != last1) { + if (comp(*i, *first1)) { + *result = *i; + ++result; + i = first1; + } + } + *result = *i; + ++result; + break; + } + + if (comp(*first1, *first2)) { + //Skip equivalent elements in range1 but don't write i + //to result before comparing as moving *i could alter the value in i. + ForwardIt1 i = first1; + while (++first1 != last1) { + if (comp(*i, *first1)) { + break; + } + } + *result = *i; + ++result; + } + else { + if (comp(*first2, *first1)) { + ++first2; + } + else{ + ++first1; + } + } + } + return result; +} + +//Moves the elements from the sorted range [first1, last1) which are not found in the sorted +//range [first2, last2) to the range beginning at first1 (in place operation in range1). +//The resulting range is also sorted. Equivalent elements are treated individually, +//that is, if some element is found m times in [first1, last1) and n times in [first2, last2), +//it will be moved to result exactly max(m-n, 0) times. +template +ForwardOutputIt1 inplace_set_unique_difference + (ForwardOutputIt1 first1, ForwardOutputIt1 last1, ForwardIt2 first2, ForwardIt2 last2, Compare comp ) +{ + while (first1 != last1) { + //Skip copying from range 1 if no element has to be skipped + if (first2 == last2){ + //unique-like algorithm for the remaining range 1 + ForwardOutputIt1 result = first1; + while (++first1 != last1) { + if (comp(*result, *first1) && ++result != first1) { + *result = boost::move(*first1); + } + } + return ++result; + } + else if (comp(*first2, *first1)) { + ++first2; + } + else if (comp(*first1, *first2)){ + //skip any adjacent equivalent element in range 1 + ForwardOutputIt1 result = first1; + if (++first1 != last1 && !comp(*result, *first1)) { + //Some elements from range 1 must be skipped, no longer an inplace operation + while (++first1 != last1 && !comp(*result, *first1)){} + return boost::movelib::set_unique_difference + ( boost::make_move_iterator(first1) + , boost::make_move_iterator(last1) + , first2, last2, ++result, comp); + } + } + else{ + ForwardOutputIt1 result = first1; + //Some elements from range 1 must be skipped, no longer an inplace operation + while (++first1 != last1 && !comp(*result, *first1)){} + //An element from range 1 must be skipped, no longer an inplace operation + return boost::movelib::set_unique_difference + ( boost::make_move_iterator(first1) + , boost::make_move_iterator(last1) + , first2, last2, result, comp); + } + } + return first1; +} + + + +} //namespace movelib { +} //namespace boost { + +#endif //#define BOOST_MOVE_SET_DIFFERENCE_HPP diff --git a/autowrap/data_files/boost/move/algo/move.hpp b/autowrap/data_files/boost/move/algo/move.hpp new file mode 100644 index 00000000..5d5ba19e --- /dev/null +++ b/autowrap/data_files/boost/move/algo/move.hpp @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_ALGO_MOVE_HPP +#define BOOST_MOVE_ALGO_MOVE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +#include +#include +#include +#include + +namespace boost { + +////////////////////////////////////////////////////////////////////////////// +// +// move +// +////////////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) + + //! Effects: Moves elements in the range [first,last) into the range [result,result + (last - + //! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first), + //! performs *(result + n) = ::boost::move (*(first + n)). + //! + //! Effects: result + (last - first). + //! + //! Requires: result shall not be in the range [first,last). + //! + //! Complexity: Exactly last - first move assignments. + template // O models OutputIterator + O move(I f, I l, O result) + { + while (f != l) { + *result = ::boost::move(*f); + ++f; ++result; + } + return result; + } + + ////////////////////////////////////////////////////////////////////////////// + // + // move_backward + // + ////////////////////////////////////////////////////////////////////////////// + + //! Effects: Moves elements in the range [first,last) into the range + //! [result - (last-first),result) starting from last - 1 and proceeding to + //! first. For each positive integer n <= (last - first), + //! performs *(result - n) = ::boost::move(*(last - n)). + //! + //! Requires: result shall not be in the range [first,last). + //! + //! Returns: result - (last - first). + //! + //! Complexity: Exactly last - first assignments. + template // O models BidirectionalIterator + O move_backward(I f, I l, O result) + { + while (f != l) { + --l; --result; + *result = ::boost::move(*l); + } + return result; + } + +#else + + using ::std::move_backward; + +#endif //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE) + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; first != last; ++result, ++first) +//! new (static_cast(&*result)) +//! typename iterator_traits::value_type(boost::move(*first)); +//! \endcode +//! +//! Returns: result +template + // F models ForwardIterator +F uninitialized_move(I f, I l, F r + /// @cond +// ,typename ::boost::move_detail::enable_if::value_type> >::type* = 0 + /// @endcond + ) +{ + typedef typename boost::movelib::iterator_traits::value_type input_value_type; + + F back = r; + BOOST_TRY{ + while (f != l) { + void * const addr = static_cast(::boost::move_detail::addressof(*r)); + ::new(addr) input_value_type(::boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + boost::movelib::iterator_to_raw_pointer(back)->~input_value_type(); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +/// @cond +/* +template + // F models ForwardIterator +F uninitialized_move(I f, I l, F r, + typename ::boost::move_detail::disable_if::value_type> >::type* = 0) +{ + return std::uninitialized_copy(f, l, r); +} +*/ + +/// @endcond + +} //namespace boost { + +#include + +#endif //#ifndef BOOST_MOVE_ALGO_MOVE_HPP diff --git a/autowrap/data_files/boost/move/algo/predicate.hpp b/autowrap/data_files/boost/move/algo/predicate.hpp new file mode 100644 index 00000000..ca76b754 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/predicate.hpp @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_MOVE_ALGO_PREDICATE_HPP +#define BOOST_MOVE_ALGO_PREDICATE_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace movelib { + +template +struct antistable +{ + explicit antistable(Comp &comp) + : m_comp(comp) + {} + + antistable(const antistable & other) + : m_comp(other.m_comp) + {} + + template + bool operator()(const U &u, const V & v) + { return !m_comp(v, u); } + + const Comp &get() const + { return m_comp; } + + private: + antistable & operator=(const antistable &); + Comp &m_comp; +}; + +template +Comp unantistable(Comp comp) +{ return comp; } + +template +Comp unantistable(antistable comp) +{ return comp.get(); } + +template +class negate +{ + public: + negate() + {} + + explicit negate(Comp comp) + : m_comp(comp) + {} + + template + bool operator()(const T1& l, const T2& r) + { + return !m_comp(l, r); + } + + private: + Comp m_comp; +}; + + +template +class inverse +{ + public: + inverse() + {} + + explicit inverse(Comp comp) + : m_comp(comp) + {} + + template + bool operator()(const T1& l, const T2& r) + { + return m_comp(r, l); + } + + private: + Comp m_comp; +}; + +} //namespace movelib { +} //namespace boost { + +#endif //#define BOOST_MOVE_ALGO_PREDICATE_HPP diff --git a/autowrap/data_files/boost/move/algo/unique.hpp b/autowrap/data_files/boost/move/algo/unique.hpp new file mode 100644 index 00000000..8022a654 --- /dev/null +++ b/autowrap/data_files/boost/move/algo/unique.hpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2017. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_ALGO_UNIQUE_HPP +#define BOOST_MOVE_ALGO_UNIQUE_HPP + +#include +#include + +namespace boost { +namespace movelib { + +//! Requires: The comparison function shall be an equivalence relation. The type of *first shall satisfy +//! the MoveAssignable requirements +//! +//! Effects: For a nonempty range, eliminates all but the first element from every consecutive group +//! of equivalent elements referred to by the iterator i in the range [first + 1, last) for which the +//! following conditions hold: pred(*(i - 1), *i) != false. +//! +//! Returns: The end of the resulting range. +//! +//! Complexity: For nonempty ranges, exactly (last - first) - 1 applications of the corresponding predicate. +template +ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred) +{ + if (first != last) { + ForwardIterator next(first); + ++next; + for (; next != last; ++next, ++first) { + if (pred(*first, *next)) { //Find first equal element + while (++next != last) + if (!pred(*first, *next)) + *++first = ::boost::move(*next); + break; + } + } + ++first; + } + return first; +} + +} //namespace movelib { +} //namespace boost { + +#include + +#endif //#define BOOST_MOVE_ALGO_UNIQUE_HPP diff --git a/autowrap/data_files/boost/move/algorithm.hpp b/autowrap/data_files/boost/move/algorithm.hpp new file mode 100644 index 00000000..880d661e --- /dev/null +++ b/autowrap/data_files/boost/move/algorithm.hpp @@ -0,0 +1,167 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2012. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_ALGORITHM_HPP +#define BOOST_MOVE_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +#include +#include +#include +#include + +#include //copy, copy_backward +#include //uninitialized_copy + +namespace boost { + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_or_move +// +////////////////////////////////////////////////////////////////////////////// + +namespace move_detail { + +template + // F models ForwardIterator +inline F uninitialized_move_move_iterator(I f, I l, F r +// ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled >::type* = 0 +) +{ + return ::boost::uninitialized_move(f, l, r); +} +/* +template + // F models ForwardIterator +F uninitialized_move_move_iterator(I f, I l, F r, + typename ::boost::move_detail::disable_if< has_move_emulation_enabled >::type* = 0) +{ + return std::uninitialized_copy(f.base(), l.base(), r); +} +*/ +} //namespace move_detail { + +template + // F models ForwardIterator +inline F uninitialized_copy_or_move(I f, I l, F r, + typename ::boost::move_detail::enable_if< move_detail::is_move_iterator >::type* = 0) +{ + return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r); +} + +////////////////////////////////////////////////////////////////////////////// +// +// copy_or_move +// +////////////////////////////////////////////////////////////////////////////// + +namespace move_detail { + +template + // F models ForwardIterator +inline F move_move_iterator(I f, I l, F r +// ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled >::type* = 0 +) +{ + return ::boost::move(f, l, r); +} +/* +template + // F models ForwardIterator +F move_move_iterator(I f, I l, F r, + typename ::boost::move_detail::disable_if< has_move_emulation_enabled >::type* = 0) +{ + return std::copy(f.base(), l.base(), r); +} +*/ + +} //namespace move_detail { + +template + // F models ForwardIterator +inline F copy_or_move(I f, I l, F r, + typename ::boost::move_detail::enable_if< move_detail::is_move_iterator >::type* = 0) +{ + return ::boost::move_detail::move_move_iterator(f, l, r); +} + +/// @endcond + +//! Effects: +//! \code +//! for (; first != last; ++result, ++first) +//! new (static_cast(&*result)) +//! typename iterator_traits::value_type(*first); +//! \endcode +//! +//! Returns: result +//! +//! Note: This function is provided because +//! std::uninitialized_copy from some STL implementations +//! is not compatible with move_iterator +template + // F models ForwardIterator +inline F uninitialized_copy_or_move(I f, I l, F r + /// @cond + ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator >::type* = 0 + /// @endcond + ) +{ + return std::uninitialized_copy(f, l, r); +} + +//! Effects: +//! \code +//! for (; first != last; ++result, ++first) +//! *result = *first; +//! \endcode +//! +//! Returns: result +//! +//! Note: This function is provided because +//! std::uninitialized_copy from some STL implementations +//! is not compatible with move_iterator +template + // F models ForwardIterator +inline F copy_or_move(I f, I l, F r + /// @cond + ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator >::type* = 0 + /// @endcond + ) +{ + return std::copy(f, l, r); +} + +} //namespace boost { + +#include + +#endif //#ifndef BOOST_MOVE_ALGORITHM_HPP diff --git a/autowrap/data_files/boost/move/core.hpp b/autowrap/data_files/boost/move/core.hpp new file mode 100644 index 00000000..b34740dc --- /dev/null +++ b/autowrap/data_files/boost/move/core.hpp @@ -0,0 +1,494 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2012. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file +//! This header implements macros to define movable classes and +//! move-aware functions + +#ifndef BOOST_MOVE_CORE_HPP +#define BOOST_MOVE_CORE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// @cond + +//boost_move_no_copy_constructor_or_assign typedef +//used to detect noncopyable types for other Boost libraries. +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ + private:\ + TYPE(TYPE &);\ + TYPE& operator=(TYPE &);\ + public:\ + typedef int boost_move_no_copy_constructor_or_assign; \ + private:\ + // +#else + #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \ + public:\ + TYPE(TYPE const &) = delete;\ + TYPE& operator=(TYPE const &) = delete;\ + public:\ + typedef int boost_move_no_copy_constructor_or_assign; \ + private:\ + // +#endif //BOOST_NO_CXX11_DELETED_FUNCTIONS + +// @endcond + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED) + + #include + + #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast(ARG) + + //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers + #if defined(BOOST_GCC) && (BOOST_GCC >= 40400) && (BOOST_GCC < 40500) + #define BOOST_RV_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS + #else + #define BOOST_RV_ATTRIBUTE_MAY_ALIAS + #endif + + namespace boost { + + ////////////////////////////////////////////////////////////////////////////// + // + // struct rv + // + ////////////////////////////////////////////////////////////////////////////// + template + class BOOST_RV_ATTRIBUTE_MAY_ALIAS rv + : public ::boost::move_detail::if_c + < ::boost::move_detail::is_class::value + , T + , ::boost::move_detail::nat + >::type + { + rv(); + ~rv() throw(); + rv(rv const&); + void operator=(rv const&); + }; + + + ////////////////////////////////////////////////////////////////////////////// + // + // is_rv + // + ////////////////////////////////////////////////////////////////////////////// + + namespace move_detail { + + template + struct is_rv + //Derive from integral constant because some Boost code assummes it has + //a "type" internal typedef + : integral_constant::value > + {}; + + template + struct is_not_rv + { + static const bool value = !is_rv::value; + }; + + } //namespace move_detail { + + ////////////////////////////////////////////////////////////////////////////// + // + // has_move_emulation_enabled + // + ////////////////////////////////////////////////////////////////////////////// + template + struct has_move_emulation_enabled + : ::boost::move_detail::has_move_emulation_enabled_impl + {}; + + template + struct has_move_emulation_disabled + { + static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl::value; + }; + + } //namespace boost { + + #define BOOST_RV_REF(TYPE)\ + ::boost::rv< TYPE >& \ + // + + #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + ::boost::rv< TYPE >& \ + // + + #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + ::boost::rv< TYPE >& \ + // + + #define BOOST_RV_REF_BEG\ + ::boost::rv< \ + // + + #define BOOST_RV_REF_END\ + >& \ + // + + #define BOOST_RV_REF_BEG_IF_CXX11 \ + \ + // + + #define BOOST_RV_REF_END_IF_CXX11 \ + \ + // + + #define BOOST_FWD_REF(TYPE)\ + const TYPE & \ + // + + #define BOOST_COPY_ASSIGN_REF(TYPE)\ + const ::boost::rv< TYPE >& \ + // + + #define BOOST_COPY_ASSIGN_REF_BEG \ + const ::boost::rv< \ + // + + #define BOOST_COPY_ASSIGN_REF_END \ + >& \ + // + + #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + const ::boost::rv< TYPE >& \ + // + + #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + const ::boost::rv< TYPE >& \ + // + + #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const ::boost::rv< TYPE >& \ + // + + namespace boost { + namespace move_detail { + + template + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_lvalue_reference::value || + !::boost::has_move_emulation_enabled::value + , T&>::type + move_return(T& x) BOOST_NOEXCEPT + { + return x; + } + + template + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_lvalue_reference::value && + ::boost::has_move_emulation_enabled::value + , ::boost::rv&>::type + move_return(T& x) BOOST_NOEXCEPT + { + return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, ::boost::move_detail::addressof(x)); + } + + template + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_lvalue_reference::value && + ::boost::has_move_emulation_enabled::value + , ::boost::rv&>::type + move_return(::boost::rv& x) BOOST_NOEXCEPT + { + return x; + } + + } //namespace move_detail { + } //namespace boost { + + #define BOOST_MOVE_RET(RET_TYPE, REF)\ + boost::move_detail::move_return< RET_TYPE >(REF) + // + + #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \ + ::boost::move((BASE_TYPE&)(ARG)) + // + + ////////////////////////////////////////////////////////////////////////////// + // + // BOOST_MOVABLE_BUT_NOT_COPYABLE + // + ////////////////////////////////////////////////////////////////////////////// + #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\ + public:\ + BOOST_MOVE_FORCEINLINE operator ::boost::rv&() \ + { return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, this); }\ + BOOST_MOVE_FORCEINLINE operator const ::boost::rv&() const \ + { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv*, this); }\ + private:\ + // + + ////////////////////////////////////////////////////////////////////////////// + // + // BOOST_COPYABLE_AND_MOVABLE + // + ////////////////////////////////////////////////////////////////////////////// + + #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ + public:\ + BOOST_MOVE_FORCEINLINE TYPE& operator=(TYPE &t)\ + { this->operator=(const_cast(t)); return *this;}\ + public:\ + BOOST_MOVE_FORCEINLINE operator ::boost::rv&() \ + { return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, this); }\ + BOOST_MOVE_FORCEINLINE operator const ::boost::rv&() const \ + { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv*, this); }\ + private:\ + // + + #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ + public:\ + BOOST_MOVE_FORCEINLINE operator ::boost::rv&() \ + { return *BOOST_MOVE_TO_RV_CAST(::boost::rv*, this); }\ + BOOST_MOVE_FORCEINLINE operator const ::boost::rv&() const \ + { return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv*, this); }\ + private:\ + // + + namespace boost{ + namespace move_detail{ + + template< class T> + struct forward_type + { typedef const T &type; }; + + template< class T> + struct forward_type< boost::rv > + { typedef T type; }; + + }} + +#else //BOOST_NO_CXX11_RVALUE_REFERENCES + + //! This macro marks a type as movable but not copyable, disabling copy construction + //! and assignment. The user will need to write a move constructor/assignment as explained + //! in the documentation to fully write a movable but not copyable class. + #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ + BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\ + public:\ + typedef int boost_move_emulation_t;\ + private:\ + // + + //! This macro marks a type as copyable and movable. + //! The user will need to write a move constructor/assignment and a copy assignment + //! as explained in the documentation to fully write a copyable and movable class. + #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ + // + + #if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\ + // + #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + + namespace boost { + + //!This trait yields to a compile-time true boolean if T was marked as + //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and + //!rvalue references are not available on the platform. False otherwise. + template + struct has_move_emulation_enabled + { + static const bool value = false; + }; + + template + struct has_move_emulation_disabled + { + static const bool value = true; + }; + + } //namespace boost{ + + //!This macro is used to achieve portable syntax in move + //!constructors and assignments for classes marked as + //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE + #define BOOST_RV_REF(TYPE)\ + TYPE && \ + // + + //!This macro is used to achieve portable syntax in move + //!constructors and assignments for template classes marked as + //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE. + //!As macros have problems with comma-separated template arguments, + //!the template argument must be preceded with BOOST_RV_REF_BEG + //!and ended with BOOST_RV_REF_END + #define BOOST_RV_REF_BEG\ + \ + // + + //!This macro is used to achieve portable syntax in move + //!constructors and assignments for template classes marked as + //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE. + //!As macros have problems with comma-separated template arguments, + //!the template argument must be preceded with BOOST_RV_REF_BEG + //!and ended with BOOST_RV_REF_END + #define BOOST_RV_REF_END\ + && \ + // + + //!This macro expands to BOOST_RV_REF_BEG if BOOST_NO_CXX11_RVALUE_REFERENCES + //!is not defined, empty otherwise + #define BOOST_RV_REF_BEG_IF_CXX11 \ + BOOST_RV_REF_BEG \ + // + + //!This macro expands to BOOST_RV_REF_END if BOOST_NO_CXX11_RVALUE_REFERENCES + //!is not defined, empty otherwise + #define BOOST_RV_REF_END_IF_CXX11 \ + BOOST_RV_REF_END \ + // + + //!This macro is used to achieve portable syntax in copy + //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE. + #define BOOST_COPY_ASSIGN_REF(TYPE)\ + const TYPE & \ + // + + //! This macro is used to implement portable perfect forwarding + //! as explained in the documentation. + #define BOOST_FWD_REF(TYPE)\ + TYPE && \ + // + + #if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + + #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + TYPE && \ + // + + #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + TYPE && \ + // + + #define BOOST_COPY_ASSIGN_REF_BEG \ + const \ + // + + #define BOOST_COPY_ASSIGN_REF_END \ + & \ + // + + #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\ + const TYPE & \ + // + + #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\ + const TYPE& \ + // + + #define BOOST_CATCH_CONST_RLVALUE(TYPE)\ + const TYPE & \ + // + + #endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED) + + #if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED) + + //!This macro is used to achieve portable move return semantics. + //!The C++11 Standard allows implicit move returns when the object to be returned + //!is designated by a lvalue and: + //! - The criteria for elision of a copy operation are met OR + //! - The criteria would be met save for the fact that the source object is a function parameter + //! + //!For C++11 conforming compilers this macros only yields to REF: + //! return BOOST_MOVE_RET(RET_TYPE, REF); -> return REF; + //! + //!For compilers without rvalue references + //!this macro does an explicit move if the move emulation is activated + //!and the return type (RET_TYPE) is not a reference. + //! + //!For non-conforming compilers with rvalue references like Visual 2010 & 2012, + //!an explicit move is performed if RET_TYPE is not a reference. + //! + //! Caution: When using this macro in non-conforming or C++03 + //!compilers, a move will be performed even if the C++11 standard does not allow it + //!(e.g. returning a static variable). The user is responsible for using this macro + //!only to return local objects that met C++11 criteria. + #define BOOST_MOVE_RET(RET_TYPE, REF)\ + REF + // + + #else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED) + + #include + + namespace boost { + namespace move_detail { + + template + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_lvalue_reference::value + , T&>::type + move_return(T& x) BOOST_NOEXCEPT + { + return x; + } + + template + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_lvalue_reference::value + , Ret && >::type + move_return(T&& t) BOOST_NOEXCEPT + { + return static_cast< Ret&& >(t); + } + + } //namespace move_detail { + } //namespace boost { + + #define BOOST_MOVE_RET(RET_TYPE, REF)\ + boost::move_detail::move_return< RET_TYPE >(REF) + // + + #endif //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED) + + //!This macro is used to achieve portable optimal move constructors. + //! + //!When implementing the move constructor, in C++03 compilers the moved-from argument must be + //!cast to the base type before calling `::boost::move()` due to rvalue reference limitations. + //! + //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of + //!a base type is implicit. + #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \ + ::boost::move((BASE_TYPE&)(ARG)) + // + + namespace boost { + namespace move_detail { + + template< class T> struct forward_type { typedef T type; }; + + }} + +#endif //BOOST_NO_CXX11_RVALUE_REFERENCES + +#include + +#endif //#ifndef BOOST_MOVE_CORE_HPP diff --git a/autowrap/data_files/boost/move/default_delete.hpp b/autowrap/data_files/boost/move/default_delete.hpp new file mode 100644 index 00000000..31ae67aa --- /dev/null +++ b/autowrap/data_files/boost/move/default_delete.hpp @@ -0,0 +1,217 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED +#define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +#include //For std::size_t,std::nullptr_t + +//!\file +//! Describes the default deleter (destruction policy) of unique_ptr: default_delete. + +namespace boost{ +// @cond +namespace move_upd { + +namespace bmupmu = ::boost::move_upmu; + +//////////////////////////////////////// +//// enable_def_del +//////////////////////////////////////// + +//compatible with a pointer type T*: +//When either Y* is convertible to T* +//Y is U[N] and T is U cv [] +template +struct def_del_compatible_cond + : bmupmu::is_convertible +{}; + +template +struct def_del_compatible_cond + : def_del_compatible_cond +{}; + +template +struct enable_def_del + : bmupmu::enable_if_c::value, Type> +{}; + +//////////////////////////////////////// +//// enable_defdel_call +//////////////////////////////////////// + +//When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N]; +//When 2nd is T[], 1st(*)[] shall be convertible to T(*)[]; +//Otherwise, 1st* shall be convertible to 2nd*. + +template +struct enable_defdel_call + : public enable_def_del +{}; + +template +struct enable_defdel_call + : public enable_def_del +{}; + +template +struct enable_defdel_call + : public enable_def_del +{}; + +//////////////////////////////////////// +//// Some bool literal zero conversion utilities +//////////////////////////////////////// + +struct bool_conversion {int for_bool; int for_arg(); }; +typedef int bool_conversion::* explicit_bool_arg; + +#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_CXX11_DECLTYPE) + typedef decltype(nullptr) nullptr_type; +#elif !defined(BOOST_NO_CXX11_NULLPTR) + typedef std::nullptr_t nullptr_type; +#else + typedef int (bool_conversion::*nullptr_type)(); +#endif + +template +struct is_array_del +{}; + +template +void call_delete(T *p, is_array_del) +{ + delete [] p; +} + +template +void call_delete(T *p, is_array_del) +{ + delete p; +} + +} //namespace move_upd { +// @endcond + +namespace movelib { + +namespace bmupd = boost::move_upd; +namespace bmupmu = ::boost::move_upmu; + +//!The class template default_delete serves as the default deleter +//!(destruction policy) for the class template unique_ptr. +//! +//! \tparam T The type to be deleted. It may be an incomplete type +template +struct default_delete +{ + //! Default constructor. + //! + BOOST_CONSTEXPR default_delete() + //Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6 + #if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED) + BOOST_NOEXCEPT + #endif + #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED) + = default; + #else + {}; + #endif + + #if defined(BOOST_MOVE_DOXYGEN_INVOKED) + //! Trivial copy constructor + //! + default_delete(const default_delete&) BOOST_NOEXCEPT = default; + //! Trivial assignment + //! + default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default; + #else + typedef typename bmupmu::remove_extent::type element_type; + #endif + + //! Effects: Constructs a default_delete object from another default_delete object. + //! + //! Remarks: This constructor shall not participate in overload resolution unless: + //! - If T is not an array type and U* is implicitly convertible to T*. + //! - If T is an array type and U* is a more CV qualified pointer to remove_extent::type. + template + default_delete(const default_delete& + BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del::type* =0) + ) BOOST_NOEXCEPT + { + //If T is not an array type, U derives from T + //and T has no virtual destructor, then you have a problem + BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor::value )); + } + + //! Effects: Constructs a default_delete object from another default_delete object. + //! + //! Remarks: This constructor shall not participate in overload resolution unless: + //! - If T is not an array type and U* is implicitly convertible to T*. + //! - If T is an array type and U* is a more CV qualified pointer to remove_extent::type. + template + BOOST_MOVE_DOC1ST(default_delete&, + typename bmupd::enable_def_del::type) + operator=(const default_delete&) BOOST_NOEXCEPT + { + //If T is not an array type, U derives from T + //and T has no virtual destructor, then you have a problem + BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor::value )); + return *this; + } + + //! Effects: if T is not an array type, calls delete on static_cast(ptr), + //! otherwise calls delete[] on static_cast::type*>(ptr). + //! + //! Remarks: If U is an incomplete type, the program is ill-formed. + //! This operator shall not participate in overload resolution unless: + //! - T is not an array type and U* is convertible to T*, OR + //! - T is an array type, and remove_cv::type is the same type as + //! remove_cv::type>::type and U* is convertible to remove_extent::type*. + template + BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call::type) + operator()(U* ptr) const BOOST_NOEXCEPT + { + //U must be a complete type + BOOST_STATIC_ASSERT(sizeof(U) > 0); + //If T is not an array type, U derives from T + //and T has no virtual destructor, then you have a problem + BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor::value )); + element_type * const p = static_cast(ptr); + move_upd::call_delete(p, move_upd::is_array_del::value>()); + } + + //! Effects: Same as (*this)(static_cast(nullptr)). + //! + void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT + { BOOST_STATIC_ASSERT(sizeof(element_type) > 0); } +}; + +} //namespace movelib { +} //namespace boost{ + +#include + +#endif //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED diff --git a/autowrap/data_files/boost/move/detail/config_begin.hpp b/autowrap/data_files/boost/move/detail/config_begin.hpp new file mode 100644 index 00000000..637eb158 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/config_begin.hpp @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2012. 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifdef BOOST_MSVC +# pragma warning (push) +# pragma warning (disable : 4324) // structure was padded due to __declspec(align()) +# pragma warning (disable : 4675) // "function": resolved overload was found by argument-dependent lookup +# pragma warning (disable : 4996) // "function": was declared deprecated (_CRT_SECURE_NO_DEPRECATE/_SCL_SECURE_NO_WARNINGS) +# pragma warning (disable : 4714) // "function": marked as __forceinline not inlined +# pragma warning (disable : 4127) // conditional expression is constant +#endif diff --git a/autowrap/data_files/boost/move/detail/config_end.hpp b/autowrap/data_files/boost/move/detail/config_end.hpp new file mode 100644 index 00000000..71a99e93 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/config_end.hpp @@ -0,0 +1,12 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2012. 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#if defined BOOST_MSVC +# pragma warning (pop) +#endif diff --git a/autowrap/data_files/boost/move/detail/destruct_n.hpp b/autowrap/data_files/boost/move/detail/destruct_n.hpp new file mode 100644 index 00000000..9f60fc27 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/destruct_n.hpp @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_DESTRUCT_N_HPP +#define BOOST_MOVE_DETAIL_DESTRUCT_N_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace movelib{ + +template +class destruct_n +{ + public: + explicit destruct_n(RandItUninit raw) + : m_ptr(raw), m_size() + {} + + void incr() + { + ++m_size; + } + + void incr(std::size_t n) + { + m_size += n; + } + + void release() + { + m_size = 0u; + } + + ~destruct_n() + { + while(m_size--){ + m_ptr[m_size].~T(); + } + } + private: + RandItUninit m_ptr; + std::size_t m_size; +}; + +}} //namespace boost { namespace movelib{ + +#endif //#ifndef BOOST_MOVE_DETAIL_DESTRUCT_N_HPP diff --git a/autowrap/data_files/boost/move/detail/fwd_macros.hpp b/autowrap/data_files/boost/move/detail/fwd_macros.hpp new file mode 100644 index 00000000..a5df5f1b --- /dev/null +++ b/autowrap/data_files/boost/move/detail/fwd_macros.hpp @@ -0,0 +1,881 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. 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_MOVE_DETAIL_FWD_MACROS_HPP +#define BOOST_MOVE_DETAIL_FWD_MACROS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace move_detail { + +template struct unvoid { typedef T type; }; +template <> struct unvoid { struct type { }; }; +template <> struct unvoid { struct type { }; }; + +} //namespace move_detail { +} //namespace boost { + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG) + +namespace boost { +namespace move_detail { + + template + struct mref; + + template + struct mref + { + explicit mref(T &t) : t_(t){} + T &t_; + T & get() { return t_; } + }; + + template + struct mref + { + explicit mref(T &&t) : t_(t) {} + T &t_; + T &&get() { return ::boost::move(t_); } + }; + +} //namespace move_detail { +} //namespace boost { + +#endif //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG +#endif //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +//BOOST_MOVE_REPEATN(MACRO) +#define BOOST_MOVE_REPEAT(x, MACRO) BOOST_MOVE_REPEAT_I(x,MACRO) +#define BOOST_MOVE_REPEAT_I(x, MACRO) BOOST_MOVE_REPEAT##x(MACRO) +#define BOOST_MOVE_REPEAT0(MACRO) +#define BOOST_MOVE_REPEAT1(MACRO) MACRO +#define BOOST_MOVE_REPEAT2(MACRO) BOOST_MOVE_REPEAT1(MACRO), MACRO +#define BOOST_MOVE_REPEAT3(MACRO) BOOST_MOVE_REPEAT2(MACRO), MACRO +#define BOOST_MOVE_REPEAT4(MACRO) BOOST_MOVE_REPEAT3(MACRO), MACRO +#define BOOST_MOVE_REPEAT5(MACRO) BOOST_MOVE_REPEAT4(MACRO), MACRO +#define BOOST_MOVE_REPEAT6(MACRO) BOOST_MOVE_REPEAT5(MACRO), MACRO +#define BOOST_MOVE_REPEAT7(MACRO) BOOST_MOVE_REPEAT6(MACRO), MACRO +#define BOOST_MOVE_REPEAT8(MACRO) BOOST_MOVE_REPEAT7(MACRO), MACRO +#define BOOST_MOVE_REPEAT9(MACRO) BOOST_MOVE_REPEAT8(MACRO), MACRO +#define BOOST_MOVE_REPEAT10(MACRO) BOOST_MOVE_REPEAT9(MACRO), MACRO +#define BOOST_MOVE_REPEAT11(MACRO) BOOST_MOVE_REPEAT10(MACRO), MACRO +#define BOOST_MOVE_REPEAT12(MACRO) BOOST_MOVE_REPEAT11(MACRO), MACRO +#define BOOST_MOVE_REPEAT13(MACRO) BOOST_MOVE_REPEAT12(MACRO), MACRO + +//BOOST_MOVE_FWDN +#define BOOST_MOVE_FWD0 +#define BOOST_MOVE_FWD1 ::boost::forward(p0) +#define BOOST_MOVE_FWD2 BOOST_MOVE_FWD1, ::boost::forward(p1) +#define BOOST_MOVE_FWD3 BOOST_MOVE_FWD2, ::boost::forward(p2) +#define BOOST_MOVE_FWD4 BOOST_MOVE_FWD3, ::boost::forward(p3) +#define BOOST_MOVE_FWD5 BOOST_MOVE_FWD4, ::boost::forward(p4) +#define BOOST_MOVE_FWD6 BOOST_MOVE_FWD5, ::boost::forward(p5) +#define BOOST_MOVE_FWD7 BOOST_MOVE_FWD6, ::boost::forward(p6) +#define BOOST_MOVE_FWD8 BOOST_MOVE_FWD7, ::boost::forward(p7) +#define BOOST_MOVE_FWD9 BOOST_MOVE_FWD8, ::boost::forward(p8) + +//BOOST_MOVE_FWDQN +#define BOOST_MOVE_FWDQ0 +#define BOOST_MOVE_FWDQ1 ::boost::forward(q0) +#define BOOST_MOVE_FWDQ2 BOOST_MOVE_FWDQ1, ::boost::forward(q1) +#define BOOST_MOVE_FWDQ3 BOOST_MOVE_FWDQ2, ::boost::forward(q2) +#define BOOST_MOVE_FWDQ4 BOOST_MOVE_FWDQ3, ::boost::forward(q3) +#define BOOST_MOVE_FWDQ5 BOOST_MOVE_FWDQ4, ::boost::forward(q4) +#define BOOST_MOVE_FWDQ6 BOOST_MOVE_FWDQ5, ::boost::forward(q5) +#define BOOST_MOVE_FWDQ7 BOOST_MOVE_FWDQ6, ::boost::forward(q6) +#define BOOST_MOVE_FWDQ8 BOOST_MOVE_FWDQ7, ::boost::forward(q7) +#define BOOST_MOVE_FWDQ9 BOOST_MOVE_FWDQ8, ::boost::forward(q8) + +//BOOST_MOVE_TMPL_GETN +#define BOOST_MOVE_TMPL_GET0 +#define BOOST_MOVE_TMPL_GET1 p.template get<0>() +#define BOOST_MOVE_TMPL_GET2 BOOST_MOVE_TMPL_GET1, p.template get<1>() +#define BOOST_MOVE_TMPL_GET3 BOOST_MOVE_TMPL_GET2, p.template get<2>() +#define BOOST_MOVE_TMPL_GET4 BOOST_MOVE_TMPL_GET3, p.template get<3>() +#define BOOST_MOVE_TMPL_GET5 BOOST_MOVE_TMPL_GET4, p.template get<4>() +#define BOOST_MOVE_TMPL_GET6 BOOST_MOVE_TMPL_GET5, p.template get<5>() +#define BOOST_MOVE_TMPL_GET7 BOOST_MOVE_TMPL_GET6, p.template get<6>() +#define BOOST_MOVE_TMPL_GET8 BOOST_MOVE_TMPL_GET7, p.template get<7>() +#define BOOST_MOVE_TMPL_GET9 BOOST_MOVE_TMPL_GET8, p.template get<8>() + +//BOOST_MOVE_TMPL_GETQN +#define BOOST_MOVE_TMPL_GETQ0 +#define BOOST_MOVE_TMPL_GETQ1 q.template get<0>() +#define BOOST_MOVE_TMPL_GETQ2 BOOST_MOVE_TMPL_GETQ1, q.template get<1>() +#define BOOST_MOVE_TMPL_GETQ3 BOOST_MOVE_TMPL_GETQ2, q.template get<2>() +#define BOOST_MOVE_TMPL_GETQ4 BOOST_MOVE_TMPL_GETQ3, q.template get<3>() +#define BOOST_MOVE_TMPL_GETQ5 BOOST_MOVE_TMPL_GETQ4, q.template get<4>() +#define BOOST_MOVE_TMPL_GETQ6 BOOST_MOVE_TMPL_GETQ5, q.template get<5>() +#define BOOST_MOVE_TMPL_GETQ7 BOOST_MOVE_TMPL_GETQ6, q.template get<6>() +#define BOOST_MOVE_TMPL_GETQ8 BOOST_MOVE_TMPL_GETQ7, q.template get<7>() +#define BOOST_MOVE_TMPL_GETQ9 BOOST_MOVE_TMPL_GETQ8, q.template get<8>() + +//BOOST_MOVE_GET_IDXN +#define BOOST_MOVE_GET_IDX0 +#define BOOST_MOVE_GET_IDX1 get<0>(p) +#define BOOST_MOVE_GET_IDX2 BOOST_MOVE_GET_IDX1, get<1>(p) +#define BOOST_MOVE_GET_IDX3 BOOST_MOVE_GET_IDX2, get<2>(p) +#define BOOST_MOVE_GET_IDX4 BOOST_MOVE_GET_IDX3, get<3>(p) +#define BOOST_MOVE_GET_IDX5 BOOST_MOVE_GET_IDX4, get<4>(p) +#define BOOST_MOVE_GET_IDX6 BOOST_MOVE_GET_IDX5, get<5>(p) +#define BOOST_MOVE_GET_IDX7 BOOST_MOVE_GET_IDX6, get<6>(p) +#define BOOST_MOVE_GET_IDX8 BOOST_MOVE_GET_IDX7, get<7>(p) +#define BOOST_MOVE_GET_IDX9 BOOST_MOVE_GET_IDX8, get<8>(p) + +//BOOST_MOVE_GET_IDXQN +#define BOOST_MOVE_GET_IDXQ0 +#define BOOST_MOVE_GET_IDXQ1 get<0>(q) +#define BOOST_MOVE_GET_IDXQ2 BOOST_MOVE_GET_IDXQ1, get<1>(q) +#define BOOST_MOVE_GET_IDXQ3 BOOST_MOVE_GET_IDXQ2, get<2>(q) +#define BOOST_MOVE_GET_IDXQ4 BOOST_MOVE_GET_IDXQ3, get<3>(q) +#define BOOST_MOVE_GET_IDXQ5 BOOST_MOVE_GET_IDXQ4, get<4>(q) +#define BOOST_MOVE_GET_IDXQ6 BOOST_MOVE_GET_IDXQ5, get<5>(q) +#define BOOST_MOVE_GET_IDXQ7 BOOST_MOVE_GET_IDXQ6, get<6>(q) +#define BOOST_MOVE_GET_IDXQ8 BOOST_MOVE_GET_IDXQ7, get<7>(q) +#define BOOST_MOVE_GET_IDXQ9 BOOST_MOVE_GET_IDXQ8, get<8>(q) + +//BOOST_MOVE_ARGN +#define BOOST_MOVE_ARG0 +#define BOOST_MOVE_ARG1 p0 +#define BOOST_MOVE_ARG2 BOOST_MOVE_ARG1, p1 +#define BOOST_MOVE_ARG3 BOOST_MOVE_ARG2, p2 +#define BOOST_MOVE_ARG4 BOOST_MOVE_ARG3, p3 +#define BOOST_MOVE_ARG5 BOOST_MOVE_ARG4, p4 +#define BOOST_MOVE_ARG6 BOOST_MOVE_ARG5, p5 +#define BOOST_MOVE_ARG7 BOOST_MOVE_ARG6, p6 +#define BOOST_MOVE_ARG8 BOOST_MOVE_ARG7, p7 +#define BOOST_MOVE_ARG9 BOOST_MOVE_ARG8, p8 + +//BOOST_MOVE_ARGQN +#define BOOST_MOVE_ARGQ0 +#define BOOST_MOVE_ARGQ1 q0 +#define BOOST_MOVE_ARGQ2 BOOST_MOVE_ARGQ1, q1 +#define BOOST_MOVE_ARGQ3 BOOST_MOVE_ARGQ2, q2 +#define BOOST_MOVE_ARGQ4 BOOST_MOVE_ARGQ3, q3 +#define BOOST_MOVE_ARGQ5 BOOST_MOVE_ARGQ4, q4 +#define BOOST_MOVE_ARGQ6 BOOST_MOVE_ARGQ5, q5 +#define BOOST_MOVE_ARGQ7 BOOST_MOVE_ARGQ6, q6 +#define BOOST_MOVE_ARGQ8 BOOST_MOVE_ARGQ7, q7 +#define BOOST_MOVE_ARGQ9 BOOST_MOVE_ARGQ8, q8 + +//BOOST_MOVE_DECLVALN +#define BOOST_MOVE_DECLVAL0 +#define BOOST_MOVE_DECLVAL1 ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL2 BOOST_MOVE_DECLVAL1, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL3 BOOST_MOVE_DECLVAL2, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL4 BOOST_MOVE_DECLVAL3, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL5 BOOST_MOVE_DECLVAL4, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL6 BOOST_MOVE_DECLVAL5, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL7 BOOST_MOVE_DECLVAL6, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL8 BOOST_MOVE_DECLVAL7, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVAL9 BOOST_MOVE_DECLVAL8, ::boost::move_detail::declval() + +//BOOST_MOVE_DECLVALQN +#define BOOST_MOVE_DECLVALQ0 +#define BOOST_MOVE_DECLVALQ1 ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ2 BOOST_MOVE_DECLVALQ1, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ3 BOOST_MOVE_DECLVALQ2, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ4 BOOST_MOVE_DECLVALQ3, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ5 BOOST_MOVE_DECLVALQ4, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ6 BOOST_MOVE_DECLVALQ5, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ7 BOOST_MOVE_DECLVALQ6, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ8 BOOST_MOVE_DECLVALQ7, ::boost::move_detail::declval() +#define BOOST_MOVE_DECLVALQ9 BOOST_MOVE_DECLVALQ8, ::boost::move_detail::declval() + +#ifdef BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG + #define BOOST_MOVE_MREF(T) ::boost::move_detail::mref + #define BOOST_MOVE_MFWD(N) ::boost::forward(this->m_p##N.get()) + #define BOOST_MOVE_MFWDQ(N) ::boost::forward(this->m_q##N.get()) +#else + #define BOOST_MOVE_MREF(T) BOOST_FWD_REF(T) + #define BOOST_MOVE_MFWD(N) ::boost::forward(this->m_p##N) + #define BOOST_MOVE_MFWDQ(N) ::boost::forward(this->m_q##N) +#endif +#define BOOST_MOVE_MITFWD(N) *this->m_p##N +#define BOOST_MOVE_MINC(N) ++this->m_p##N +#define BOOST_MOVE_MITFWDQ(N) *this->m_q##N +#define BOOST_MOVE_MINCQ(N) ++this->m_q##N + + +//BOOST_MOVE_MFWDN +#define BOOST_MOVE_MFWD0 +#define BOOST_MOVE_MFWD1 BOOST_MOVE_MFWD(0) +#define BOOST_MOVE_MFWD2 BOOST_MOVE_MFWD1, BOOST_MOVE_MFWD(1) +#define BOOST_MOVE_MFWD3 BOOST_MOVE_MFWD2, BOOST_MOVE_MFWD(2) +#define BOOST_MOVE_MFWD4 BOOST_MOVE_MFWD3, BOOST_MOVE_MFWD(3) +#define BOOST_MOVE_MFWD5 BOOST_MOVE_MFWD4, BOOST_MOVE_MFWD(4) +#define BOOST_MOVE_MFWD6 BOOST_MOVE_MFWD5, BOOST_MOVE_MFWD(5) +#define BOOST_MOVE_MFWD7 BOOST_MOVE_MFWD6, BOOST_MOVE_MFWD(6) +#define BOOST_MOVE_MFWD8 BOOST_MOVE_MFWD7, BOOST_MOVE_MFWD(7) +#define BOOST_MOVE_MFWD9 BOOST_MOVE_MFWD8, BOOST_MOVE_MFWD(8) + +//BOOST_MOVE_MFWDN +#define BOOST_MOVE_MFWDQ0 +#define BOOST_MOVE_MFWDQ1 BOOST_MOVE_MFWDQ(0) +#define BOOST_MOVE_MFWDQ2 BOOST_MOVE_MFWDQ1, BOOST_MOVE_MFWDQ(1) +#define BOOST_MOVE_MFWDQ3 BOOST_MOVE_MFWDQ2, BOOST_MOVE_MFWDQ(2) +#define BOOST_MOVE_MFWDQ4 BOOST_MOVE_MFWDQ3, BOOST_MOVE_MFWDQ(3) +#define BOOST_MOVE_MFWDQ5 BOOST_MOVE_MFWDQ4, BOOST_MOVE_MFWDQ(4) +#define BOOST_MOVE_MFWDQ6 BOOST_MOVE_MFWDQ5, BOOST_MOVE_MFWDQ(5) +#define BOOST_MOVE_MFWDQ7 BOOST_MOVE_MFWDQ6, BOOST_MOVE_MFWDQ(6) +#define BOOST_MOVE_MFWDQ8 BOOST_MOVE_MFWDQ7, BOOST_MOVE_MFWDQ(7) +#define BOOST_MOVE_MFWDQ9 BOOST_MOVE_MFWDQ8, BOOST_MOVE_MFWDQ(8) + +//BOOST_MOVE_MINCN +#define BOOST_MOVE_MINC0 +#define BOOST_MOVE_MINC1 BOOST_MOVE_MINC(0) +#define BOOST_MOVE_MINC2 BOOST_MOVE_MINC1, BOOST_MOVE_MINC(1) +#define BOOST_MOVE_MINC3 BOOST_MOVE_MINC2, BOOST_MOVE_MINC(2) +#define BOOST_MOVE_MINC4 BOOST_MOVE_MINC3, BOOST_MOVE_MINC(3) +#define BOOST_MOVE_MINC5 BOOST_MOVE_MINC4, BOOST_MOVE_MINC(4) +#define BOOST_MOVE_MINC6 BOOST_MOVE_MINC5, BOOST_MOVE_MINC(5) +#define BOOST_MOVE_MINC7 BOOST_MOVE_MINC6, BOOST_MOVE_MINC(6) +#define BOOST_MOVE_MINC8 BOOST_MOVE_MINC7, BOOST_MOVE_MINC(7) +#define BOOST_MOVE_MINC9 BOOST_MOVE_MINC8, BOOST_MOVE_MINC(8) + +//BOOST_MOVE_MINCQN +#define BOOST_MOVE_MINCQ0 +#define BOOST_MOVE_MINCQ1 BOOST_MOVE_MINCQ(0) +#define BOOST_MOVE_MINCQ2 BOOST_MOVE_MINCQ1, BOOST_MOVE_MINCQ(1) +#define BOOST_MOVE_MINCQ3 BOOST_MOVE_MINCQ2, BOOST_MOVE_MINCQ(2) +#define BOOST_MOVE_MINCQ4 BOOST_MOVE_MINCQ3, BOOST_MOVE_MINCQ(3) +#define BOOST_MOVE_MINCQ5 BOOST_MOVE_MINCQ4, BOOST_MOVE_MINCQ(4) +#define BOOST_MOVE_MINCQ6 BOOST_MOVE_MINCQ5, BOOST_MOVE_MINCQ(5) +#define BOOST_MOVE_MINCQ7 BOOST_MOVE_MINCQ6, BOOST_MOVE_MINCQ(6) +#define BOOST_MOVE_MINCQ8 BOOST_MOVE_MINCQ7, BOOST_MOVE_MINCQ(7) +#define BOOST_MOVE_MINCQ9 BOOST_MOVE_MINCQ8, BOOST_MOVE_MINCQ(8) + +//BOOST_MOVE_MITFWDN +#define BOOST_MOVE_MITFWD0 +#define BOOST_MOVE_MITFWD1 BOOST_MOVE_MITFWD(0) +#define BOOST_MOVE_MITFWD2 BOOST_MOVE_MITFWD1, BOOST_MOVE_MITFWD(1) +#define BOOST_MOVE_MITFWD3 BOOST_MOVE_MITFWD2, BOOST_MOVE_MITFWD(2) +#define BOOST_MOVE_MITFWD4 BOOST_MOVE_MITFWD3, BOOST_MOVE_MITFWD(3) +#define BOOST_MOVE_MITFWD5 BOOST_MOVE_MITFWD4, BOOST_MOVE_MITFWD(4) +#define BOOST_MOVE_MITFWD6 BOOST_MOVE_MITFWD5, BOOST_MOVE_MITFWD(5) +#define BOOST_MOVE_MITFWD7 BOOST_MOVE_MITFWD6, BOOST_MOVE_MITFWD(6) +#define BOOST_MOVE_MITFWD8 BOOST_MOVE_MITFWD7, BOOST_MOVE_MITFWD(7) +#define BOOST_MOVE_MITFWD9 BOOST_MOVE_MITFWD8, BOOST_MOVE_MITFWD(8) + +//BOOST_MOVE_MITFWDQN +#define BOOST_MOVE_MITFWDQ0 +#define BOOST_MOVE_MITFWDQ1 BOOST_MOVE_MITFWDQ(0) +#define BOOST_MOVE_MITFWDQ2 BOOST_MOVE_MITFWDQ1, BOOST_MOVE_MITFWDQ(1) +#define BOOST_MOVE_MITFWDQ3 BOOST_MOVE_MITFWDQ2, BOOST_MOVE_MITFWDQ(2) +#define BOOST_MOVE_MITFWDQ4 BOOST_MOVE_MITFWDQ3, BOOST_MOVE_MITFWDQ(3) +#define BOOST_MOVE_MITFWDQ5 BOOST_MOVE_MITFWDQ4, BOOST_MOVE_MITFWDQ(4) +#define BOOST_MOVE_MITFWDQ6 BOOST_MOVE_MITFWDQ5, BOOST_MOVE_MITFWDQ(5) +#define BOOST_MOVE_MITFWDQ7 BOOST_MOVE_MITFWDQ6, BOOST_MOVE_MITFWDQ(6) +#define BOOST_MOVE_MITFWDQ8 BOOST_MOVE_MITFWDQ7, BOOST_MOVE_MITFWDQ(7) +#define BOOST_MOVE_MITFWDQ9 BOOST_MOVE_MITFWDQ8, BOOST_MOVE_MITFWDQ(8) + +//BOOST_MOVE_FWD_INITN +#define BOOST_MOVE_FWD_INIT0 +#define BOOST_MOVE_FWD_INIT1 m_p0(::boost::forward(p0)) +#define BOOST_MOVE_FWD_INIT2 BOOST_MOVE_FWD_INIT1, m_p1(::boost::forward(p1)) +#define BOOST_MOVE_FWD_INIT3 BOOST_MOVE_FWD_INIT2, m_p2(::boost::forward(p2)) +#define BOOST_MOVE_FWD_INIT4 BOOST_MOVE_FWD_INIT3, m_p3(::boost::forward(p3)) +#define BOOST_MOVE_FWD_INIT5 BOOST_MOVE_FWD_INIT4, m_p4(::boost::forward(p4)) +#define BOOST_MOVE_FWD_INIT6 BOOST_MOVE_FWD_INIT5, m_p5(::boost::forward(p5)) +#define BOOST_MOVE_FWD_INIT7 BOOST_MOVE_FWD_INIT6, m_p6(::boost::forward(p6)) +#define BOOST_MOVE_FWD_INIT8 BOOST_MOVE_FWD_INIT7, m_p7(::boost::forward(p7)) +#define BOOST_MOVE_FWD_INIT9 BOOST_MOVE_FWD_INIT8, m_p8(::boost::forward(p8)) + +//BOOST_MOVE_FWD_INITQN +#define BOOST_MOVE_FWD_INITQ0 +#define BOOST_MOVE_FWD_INITQ1 m_q0(::boost::forward(q0)) +#define BOOST_MOVE_FWD_INITQ2 BOOST_MOVE_FWD_INITQ1, m_q1(::boost::forward(q1)) +#define BOOST_MOVE_FWD_INITQ3 BOOST_MOVE_FWD_INITQ2, m_q2(::boost::forward(q2)) +#define BOOST_MOVE_FWD_INITQ4 BOOST_MOVE_FWD_INITQ3, m_q3(::boost::forward(q3)) +#define BOOST_MOVE_FWD_INITQ5 BOOST_MOVE_FWD_INITQ4, m_q4(::boost::forward(q4)) +#define BOOST_MOVE_FWD_INITQ6 BOOST_MOVE_FWD_INITQ5, m_q5(::boost::forward(q5)) +#define BOOST_MOVE_FWD_INITQ7 BOOST_MOVE_FWD_INITQ6, m_q6(::boost::forward(q6)) +#define BOOST_MOVE_FWD_INITQ8 BOOST_MOVE_FWD_INITQ7, m_q7(::boost::forward(q7)) +#define BOOST_MOVE_FWD_INITQ9 BOOST_MOVE_FWD_INITQ8, m_q8(::boost::forward(q8)) + +//BOOST_MOVE_VAL_INITN +#define BOOST_MOVE_VAL_INIT0 +#define BOOST_MOVE_VAL_INIT1 m_p0(p0) +#define BOOST_MOVE_VAL_INIT2 BOOST_MOVE_VAL_INIT1, m_p1(p1) +#define BOOST_MOVE_VAL_INIT3 BOOST_MOVE_VAL_INIT2, m_p2(p2) +#define BOOST_MOVE_VAL_INIT4 BOOST_MOVE_VAL_INIT3, m_p3(p3) +#define BOOST_MOVE_VAL_INIT5 BOOST_MOVE_VAL_INIT4, m_p4(p4) +#define BOOST_MOVE_VAL_INIT6 BOOST_MOVE_VAL_INIT5, m_p5(p5) +#define BOOST_MOVE_VAL_INIT7 BOOST_MOVE_VAL_INIT6, m_p6(p6) +#define BOOST_MOVE_VAL_INIT8 BOOST_MOVE_VAL_INIT7, m_p7(p7) +#define BOOST_MOVE_VAL_INIT9 BOOST_MOVE_VAL_INIT8, m_p8(p8) + +//BOOST_MOVE_VAL_INITQN +#define BOOST_MOVE_VAL_INITQ0 +#define BOOST_MOVE_VAL_INITQ1 m_q0(q0) +#define BOOST_MOVE_VAL_INITQ2 BOOST_MOVE_VAL_INITQ1, m_q1(q1) +#define BOOST_MOVE_VAL_INITQ3 BOOST_MOVE_VAL_INITQ2, m_q2(q2) +#define BOOST_MOVE_VAL_INITQ4 BOOST_MOVE_VAL_INITQ3, m_q3(q3) +#define BOOST_MOVE_VAL_INITQ5 BOOST_MOVE_VAL_INITQ4, m_q4(q4) +#define BOOST_MOVE_VAL_INITQ6 BOOST_MOVE_VAL_INITQ5, m_q5(q5) +#define BOOST_MOVE_VAL_INITQ7 BOOST_MOVE_VAL_INITQ6, m_q6(q6) +#define BOOST_MOVE_VAL_INITQ8 BOOST_MOVE_VAL_INITQ7, m_q7(q7) +#define BOOST_MOVE_VAL_INITQ9 BOOST_MOVE_VAL_INITQ8, m_q8(q8) + +//BOOST_MOVE_UREFN +#define BOOST_MOVE_UREF0 +#define BOOST_MOVE_UREF1 BOOST_FWD_REF(P0) p0 +#define BOOST_MOVE_UREF2 BOOST_MOVE_UREF1, BOOST_FWD_REF(P1) p1 +#define BOOST_MOVE_UREF3 BOOST_MOVE_UREF2, BOOST_FWD_REF(P2) p2 +#define BOOST_MOVE_UREF4 BOOST_MOVE_UREF3, BOOST_FWD_REF(P3) p3 +#define BOOST_MOVE_UREF5 BOOST_MOVE_UREF4, BOOST_FWD_REF(P4) p4 +#define BOOST_MOVE_UREF6 BOOST_MOVE_UREF5, BOOST_FWD_REF(P5) p5 +#define BOOST_MOVE_UREF7 BOOST_MOVE_UREF6, BOOST_FWD_REF(P6) p6 +#define BOOST_MOVE_UREF8 BOOST_MOVE_UREF7, BOOST_FWD_REF(P7) p7 +#define BOOST_MOVE_UREF9 BOOST_MOVE_UREF8, BOOST_FWD_REF(P8) p8 + +//BOOST_MOVE_UREFQN +#define BOOST_MOVE_UREFQ0 +#define BOOST_MOVE_UREFQ1 BOOST_FWD_REF(Q0) q0 +#define BOOST_MOVE_UREFQ2 BOOST_MOVE_UREFQ1, BOOST_FWD_REF(Q1) q1 +#define BOOST_MOVE_UREFQ3 BOOST_MOVE_UREFQ2, BOOST_FWD_REF(Q2) q2 +#define BOOST_MOVE_UREFQ4 BOOST_MOVE_UREFQ3, BOOST_FWD_REF(Q3) q3 +#define BOOST_MOVE_UREFQ5 BOOST_MOVE_UREFQ4, BOOST_FWD_REF(Q4) q4 +#define BOOST_MOVE_UREFQ6 BOOST_MOVE_UREFQ5, BOOST_FWD_REF(Q5) q5 +#define BOOST_MOVE_UREFQ7 BOOST_MOVE_UREFQ6, BOOST_FWD_REF(Q6) q6 +#define BOOST_MOVE_UREFQ8 BOOST_MOVE_UREFQ7, BOOST_FWD_REF(Q7) q7 +#define BOOST_MOVE_UREFQ9 BOOST_MOVE_UREFQ8, BOOST_FWD_REF(Q8) q8 + +//BOOST_MOVE_VALN +#define BOOST_MOVE_VAL0 +#define BOOST_MOVE_VAL1 BOOST_FWD_REF(P0) p0 +#define BOOST_MOVE_VAL2 BOOST_MOVE_VAL1, BOOST_FWD_REF(P1) p1 +#define BOOST_MOVE_VAL3 BOOST_MOVE_VAL2, BOOST_FWD_REF(P2) p2 +#define BOOST_MOVE_VAL4 BOOST_MOVE_VAL3, BOOST_FWD_REF(P3) p3 +#define BOOST_MOVE_VAL5 BOOST_MOVE_VAL4, BOOST_FWD_REF(P4) p4 +#define BOOST_MOVE_VAL6 BOOST_MOVE_VAL5, BOOST_FWD_REF(P5) p5 +#define BOOST_MOVE_VAL7 BOOST_MOVE_VAL6, BOOST_FWD_REF(P6) p6 +#define BOOST_MOVE_VAL8 BOOST_MOVE_VAL7, BOOST_FWD_REF(P7) p7 +#define BOOST_MOVE_VAL9 BOOST_MOVE_VAL8, BOOST_FWD_REF(P8) p8 + +//BOOST_MOVE_VALQN +#define BOOST_MOVE_VALQ0 +#define BOOST_MOVE_VALQ1 BOOST_FWD_REF(Q0) q0 +#define BOOST_MOVE_VALQ2 BOOST_MOVE_VALQ1, BOOST_FWD_REF(Q1) q1 +#define BOOST_MOVE_VALQ3 BOOST_MOVE_VALQ2, BOOST_FWD_REF(Q2) q2 +#define BOOST_MOVE_VALQ4 BOOST_MOVE_VALQ3, BOOST_FWD_REF(Q3) q3 +#define BOOST_MOVE_VALQ5 BOOST_MOVE_VALQ4, BOOST_FWD_REF(Q4) q4 +#define BOOST_MOVE_VALQ6 BOOST_MOVE_VALQ5, BOOST_FWD_REF(Q5) q5 +#define BOOST_MOVE_VALQ7 BOOST_MOVE_VALQ6, BOOST_FWD_REF(Q6) q6 +#define BOOST_MOVE_VALQ8 BOOST_MOVE_VALQ7, BOOST_FWD_REF(Q7) q7 +#define BOOST_MOVE_VALQ9 BOOST_MOVE_VALQ8, BOOST_FWD_REF(Q8) q8 + + +#define BOOST_MOVE_UNVOIDCREF(T) const typename boost::move_detail::unvoid::type& +//BOOST_MOVE_CREFN +#define BOOST_MOVE_CREF0 +#define BOOST_MOVE_CREF1 BOOST_MOVE_UNVOIDCREF(P0) p0 +#define BOOST_MOVE_CREF2 BOOST_MOVE_CREF1, BOOST_MOVE_UNVOIDCREF(P1) p1 +#define BOOST_MOVE_CREF3 BOOST_MOVE_CREF2, BOOST_MOVE_UNVOIDCREF(P2) p2 +#define BOOST_MOVE_CREF4 BOOST_MOVE_CREF3, BOOST_MOVE_UNVOIDCREF(P3) p3 +#define BOOST_MOVE_CREF5 BOOST_MOVE_CREF4, BOOST_MOVE_UNVOIDCREF(P4) p4 +#define BOOST_MOVE_CREF6 BOOST_MOVE_CREF5, BOOST_MOVE_UNVOIDCREF(P5) p5 +#define BOOST_MOVE_CREF7 BOOST_MOVE_CREF6, BOOST_MOVE_UNVOIDCREF(P6) p6 +#define BOOST_MOVE_CREF8 BOOST_MOVE_CREF7, BOOST_MOVE_UNVOIDCREF(P7) p7 +#define BOOST_MOVE_CREF9 BOOST_MOVE_CREF8, BOOST_MOVE_UNVOIDCREF(P8) p8 + +//BOOST_MOVE_CREFQN +#define BOOST_MOVE_CREFQ0 +#define BOOST_MOVE_CREFQ1 BOOST_MOVE_UNVOIDCREF(Q0) q0 +#define BOOST_MOVE_CREFQ2 BOOST_MOVE_CREFQ1, BOOST_MOVE_UNVOIDCREF(Q1) q1 +#define BOOST_MOVE_CREFQ3 BOOST_MOVE_CREFQ2, BOOST_MOVE_UNVOIDCREF(Q2) q2 +#define BOOST_MOVE_CREFQ4 BOOST_MOVE_CREFQ3, BOOST_MOVE_UNVOIDCREF(Q3) q3 +#define BOOST_MOVE_CREFQ5 BOOST_MOVE_CREFQ4, BOOST_MOVE_UNVOIDCREF(Q4) q4 +#define BOOST_MOVE_CREFQ6 BOOST_MOVE_CREFQ5, BOOST_MOVE_UNVOIDCREF(Q5) q5 +#define BOOST_MOVE_CREFQ7 BOOST_MOVE_CREFQ6, BOOST_MOVE_UNVOIDCREF(Q6) q6 +#define BOOST_MOVE_CREFQ8 BOOST_MOVE_CREFQ7, BOOST_MOVE_UNVOIDCREF(Q7) q7 +#define BOOST_MOVE_CREFQ9 BOOST_MOVE_CREFQ8, BOOST_MOVE_UNVOIDCREF(Q8) q8 + +//BOOST_MOVE_CLASSN +#define BOOST_MOVE_CLASS0 +#define BOOST_MOVE_CLASS1 class P0 +#define BOOST_MOVE_CLASS2 BOOST_MOVE_CLASS1, class P1 +#define BOOST_MOVE_CLASS3 BOOST_MOVE_CLASS2, class P2 +#define BOOST_MOVE_CLASS4 BOOST_MOVE_CLASS3, class P3 +#define BOOST_MOVE_CLASS5 BOOST_MOVE_CLASS4, class P4 +#define BOOST_MOVE_CLASS6 BOOST_MOVE_CLASS5, class P5 +#define BOOST_MOVE_CLASS7 BOOST_MOVE_CLASS6, class P6 +#define BOOST_MOVE_CLASS8 BOOST_MOVE_CLASS7, class P7 +#define BOOST_MOVE_CLASS9 BOOST_MOVE_CLASS8, class P8 + +//BOOST_MOVE_CLASSQN +#define BOOST_MOVE_CLASSQ0 +#define BOOST_MOVE_CLASSQ1 class Q0 +#define BOOST_MOVE_CLASSQ2 BOOST_MOVE_CLASSQ1, class Q1 +#define BOOST_MOVE_CLASSQ3 BOOST_MOVE_CLASSQ2, class Q2 +#define BOOST_MOVE_CLASSQ4 BOOST_MOVE_CLASSQ3, class Q3 +#define BOOST_MOVE_CLASSQ5 BOOST_MOVE_CLASSQ4, class Q4 +#define BOOST_MOVE_CLASSQ6 BOOST_MOVE_CLASSQ5, class Q5 +#define BOOST_MOVE_CLASSQ7 BOOST_MOVE_CLASSQ6, class Q6 +#define BOOST_MOVE_CLASSQ8 BOOST_MOVE_CLASSQ7, class Q7 +#define BOOST_MOVE_CLASSQ9 BOOST_MOVE_CLASSQ8, class Q8 + +//BOOST_MOVE_CLASSDFLTN +#define BOOST_MOVE_CLASSDFLT0 +#define BOOST_MOVE_CLASSDFLT1 class P0 = void +#define BOOST_MOVE_CLASSDFLT2 BOOST_MOVE_CLASSDFLT1, class P1 = void +#define BOOST_MOVE_CLASSDFLT3 BOOST_MOVE_CLASSDFLT2, class P2 = void +#define BOOST_MOVE_CLASSDFLT4 BOOST_MOVE_CLASSDFLT3, class P3 = void +#define BOOST_MOVE_CLASSDFLT5 BOOST_MOVE_CLASSDFLT4, class P4 = void +#define BOOST_MOVE_CLASSDFLT6 BOOST_MOVE_CLASSDFLT5, class P5 = void +#define BOOST_MOVE_CLASSDFLT7 BOOST_MOVE_CLASSDFLT6, class P6 = void +#define BOOST_MOVE_CLASSDFLT8 BOOST_MOVE_CLASSDFLT7, class P7 = void +#define BOOST_MOVE_CLASSDFLT9 BOOST_MOVE_CLASSDFLT8, class P8 = void + +//BOOST_MOVE_CLASSDFLTQN +#define BOOST_MOVE_CLASSDFLTQ0 +#define BOOST_MOVE_CLASSDFLTQ1 class Q0 = void +#define BOOST_MOVE_CLASSDFLTQ2 BOOST_MOVE_CLASSDFLTQ1, class Q1 = void +#define BOOST_MOVE_CLASSDFLTQ3 BOOST_MOVE_CLASSDFLTQ2, class Q2 = void +#define BOOST_MOVE_CLASSDFLTQ4 BOOST_MOVE_CLASSDFLTQ3, class Q3 = void +#define BOOST_MOVE_CLASSDFLTQ5 BOOST_MOVE_CLASSDFLTQ4, class Q4 = void +#define BOOST_MOVE_CLASSDFLTQ6 BOOST_MOVE_CLASSDFLTQ5, class Q5 = void +#define BOOST_MOVE_CLASSDFLTQ7 BOOST_MOVE_CLASSDFLTQ6, class Q6 = void +#define BOOST_MOVE_CLASSDFLTQ8 BOOST_MOVE_CLASSDFLTQ7, class Q7 = void +#define BOOST_MOVE_CLASSDFLTQ9 BOOST_MOVE_CLASSDFLTQ8, class Q8 = void + +//BOOST_MOVE_LAST_TARGN +#define BOOST_MOVE_LAST_TARG0 void +#define BOOST_MOVE_LAST_TARG1 P0 +#define BOOST_MOVE_LAST_TARG2 P1 +#define BOOST_MOVE_LAST_TARG3 P2 +#define BOOST_MOVE_LAST_TARG4 P3 +#define BOOST_MOVE_LAST_TARG5 P4 +#define BOOST_MOVE_LAST_TARG6 P5 +#define BOOST_MOVE_LAST_TARG7 P6 +#define BOOST_MOVE_LAST_TARG8 P7 +#define BOOST_MOVE_LAST_TARG9 P8 + +//BOOST_MOVE_LAST_TARGQN +#define BOOST_MOVE_LAST_TARGQ0 void +#define BOOST_MOVE_LAST_TARGQ1 Q0 +#define BOOST_MOVE_LAST_TARGQ2 Q1 +#define BOOST_MOVE_LAST_TARGQ3 Q2 +#define BOOST_MOVE_LAST_TARGQ4 Q3 +#define BOOST_MOVE_LAST_TARGQ5 Q4 +#define BOOST_MOVE_LAST_TARGQ6 Q5 +#define BOOST_MOVE_LAST_TARGQ7 Q6 +#define BOOST_MOVE_LAST_TARGQ8 Q7 +#define BOOST_MOVE_LAST_TARGQ9 Q8 + + +//BOOST_MOVE_TARGN +#define BOOST_MOVE_TARG0 +#define BOOST_MOVE_TARG1 P0 +#define BOOST_MOVE_TARG2 BOOST_MOVE_TARG1, P1 +#define BOOST_MOVE_TARG3 BOOST_MOVE_TARG2, P2 +#define BOOST_MOVE_TARG4 BOOST_MOVE_TARG3, P3 +#define BOOST_MOVE_TARG5 BOOST_MOVE_TARG4, P4 +#define BOOST_MOVE_TARG6 BOOST_MOVE_TARG5, P5 +#define BOOST_MOVE_TARG7 BOOST_MOVE_TARG6, P6 +#define BOOST_MOVE_TARG8 BOOST_MOVE_TARG7, P7 +#define BOOST_MOVE_TARG9 BOOST_MOVE_TARG8, P8 + +//BOOST_MOVE_TARGQN +#define BOOST_MOVE_TARGQ0 +#define BOOST_MOVE_TARGQ1 Q0 +#define BOOST_MOVE_TARGQ2 BOOST_MOVE_TARGQ1, Q1 +#define BOOST_MOVE_TARGQ3 BOOST_MOVE_TARGQ2, Q2 +#define BOOST_MOVE_TARGQ4 BOOST_MOVE_TARGQ3, Q3 +#define BOOST_MOVE_TARGQ5 BOOST_MOVE_TARGQ4, Q4 +#define BOOST_MOVE_TARGQ6 BOOST_MOVE_TARGQ5, Q5 +#define BOOST_MOVE_TARGQ7 BOOST_MOVE_TARGQ6, Q6 +#define BOOST_MOVE_TARGQ8 BOOST_MOVE_TARGQ7, Q7 +#define BOOST_MOVE_TARGQ9 BOOST_MOVE_TARGQ8, Q8 + +//BOOST_MOVE_FWD_TN +#define BOOST_MOVE_FWD_T0 +#define BOOST_MOVE_FWD_T1 typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T2 BOOST_MOVE_FWD_T1, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T3 BOOST_MOVE_FWD_T2, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T4 BOOST_MOVE_FWD_T3, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T5 BOOST_MOVE_FWD_T4, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T6 BOOST_MOVE_FWD_T5, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T7 BOOST_MOVE_FWD_T6, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T8 BOOST_MOVE_FWD_T7, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_T9 BOOST_MOVE_FWD_T8, typename ::boost::move_detail::forward_type::type + +//BOOST_MOVE_FWD_TQN +#define BOOST_MOVE_FWD_TQ0 +#define BOOST_MOVE_FWD_TQ1 typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ2 BOOST_MOVE_FWD_TQ1, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ3 BOOST_MOVE_FWD_TQ2, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ4 BOOST_MOVE_FWD_TQ3, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ5 BOOST_MOVE_FWD_TQ4, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ6 BOOST_MOVE_FWD_TQ5, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ7 BOOST_MOVE_FWD_TQ6, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ8 BOOST_MOVE_FWD_TQ7, typename ::boost::move_detail::forward_type::type +#define BOOST_MOVE_FWD_TQ9 BOOST_MOVE_FWD_TQ8, typename ::boost::move_detail::forward_type::type + +//BOOST_MOVE_MREFX +#define BOOST_MOVE_MREF0 +#define BOOST_MOVE_MREF1 BOOST_MOVE_MREF(P0) m_p0; +#define BOOST_MOVE_MREF2 BOOST_MOVE_MREF1 BOOST_MOVE_MREF(P1) m_p1; +#define BOOST_MOVE_MREF3 BOOST_MOVE_MREF2 BOOST_MOVE_MREF(P2) m_p2; +#define BOOST_MOVE_MREF4 BOOST_MOVE_MREF3 BOOST_MOVE_MREF(P3) m_p3; +#define BOOST_MOVE_MREF5 BOOST_MOVE_MREF4 BOOST_MOVE_MREF(P4) m_p4; +#define BOOST_MOVE_MREF6 BOOST_MOVE_MREF5 BOOST_MOVE_MREF(P5) m_p5; +#define BOOST_MOVE_MREF7 BOOST_MOVE_MREF6 BOOST_MOVE_MREF(P6) m_p6; +#define BOOST_MOVE_MREF8 BOOST_MOVE_MREF7 BOOST_MOVE_MREF(P7) m_p7; +#define BOOST_MOVE_MREF9 BOOST_MOVE_MREF8 BOOST_MOVE_MREF(P8) m_p8; + +//BOOST_MOVE_MREFQX +#define BOOST_MOVE_MREFQ0 +#define BOOST_MOVE_MREFQ1 BOOST_MOVE_MREFQ(Q0) m_q0; +#define BOOST_MOVE_MREFQ2 BOOST_MOVE_MREFQ1 BOOST_MOVE_MREFQ(Q1) m_q1; +#define BOOST_MOVE_MREFQ3 BOOST_MOVE_MREFQ2 BOOST_MOVE_MREFQ(Q2) m_q2; +#define BOOST_MOVE_MREFQ4 BOOST_MOVE_MREFQ3 BOOST_MOVE_MREFQ(Q3) m_q3; +#define BOOST_MOVE_MREFQ5 BOOST_MOVE_MREFQ4 BOOST_MOVE_MREFQ(Q4) m_q4; +#define BOOST_MOVE_MREFQ6 BOOST_MOVE_MREFQ5 BOOST_MOVE_MREFQ(Q5) m_q5; +#define BOOST_MOVE_MREFQ7 BOOST_MOVE_MREFQ6 BOOST_MOVE_MREFQ(Q6) m_q6; +#define BOOST_MOVE_MREFQ8 BOOST_MOVE_MREFQ7 BOOST_MOVE_MREFQ(Q7) m_q7; +#define BOOST_MOVE_MREFQ9 BOOST_MOVE_MREFQ8 BOOST_MOVE_MREFQ(Q8) m_q8; + +//BOOST_MOVE_MEMBX +#define BOOST_MOVE_MEMB0 +#define BOOST_MOVE_MEMB1 P0 m_p0; +#define BOOST_MOVE_MEMB2 BOOST_MOVE_MEMB1 P1 m_p1; +#define BOOST_MOVE_MEMB3 BOOST_MOVE_MEMB2 P2 m_p2; +#define BOOST_MOVE_MEMB4 BOOST_MOVE_MEMB3 P3 m_p3; +#define BOOST_MOVE_MEMB5 BOOST_MOVE_MEMB4 P4 m_p4; +#define BOOST_MOVE_MEMB6 BOOST_MOVE_MEMB5 P5 m_p5; +#define BOOST_MOVE_MEMB7 BOOST_MOVE_MEMB6 P6 m_p6; +#define BOOST_MOVE_MEMB8 BOOST_MOVE_MEMB7 P7 m_p7; +#define BOOST_MOVE_MEMB9 BOOST_MOVE_MEMB8 P8 m_p8; + +//BOOST_MOVE_MEMBQX +#define BOOST_MOVE_MEMBQ0 +#define BOOST_MOVE_MEMBQ1 Q0 m_q0; +#define BOOST_MOVE_MEMBQ2 BOOST_MOVE_MEMBQ1 Q1 m_q1; +#define BOOST_MOVE_MEMBQ3 BOOST_MOVE_MEMBQ2 Q2 m_q2; +#define BOOST_MOVE_MEMBQ4 BOOST_MOVE_MEMBQ3 Q3 m_q3; +#define BOOST_MOVE_MEMBQ5 BOOST_MOVE_MEMBQ4 Q4 m_q4; +#define BOOST_MOVE_MEMBQ6 BOOST_MOVE_MEMBQ5 Q5 m_q5; +#define BOOST_MOVE_MEMBQ7 BOOST_MOVE_MEMBQ6 Q6 m_q6; +#define BOOST_MOVE_MEMBQ8 BOOST_MOVE_MEMBQ7 Q7 m_q7; +#define BOOST_MOVE_MEMBQ9 BOOST_MOVE_MEMBQ8 Q8 m_q8; + +//BOOST_MOVE_TMPL_LTN +#define BOOST_MOVE_TMPL_LT0 +#define BOOST_MOVE_TMPL_LT1 template< +#define BOOST_MOVE_TMPL_LT2 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT3 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT4 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT5 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT6 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT7 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT8 BOOST_MOVE_TMPL_LT1 +#define BOOST_MOVE_TMPL_LT9 BOOST_MOVE_TMPL_LT1 + +//BOOST_MOVE_LTN +#define BOOST_MOVE_LT0 +#define BOOST_MOVE_LT1 < +#define BOOST_MOVE_LT2 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT3 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT4 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT5 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT6 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT7 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT8 BOOST_MOVE_LT1 +#define BOOST_MOVE_LT9 BOOST_MOVE_LT1 + +//BOOST_MOVE_GTN +#define BOOST_MOVE_GT0 +#define BOOST_MOVE_GT1 > +#define BOOST_MOVE_GT2 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT3 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT4 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT5 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT6 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT7 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT8 BOOST_MOVE_GT1 +#define BOOST_MOVE_GT9 BOOST_MOVE_GT1 + +//BOOST_MOVE_LPN +#define BOOST_MOVE_LP0 +#define BOOST_MOVE_LP1 ( +#define BOOST_MOVE_LP2 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP3 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP4 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP5 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP6 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP7 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP8 BOOST_MOVE_LP1 +#define BOOST_MOVE_LP9 BOOST_MOVE_LP1 + +//BOOST_MOVE_RPN +#define BOOST_MOVE_RP0 +#define BOOST_MOVE_RP1 ) +#define BOOST_MOVE_RP2 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP3 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP4 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP5 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP6 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP7 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP8 BOOST_MOVE_RP1 +#define BOOST_MOVE_RP9 BOOST_MOVE_RP1 + +//BOOST_MOVE_IN +#define BOOST_MOVE_I0 +#define BOOST_MOVE_I1 , +#define BOOST_MOVE_I2 BOOST_MOVE_I1 +#define BOOST_MOVE_I3 BOOST_MOVE_I1 +#define BOOST_MOVE_I4 BOOST_MOVE_I1 +#define BOOST_MOVE_I5 BOOST_MOVE_I1 +#define BOOST_MOVE_I6 BOOST_MOVE_I1 +#define BOOST_MOVE_I7 BOOST_MOVE_I1 +#define BOOST_MOVE_I8 BOOST_MOVE_I1 +#define BOOST_MOVE_I9 BOOST_MOVE_I1 + +//BOOST_MOVE_BOOL +# define BOOST_MOVE_BOOL(x) BOOST_MOVE_BOOL_I(x) +# define BOOST_MOVE_BOOL_I(x) BOOST_MOVE_BOOL##x +# define BOOST_MOVE_BOOL0 0 +# define BOOST_MOVE_BOOL1 1 +# define BOOST_MOVE_BOOL2 1 +# define BOOST_MOVE_BOOL3 1 +# define BOOST_MOVE_BOOL4 1 +# define BOOST_MOVE_BOOL5 1 +# define BOOST_MOVE_BOOL6 1 +# define BOOST_MOVE_BOOL7 1 +# define BOOST_MOVE_BOOL8 1 +# define BOOST_MOVE_BOOL9 1 + +//BOOST_MOVE_I_IF +#define BOOST_MOVE_I_IF(x) BOOST_MOVE_I_IF_I (BOOST_MOVE_BOOL(x)) +#define BOOST_MOVE_I_IF_I(x) BOOST_MOVE_I_IF_I2(x) +#define BOOST_MOVE_I_IF_I2(x) BOOST_MOVE_IF_I_##x +#define BOOST_MOVE_IF_I_0 +#define BOOST_MOVE_IF_I_1 , + +//BOOST_MOVE_IF +#define BOOST_MOVE_IF(cond, t, f) BOOST_MOVE_IF_I(cond, t, f) +#define BOOST_MOVE_IF_I(cond, t, f) BOOST_MOVE_IIF(BOOST_MOVE_BOOL(cond), t, f) + +#define BOOST_MOVE_IIF(bit, t, f) BOOST_MOVE_IIF_I(bit, t, f) +#define BOOST_MOVE_IIF_I(bit, t, f) BOOST_MOVE_IIF_##bit(t, f) +#define BOOST_MOVE_IIF_0(t, f) f +#define BOOST_MOVE_IIF_1(t, f) t + +/* +#define BOOST_MOVE_IIF(bit, t, f) BOOST_MOVE_IIF_OO((bit, t, f)) +#define BOOST_MOVE_IIF_OO(par) BOOST_MOVE_IIF_I ## par +#define BOOST_MOVE_IIF_I(bit, t, f) BOOST_MOVE_IIF_II(BOOST_MOVE_IIF_ ## bit(t, f)) +#define BOOST_MOVE_IIF_II(id) id +#define BOOST_MOVE_IIF_0(t, f) f +#define BOOST_MOVE_IIF_1(t, f) t +*/ + +//BOOST_MOVE_COLON +#define BOOST_MOVE_COLON0 +#define BOOST_MOVE_COLON1 : +#define BOOST_MOVE_COLON2 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON3 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON4 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON5 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON6 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON7 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON8 BOOST_MOVE_COLON1 +#define BOOST_MOVE_COLON9 BOOST_MOVE_COLON1 + +//BOOST_MOVE_BITOR +#define BOOST_MOVE_BITOR(x,y) BOOST_MOVE_BITOR_I(x,y) +#define BOOST_MOVE_BITOR_I(x,y) BOOST_MOVE_BITOR##x##y +#define BOOST_MOVE_BITOR00 0 +#define BOOST_MOVE_BITOR01 1 +#define BOOST_MOVE_BITOR10 1 +#define BOOST_MOVE_BITOR11 1 + +//BOOST_MOVE_OR +#define BOOST_MOVE_OR(x, y) BOOST_MOVE_OR_I(x, y) +#define BOOST_MOVE_OR_I(x, y) BOOST_MOVE_BITOR(BOOST_MOVE_BOOL(x), BOOST_MOVE_BOOL(y)) + +//BOOST_MOVE_BITAND +#define BOOST_MOVE_BITAND(x,y) BOOST_MOVE_BITAND_I(x,y) +#define BOOST_MOVE_BITAND_I(x,y) BOOST_MOVE_BITAND##x##y +#define BOOST_MOVE_BITAND00 0 +#define BOOST_MOVE_BITAND01 0 +#define BOOST_MOVE_BITAND10 0 +#define BOOST_MOVE_BITAND11 1 + +//BOOST_MOVE_AND +#define BOOST_MOVE_AND(x, y) BOOST_MOVE_AND_I(x, y) +#define BOOST_MOVE_AND_I(x, y) BOOST_MOVE_BITAND(BOOST_MOVE_BOOL(x), BOOST_MOVE_BOOL(y)) + +//BOOST_MOVE_DEC +#define BOOST_MOVE_DEC(x) BOOST_MOVE_DEC_I(x) +#define BOOST_MOVE_DEC_I(x) BOOST_MOVE_DEC##x +#define BOOST_MOVE_DEC1 0 +#define BOOST_MOVE_DEC2 1 +#define BOOST_MOVE_DEC3 2 +#define BOOST_MOVE_DEC4 3 +#define BOOST_MOVE_DEC5 4 +#define BOOST_MOVE_DEC6 5 +#define BOOST_MOVE_DEC7 6 +#define BOOST_MOVE_DEC8 7 +#define BOOST_MOVE_DEC9 8 +#define BOOST_MOVE_DEC10 9 +#define BOOST_MOVE_DEC11 10 +#define BOOST_MOVE_DEC12 11 +#define BOOST_MOVE_DEC13 12 +#define BOOST_MOVE_DEC14 13 + +//BOOST_MOVE_SUB +#define BOOST_MOVE_SUB(x, y) BOOST_MOVE_SUB_I(x,y) +#define BOOST_MOVE_SUB_I(x, y) BOOST_MOVE_SUB##y(x) +#define BOOST_MOVE_SUB0(x) x +#define BOOST_MOVE_SUB1(x) BOOST_MOVE_DEC(x) +#define BOOST_MOVE_SUB2(x) BOOST_MOVE_SUB1(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB3(x) BOOST_MOVE_SUB2(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB4(x) BOOST_MOVE_SUB3(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB5(x) BOOST_MOVE_SUB4(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB6(x) BOOST_MOVE_SUB5(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB7(x) BOOST_MOVE_SUB6(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB8(x) BOOST_MOVE_SUB7(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB9(x) BOOST_MOVE_SUB8(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB10(x) BOOST_MOVE_SUB9(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB11(x) BOOST_MOVE_SUB10(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB12(x) BOOST_MOVE_SUB11(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB13(x) BOOST_MOVE_SUB12(BOOST_MOVE_DEC(x)) +#define BOOST_MOVE_SUB14(x) BOOST_MOVE_SUB13(BOOST_MOVE_DEC(x)) + +//BOOST_MOVE_INC +#define BOOST_MOVE_INC(x) BOOST_MOVE_INC_I(x) +#define BOOST_MOVE_INC_I(x) BOOST_MOVE_INC##x +#define BOOST_MOVE_INC0 1 +#define BOOST_MOVE_INC1 2 +#define BOOST_MOVE_INC2 3 +#define BOOST_MOVE_INC3 4 +#define BOOST_MOVE_INC4 5 +#define BOOST_MOVE_INC5 6 +#define BOOST_MOVE_INC6 7 +#define BOOST_MOVE_INC7 8 +#define BOOST_MOVE_INC8 9 +#define BOOST_MOVE_INC9 10 +#define BOOST_MOVE_INC10 11 +#define BOOST_MOVE_INC11 12 +#define BOOST_MOVE_INC12 13 +#define BOOST_MOVE_INC13 14 + +//BOOST_MOVE_ADD +#define BOOST_MOVE_ADD(x, y) BOOST_MOVE_ADD_I(x,y) +#define BOOST_MOVE_ADD_I(x, y) BOOST_MOVE_ADD##y(x) +#define BOOST_MOVE_ADD0(x) x +#define BOOST_MOVE_ADD1(x) BOOST_MOVE_INC(x) +#define BOOST_MOVE_ADD2(x) BOOST_MOVE_ADD1(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD3(x) BOOST_MOVE_ADD2(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD4(x) BOOST_MOVE_ADD3(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD5(x) BOOST_MOVE_ADD4(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD6(x) BOOST_MOVE_ADD5(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD7(x) BOOST_MOVE_ADD6(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD8(x) BOOST_MOVE_ADD7(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD9(x) BOOST_MOVE_ADD8(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD10(x) BOOST_MOVE_ADD9(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD11(x) BOOST_MOVE_ADD10(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD12(x) BOOST_MOVE_ADD11(BOOST_MOVE_INC(x)) +#define BOOST_MOVE_ADD13(x) BOOST_MOVE_ADD12(BOOST_MOVE_INC(x)) + +//BOOST_MOVE_ITERATE_2TON +#define BOOST_MOVE_ITERATE_2TO2(MACROFUNC) MACROFUNC(2) +#define BOOST_MOVE_ITERATE_2TO3(MACROFUNC) BOOST_MOVE_ITERATE_2TO2(MACROFUNC) MACROFUNC(3) +#define BOOST_MOVE_ITERATE_2TO4(MACROFUNC) BOOST_MOVE_ITERATE_2TO3(MACROFUNC) MACROFUNC(4) +#define BOOST_MOVE_ITERATE_2TO5(MACROFUNC) BOOST_MOVE_ITERATE_2TO4(MACROFUNC) MACROFUNC(5) +#define BOOST_MOVE_ITERATE_2TO6(MACROFUNC) BOOST_MOVE_ITERATE_2TO5(MACROFUNC) MACROFUNC(6) +#define BOOST_MOVE_ITERATE_2TO7(MACROFUNC) BOOST_MOVE_ITERATE_2TO6(MACROFUNC) MACROFUNC(7) +#define BOOST_MOVE_ITERATE_2TO8(MACROFUNC) BOOST_MOVE_ITERATE_2TO7(MACROFUNC) MACROFUNC(8) +#define BOOST_MOVE_ITERATE_2TO9(MACROFUNC) BOOST_MOVE_ITERATE_2TO8(MACROFUNC) MACROFUNC(9) + +//BOOST_MOVE_ITERATE_1TON +#define BOOST_MOVE_ITERATE_1TO1(MACROFUNC) MACROFUNC(1) +#define BOOST_MOVE_ITERATE_1TO2(MACROFUNC) BOOST_MOVE_ITERATE_1TO1(MACROFUNC) MACROFUNC(2) +#define BOOST_MOVE_ITERATE_1TO3(MACROFUNC) BOOST_MOVE_ITERATE_1TO2(MACROFUNC) MACROFUNC(3) +#define BOOST_MOVE_ITERATE_1TO4(MACROFUNC) BOOST_MOVE_ITERATE_1TO3(MACROFUNC) MACROFUNC(4) +#define BOOST_MOVE_ITERATE_1TO5(MACROFUNC) BOOST_MOVE_ITERATE_1TO4(MACROFUNC) MACROFUNC(5) +#define BOOST_MOVE_ITERATE_1TO6(MACROFUNC) BOOST_MOVE_ITERATE_1TO5(MACROFUNC) MACROFUNC(6) +#define BOOST_MOVE_ITERATE_1TO7(MACROFUNC) BOOST_MOVE_ITERATE_1TO6(MACROFUNC) MACROFUNC(7) +#define BOOST_MOVE_ITERATE_1TO8(MACROFUNC) BOOST_MOVE_ITERATE_1TO7(MACROFUNC) MACROFUNC(8) +#define BOOST_MOVE_ITERATE_1TO9(MACROFUNC) BOOST_MOVE_ITERATE_1TO8(MACROFUNC) MACROFUNC(9) + +//BOOST_MOVE_ITERATE_0TON +#define BOOST_MOVE_ITERATE_0TO0(MACROFUNC) MACROFUNC(0) +#define BOOST_MOVE_ITERATE_0TO1(MACROFUNC) BOOST_MOVE_ITERATE_0TO0(MACROFUNC) MACROFUNC(1) +#define BOOST_MOVE_ITERATE_0TO2(MACROFUNC) BOOST_MOVE_ITERATE_0TO1(MACROFUNC) MACROFUNC(2) +#define BOOST_MOVE_ITERATE_0TO3(MACROFUNC) BOOST_MOVE_ITERATE_0TO2(MACROFUNC) MACROFUNC(3) +#define BOOST_MOVE_ITERATE_0TO4(MACROFUNC) BOOST_MOVE_ITERATE_0TO3(MACROFUNC) MACROFUNC(4) +#define BOOST_MOVE_ITERATE_0TO5(MACROFUNC) BOOST_MOVE_ITERATE_0TO4(MACROFUNC) MACROFUNC(5) +#define BOOST_MOVE_ITERATE_0TO6(MACROFUNC) BOOST_MOVE_ITERATE_0TO5(MACROFUNC) MACROFUNC(6) +#define BOOST_MOVE_ITERATE_0TO7(MACROFUNC) BOOST_MOVE_ITERATE_0TO6(MACROFUNC) MACROFUNC(7) +#define BOOST_MOVE_ITERATE_0TO8(MACROFUNC) BOOST_MOVE_ITERATE_0TO7(MACROFUNC) MACROFUNC(8) +#define BOOST_MOVE_ITERATE_0TO9(MACROFUNC) BOOST_MOVE_ITERATE_0TO8(MACROFUNC) MACROFUNC(9) + +//BOOST_MOVE_ITERATE_NTON +#define BOOST_MOVE_ITERATE_1TO1(MACROFUNC) MACROFUNC(1) +#define BOOST_MOVE_ITERATE_2TO2(MACROFUNC) MACROFUNC(2) +#define BOOST_MOVE_ITERATE_3TO3(MACROFUNC) MACROFUNC(3) +#define BOOST_MOVE_ITERATE_4TO4(MACROFUNC) MACROFUNC(4) +#define BOOST_MOVE_ITERATE_5TO5(MACROFUNC) MACROFUNC(5) +#define BOOST_MOVE_ITERATE_6TO6(MACROFUNC) MACROFUNC(6) +#define BOOST_MOVE_ITERATE_7TO7(MACROFUNC) MACROFUNC(7) +#define BOOST_MOVE_ITERATE_8TO8(MACROFUNC) MACROFUNC(8) +#define BOOST_MOVE_ITERATE_9TO9(MACROFUNC) MACROFUNC(9) + +//BOOST_MOVE_ITER2D_0TOMAX +#define BOOST_MOVE_ITER2DLOW_0TOMAX0(MACROFUNC2D, M) MACROFUNC2D(M, 0) +#define BOOST_MOVE_ITER2DLOW_0TOMAX1(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX0(MACROFUNC2D, M) MACROFUNC2D(M, 1) +#define BOOST_MOVE_ITER2DLOW_0TOMAX2(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX1(MACROFUNC2D, M) MACROFUNC2D(M, 2) +#define BOOST_MOVE_ITER2DLOW_0TOMAX3(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX2(MACROFUNC2D, M) MACROFUNC2D(M, 3) +#define BOOST_MOVE_ITER2DLOW_0TOMAX4(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX3(MACROFUNC2D, M) MACROFUNC2D(M, 4) +#define BOOST_MOVE_ITER2DLOW_0TOMAX5(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX4(MACROFUNC2D, M) MACROFUNC2D(M, 5) +#define BOOST_MOVE_ITER2DLOW_0TOMAX6(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX5(MACROFUNC2D, M) MACROFUNC2D(M, 6) +#define BOOST_MOVE_ITER2DLOW_0TOMAX7(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX6(MACROFUNC2D, M) MACROFUNC2D(M, 7) +#define BOOST_MOVE_ITER2DLOW_0TOMAX8(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX7(MACROFUNC2D, M) MACROFUNC2D(M, 8) +#define BOOST_MOVE_ITER2DLOW_0TOMAX9(MACROFUNC2D, M) BOOST_MOVE_ITER2DLOW_0TOMAX8(MACROFUNC2D, M) MACROFUNC2D(M, 9) + +#define BOOST_MOVE_ITER2D_0TOMAX0(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 0) +#define BOOST_MOVE_ITER2D_0TOMAX1(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX0(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 1) +#define BOOST_MOVE_ITER2D_0TOMAX2(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX1(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 2) +#define BOOST_MOVE_ITER2D_0TOMAX3(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX2(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 3) +#define BOOST_MOVE_ITER2D_0TOMAX4(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX3(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 4) +#define BOOST_MOVE_ITER2D_0TOMAX5(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX4(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 5) +#define BOOST_MOVE_ITER2D_0TOMAX6(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX5(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 6) +#define BOOST_MOVE_ITER2D_0TOMAX7(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX6(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 7) +#define BOOST_MOVE_ITER2D_0TOMAX8(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX7(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 8) +#define BOOST_MOVE_ITER2D_0TOMAX9(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX8(MAX, MACROFUNC2D) BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 9) + +#define BOOST_MOVE_ITER2D_0TOMAX(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX_I (MAX, MACROFUNC2D) +#define BOOST_MOVE_ITER2D_0TOMAX_I(MAX, MACROFUNC2D) BOOST_MOVE_ITER2D_0TOMAX##MAX(MAX, MACROFUNC2D) + + + + +//BOOST_MOVE_CAT +#define BOOST_MOVE_CAT(a, b) BOOST_MOVE_CAT_I(a, b) +#define BOOST_MOVE_CAT_I(a, b) a ## b +//# define BOOST_MOVE_CAT_I(a, b) BOOST_MOVE_CAT_II(~, a ## b) +//# define BOOST_MOVE_CAT_II(p, res) res + +#endif //#ifndef BOOST_MOVE_DETAIL_FWD_MACROS_HPP diff --git a/autowrap/data_files/boost/move/detail/iterator_to_raw_pointer.hpp b/autowrap/data_files/boost/move/detail/iterator_to_raw_pointer.hpp new file mode 100644 index 00000000..97ee3a65 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/iterator_to_raw_pointer.hpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. 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_MOVE_DETAIL_ITERATOR_TO_RAW_POINTER_HPP +#define BOOST_MOVE_DETAIL_ITERATOR_TO_RAW_POINTER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace movelib { +namespace detail { + +template +inline T* iterator_to_pointer(T* i) +{ return i; } + +template +inline typename boost::movelib::iterator_traits::pointer + iterator_to_pointer(const Iterator &i) +{ return i.operator->(); } + +template +struct iterator_to_element_ptr +{ + typedef typename boost::movelib::iterator_traits::pointer pointer; + typedef typename boost::movelib::pointer_element::type element_type; + typedef element_type* type; +}; + +} //namespace detail { + +template +inline typename boost::movelib::detail::iterator_to_element_ptr::type + iterator_to_raw_pointer(const Iterator &i) +{ + return ::boost::movelib::to_raw_pointer + ( ::boost::movelib::detail::iterator_to_pointer(i) ); +} + +} //namespace movelib { +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TO_RAW_POINTER_HPP diff --git a/autowrap/data_files/boost/move/detail/iterator_traits.hpp b/autowrap/data_files/boost/move/detail/iterator_traits.hpp new file mode 100644 index 00000000..5ffcb2cf --- /dev/null +++ b/autowrap/data_files/boost/move/detail/iterator_traits.hpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP +#define BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +BOOST_MOVE_STD_NS_BEG + +struct input_iterator_tag; +struct forward_iterator_tag; +struct bidirectional_iterator_tag; +struct random_access_iterator_tag; +struct output_iterator_tag; + +BOOST_MOVE_STD_NS_END +#include + +namespace boost{ namespace movelib{ + +template +struct iterator_traits +{ + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; + typedef typename boost::move_detail::make_unsigned::type size_type; +}; + +template +struct iterator_traits +{ + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::random_access_iterator_tag iterator_category; + typedef typename boost::move_detail::make_unsigned::type size_type; +}; + +template +struct iterator_traits +{ + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef std::random_access_iterator_tag iterator_category; + typedef typename boost::move_detail::make_unsigned::type size_type; +}; + +}} //namespace boost { namespace movelib{ + +#endif //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP diff --git a/autowrap/data_files/boost/move/detail/meta_utils.hpp b/autowrap/data_files/boost/move/detail/meta_utils.hpp new file mode 100644 index 00000000..f16e185d --- /dev/null +++ b/autowrap/data_files/boost/move/detail/meta_utils.hpp @@ -0,0 +1,587 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2015. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP +#define BOOST_MOVE_DETAIL_META_UTILS_HPP + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +#include +#include //forceinline +#include +#include //for std::size_t + +//Small meta-typetraits to support move + +namespace boost { + +//Forward declare boost::rv +template class rv; + +namespace move_detail { + +////////////////////////////////////// +// is_different +////////////////////////////////////// +template +struct is_different +{ + static const bool value = !is_same::value; +}; + +////////////////////////////////////// +// apply +////////////////////////////////////// +template +struct apply +{ + typedef typename F::template apply::type type; +}; + +////////////////////////////////////// +// bool_ +////////////////////////////////////// + +template< bool C_ > +struct bool_ : integral_constant +{ + operator bool() const { return C_; } + bool operator()() const { return C_; } +}; + +typedef bool_ true_; +typedef bool_ false_; + +////////////////////////////////////// +// nat +////////////////////////////////////// +struct nat{}; +struct nat2{}; +struct nat3{}; + +////////////////////////////////////// +// yes_type/no_type +////////////////////////////////////// +typedef char yes_type; + +struct no_type +{ + char _[2]; +}; + +////////////////////////////////////// +// natify +////////////////////////////////////// +template struct natify{}; + +////////////////////////////////////// +// remove_reference +////////////////////////////////////// +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct remove_reference +{ + typedef T type; +}; + +#else + +template +struct remove_reference< rv > +{ + typedef T type; +}; + +template +struct remove_reference< rv &> +{ + typedef T type; +}; + +template +struct remove_reference< const rv &> +{ + typedef T type; +}; + +#endif + +////////////////////////////////////// +// remove_pointer +////////////////////////////////////// + +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer { typedef T type; }; + +////////////////////////////////////// +// add_pointer +////////////////////////////////////// +template< class T > +struct add_pointer +{ + typedef typename remove_reference::type* type; +}; + +////////////////////////////////////// +// add_const +////////////////////////////////////// +template +struct add_const +{ + typedef const T type; +}; + +template +struct add_const +{ + typedef const T& type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct add_const +{ + typedef T&& type; +}; + +#endif + +////////////////////////////////////// +// add_lvalue_reference +////////////////////////////////////// +template +struct add_lvalue_reference +{ typedef T& type; }; + +template struct add_lvalue_reference { typedef T& type; }; +template<> struct add_lvalue_reference { typedef void type; }; +template<> struct add_lvalue_reference { typedef const void type; }; +template<> struct add_lvalue_reference { typedef volatile void type; }; +template<> struct add_lvalue_reference{ typedef const volatile void type; }; + +template +struct add_const_lvalue_reference +{ + typedef typename remove_reference::type t_unreferenced; + typedef typename add_const::type t_unreferenced_const; + typedef typename add_lvalue_reference + ::type type; +}; + +////////////////////////////////////// +// is_lvalue_reference +////////////////////////////////////// +template +struct is_lvalue_reference +{ + static const bool value = false; +}; + +template +struct is_lvalue_reference +{ + static const bool value = true; +}; + + +////////////////////////////////////// +// identity +////////////////////////////////////// +template +struct identity +{ + typedef T type; + typedef typename add_const_lvalue_reference::type reference; + reference operator()(reference t) + { return t; } +}; + +////////////////////////////////////// +// is_class_or_union +////////////////////////////////////// +template +struct is_class_or_union +{ + struct twochar { char dummy[2]; }; + template + static char is_class_or_union_tester(void(U::*)(void)); + template + static twochar is_class_or_union_tester(...); + static const bool value = sizeof(is_class_or_union_tester(0)) == sizeof(char); +}; + +////////////////////////////////////// +// addressof +////////////////////////////////////// +template +struct addr_impl_ref +{ + T & v_; + BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {} + BOOST_MOVE_FORCEINLINE operator T& () const { return v_; } + + private: + addr_impl_ref & operator=(const addr_impl_ref &); +}; + +template +struct addressof_impl +{ + BOOST_MOVE_FORCEINLINE static T * f( T & v, long ) + { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } + + BOOST_MOVE_FORCEINLINE static T * f( T * v, int ) + { return v; } +}; + +template +BOOST_MOVE_FORCEINLINE T * addressof( T & v ) +{ + return ::boost::move_detail::addressof_impl::f + ( ::boost::move_detail::addr_impl_ref( v ), 0 ); +} + +////////////////////////////////////// +// has_pointer_type +////////////////////////////////////// +template +struct has_pointer_type +{ + struct two { char c[2]; }; + template static two test(...); + template static char test(typename U::pointer* = 0); + static const bool value = sizeof(test(0)) == 1; +}; + +////////////////////////////////////// +// is_convertible +////////////////////////////////////// +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + +//use intrinsic since in MSVC +//overaligned types can't go through ellipsis +template +struct is_convertible +{ + static const bool value = __is_convertible_to(T, U); +}; + +#else + +template +class is_convertible +{ + typedef typename add_lvalue_reference::type t_reference; + typedef char true_t; + class false_t { char dummy[2]; }; + static false_t dispatch(...); + static true_t dispatch(U); + static t_reference trigger(); + public: + static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); +}; + +#endif + +template ::value> +struct is_same_or_convertible + : is_convertible +{}; + +template +struct is_same_or_convertible +{ + static const bool value = true; +}; + +template< + bool C + , typename F1 + , typename F2 + > +struct eval_if_c + : if_c::type +{}; + +template< + typename C + , typename T1 + , typename T2 + > +struct eval_if + : if_::type +{}; + + +#if defined(BOOST_GCC) && (BOOST_GCC <= 40000) +#define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN +#endif + +template +struct enable_if_convertible + : enable_if< is_convertible, R> +{}; + +template +struct disable_if_convertible + : disable_if< is_convertible, R> +{}; + +template +struct enable_if_same_or_convertible + : enable_if< is_same_or_convertible, R> +{}; + +template +struct disable_if_same_or_convertible + : disable_if< is_same_or_convertible, R> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// and_ +// +////////////////////////////////////////////////////////////////////////////// +template +struct and_impl + : and_impl +{}; + +template<> +struct and_impl +{ + static const bool value = true; +}; + +template +struct and_impl +{ + static const bool value = false; +}; + +template +struct and_ + : and_impl +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// or_ +// +////////////////////////////////////////////////////////////////////////////// +template +struct or_impl + : or_impl +{}; + +template<> +struct or_impl +{ + static const bool value = false; +}; + +template +struct or_impl +{ + static const bool value = true; +}; + +template +struct or_ + : or_impl +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// not_ +// +////////////////////////////////////////////////////////////////////////////// +template +struct not_ +{ + static const bool value = !T::value; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// enable_if_and / disable_if_and / enable_if_or / disable_if_or +// +////////////////////////////////////////////////////////////////////////////// + +template +struct enable_if_and + : enable_if_c< and_::value, R> +{}; + +template +struct disable_if_and + : disable_if_c< and_::value, R> +{}; + +template +struct enable_if_or + : enable_if_c< or_::value, R> +{}; + +template +struct disable_if_or + : disable_if_c< or_::value, R> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// has_move_emulation_enabled_impl +// +////////////////////////////////////////////////////////////////////////////// +template +struct has_move_emulation_enabled_impl + : is_convertible< T, ::boost::rv& > +{}; + +template +struct has_move_emulation_enabled_impl +{ static const bool value = false; }; + +template +struct has_move_emulation_enabled_impl< ::boost::rv > +{ static const bool value = false; }; + +////////////////////////////////////////////////////////////////////////////// +// +// is_rv_impl +// +////////////////////////////////////////////////////////////////////////////// + +template +struct is_rv_impl +{ static const bool value = false; }; + +template +struct is_rv_impl< rv > +{ static const bool value = true; }; + +template +struct is_rv_impl< const rv > +{ static const bool value = true; }; + +// Code from Jeffrey Lee Hellrung, many thanks + +template< class T > +struct is_rvalue_reference +{ static const bool value = false; }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > +struct is_rvalue_reference< T&& > +{ static const bool value = true; }; + +#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > +struct is_rvalue_reference< boost::rv& > +{ static const bool value = true; }; + +template< class T > +struct is_rvalue_reference< const boost::rv& > +{ static const bool value = true; }; + +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > +struct add_rvalue_reference +{ typedef T&& type; }; + +#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +namespace detail_add_rvalue_reference +{ + template< class T + , bool emulation = has_move_emulation_enabled_impl::value + , bool rv = is_rv_impl::value > + struct add_rvalue_reference_impl { typedef T type; }; + + template< class T, bool emulation> + struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; }; + + template< class T, bool rv > + struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv& type; }; +} // namespace detail_add_rvalue_reference + +template< class T > +struct add_rvalue_reference + : detail_add_rvalue_reference::add_rvalue_reference_impl +{ }; + +template< class T > +struct add_rvalue_reference +{ typedef T & type; }; + +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > struct remove_rvalue_reference { typedef T type; }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< T&& > { typedef T type; }; +#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv& >{ typedef T type; }; +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +// Ideas from Boost.Move review, Jeffrey Lee Hellrung: +// +//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? +// Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue +// references the same as wrt real rvalue references, i.e., add_reference< rv& > -> T& rather than +// rv& (since T&& & -> T&). +// +//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...? +// +//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated +// rvalue references in C++03. This may be necessary to prevent "accidental moves". + +} //namespace move_detail { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP diff --git a/autowrap/data_files/boost/move/detail/meta_utils_core.hpp b/autowrap/data_files/boost/move/detail/meta_utils_core.hpp new file mode 100644 index 00000000..4e116738 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/meta_utils_core.hpp @@ -0,0 +1,137 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2015. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP +#define BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//Small meta-typetraits to support move + +namespace boost { +namespace move_detail { + +template +struct voider { typedef void type; }; + +////////////////////////////////////// +// if_c +////////////////////////////////////// +template +struct if_c +{ + typedef T1 type; +}; + +template +struct if_c +{ + typedef T2 type; +}; + +////////////////////////////////////// +// if_ +////////////////////////////////////// +template +struct if_ : if_c<0 != T1::value, T2, T3> +{}; + +////////////////////////////////////// +// enable_if_c +////////////////////////////////////// +struct enable_if_nat{}; + +template +struct enable_if_c +{ + typedef T type; +}; + +template +struct enable_if_c {}; + +////////////////////////////////////// +// enable_if +////////////////////////////////////// +template +struct enable_if : enable_if_c {}; + +////////////////////////////////////// +// disable_if_c +////////////////////////////////////// +template +struct disable_if_c + : enable_if_c +{}; + +////////////////////////////////////// +// disable_if +////////////////////////////////////// +template +struct disable_if : enable_if_c {}; + +////////////////////////////////////// +// integral_constant +////////////////////////////////////// +template +struct integral_constant +{ + static const T value = v; + typedef T value_type; + typedef integral_constant type; + + operator T() const { return value; } + T operator()() const { return value; } +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + + +////////////////////////////////////// +// is_same +////////////////////////////////////// +template +struct is_same +{ + static const bool value = false; +}; + +template +struct is_same +{ + static const bool value = true; +}; + +////////////////////////////////////// +// enable_if_same +////////////////////////////////////// +template +struct enable_if_same : enable_if, R> {}; + +////////////////////////////////////// +// disable_if_same +////////////////////////////////////// +template +struct disable_if_same : disable_if, R> {}; + +} //namespace move_detail { +} //namespace boost { + +#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP diff --git a/autowrap/data_files/boost/move/detail/move_helpers.hpp b/autowrap/data_files/boost/move/detail/move_helpers.hpp new file mode 100644 index 00000000..17138444 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/move_helpers.hpp @@ -0,0 +1,256 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2010-2016. +// 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_MOVE_HELPERS_HPP +#define BOOST_MOVE_MOVE_HELPERS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +#define BOOST_MOVE_CATCH_CONST(U) \ + typename ::boost::move_detail::if_< ::boost::move_detail::is_class, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type +#define BOOST_MOVE_CATCH_RVALUE(U)\ + typename ::boost::move_detail::if_< ::boost::move_detail::is_class, BOOST_RV_REF(U), ::boost::move_detail::nat>::type +#define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U) +#else +#define BOOST_MOVE_CATCH_CONST(U) const U & +#define BOOST_MOVE_CATCH_RVALUE(U) U && +#define BOOST_MOVE_CATCH_FWD(U) U && +#endif + +//////////////////////////////////////// +// +// BOOST_MOVE_CONVERSION_AWARE_CATCH +// +//////////////////////////////////////// + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + + template + struct boost_move_conversion_aware_catch_1 + : public ::boost::move_detail::enable_if_and + < RETURN_VALUE + , ::boost::move_detail::is_same + , ::boost::move_detail::is_class + , ::boost::has_move_emulation_disabled + > + {}; + + template + struct boost_move_conversion_aware_catch_2 + : public ::boost::move_detail::disable_if_or + < RETURN_VALUE + , ::boost::move_detail::is_same + , ::boost::move_detail::is_rv_impl + , ::boost::move_detail::and_ + < ::boost::move_detail::is_rv_impl + , ::boost::move_detail::is_class + > + > + {}; + + #define BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(static_cast(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(::boost::move(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(TYPE &x)\ + { return FWD_FUNCTION(const_cast(x)); }\ + // + #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN) + #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + \ + template\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u,\ + typename boost_move_conversion_aware_catch_1< ::boost::move_detail::nat, BOOST_MOVE_TEMPL_PARAM, TYPE>::type* = 0)\ + { return FWD_FUNCTION(u); }\ + \ + template\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u,\ + typename boost_move_conversion_aware_catch_2< ::boost::move_detail::nat, BOOST_MOVE_TEMPL_PARAM, TYPE>::type* = 0)\ + {\ + TYPE t((u));\ + return FWD_FUNCTION(::boost::move(t));\ + }\ + // + #else + #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + \ + template\ + BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1::type\ + PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ + { return FWD_FUNCTION(u); }\ + \ + template\ + BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_2::type\ + PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t((u));\ + return FWD_FUNCTION(::boost::move(t));\ + }\ + // + #endif +#elif (defined(_MSC_VER) && (_MSC_VER == 1600)) + + #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(static_cast(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(::boost::move(x)); }\ + \ + template\ + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c\ + < !::boost::move_detail::is_same::value\ + , RETURN_VALUE >::type\ + PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t((u));\ + return FWD_FUNCTION(::boost::move(t));\ + }\ + // + +#else //BOOST_NO_CXX11_RVALUE_REFERENCES + + #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(x); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(::boost::move(x)); }\ + // + +#endif //BOOST_NO_CXX11_RVALUE_REFERENCES + +//////////////////////////////////////// +// +// BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG +// +//////////////////////////////////////// + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + + template + struct boost_move_conversion_aware_catch_1arg_1 + : public ::boost::move_detail::enable_if_and + < RETURN_VALUE + , ::boost::move_detail::not_< ::boost::move_detail::is_same_or_convertible > + , ::boost::move_detail::is_same + , ::boost::has_move_emulation_disabled + > + {}; + + template + struct boost_move_conversion_aware_catch_1arg_2 + : public ::boost::move_detail::disable_if_or + < RETURN_VALUE + , ::boost::move_detail::is_same_or_convertible< BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> + , ::boost::move_detail::is_rv_impl + , ::boost::move_detail::is_same + > + {}; + + #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(arg1, static_cast(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, TYPE &x)\ + { return FWD_FUNCTION(arg1, const_cast(x)); }\ + // + #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN) + #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + \ + template\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u,\ + typename boost_move_conversion_aware_catch_1arg_1::type* = 0)\ + { return FWD_FUNCTION(arg1, u); }\ + \ + template\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u,\ + typename boost_move_conversion_aware_catch_1arg_2::type* = 0)\ + {\ + TYPE t((u));\ + return FWD_FUNCTION(arg1, ::boost::move(t));\ + }\ + // + #else + #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + \ + template\ + BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1arg_1::type\ + PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ + { return FWD_FUNCTION(arg1, u); }\ + \ + template\ + BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1arg_2::type\ + PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t((u));\ + return FWD_FUNCTION(arg1, ::boost::move(t));\ + }\ + // + #endif + +#elif (defined(_MSC_VER) && (_MSC_VER == 1600)) + + #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(arg1, static_cast(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ + \ + template\ + BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::disable_if_or\ + < RETURN_VALUE \ + , ::boost::move_detail::is_same \ + , ::boost::move_detail::is_same_or_convertible \ + >::type\ + PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\ + {\ + TYPE t((u));\ + return FWD_FUNCTION(arg1, ::boost::move(t));\ + }\ + // + +#else + + #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\ + { return FWD_FUNCTION(arg1, static_cast(x)); }\ + \ + BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \ + { return FWD_FUNCTION(arg1, ::boost::move(x)); }\ + // + +#endif + +#endif //#ifndef BOOST_MOVE_MOVE_HELPERS_HPP diff --git a/autowrap/data_files/boost/move/detail/placement_new.hpp b/autowrap/data_files/boost/move/detail/placement_new.hpp new file mode 100644 index 00000000..69d33328 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/placement_new.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_MOVE_DETAIL_PLACEMENT_NEW_HPP +#define BOOST_MOVE_DETAIL_PLACEMENT_NEW_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. 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_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +struct boost_move_new_t{}; + +//avoid including +inline void *operator new(std::size_t, void *p, boost_move_new_t) +{ return p; } + +inline void operator delete(void *, void *, boost_move_new_t) +{} + +#endif //BOOST_MOVE_DETAIL_PLACEMENT_NEW_HPP diff --git a/autowrap/data_files/boost/move/detail/pointer_element.hpp b/autowrap/data_files/boost/move/detail/pointer_element.hpp new file mode 100644 index 00000000..ecdd6080 --- /dev/null +++ b/autowrap/data_files/boost/move/detail/pointer_element.hpp @@ -0,0 +1,168 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2017. 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/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP +#define BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP +#include +#endif //BOOST_MOVE_DETAIL_WORKAROUND_HPP + +namespace boost { +namespace movelib { +namespace detail{ + +////////////////////// +//struct first_param +////////////////////// + +template struct first_param +{ typedef void type; }; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template