blob: 37844f1212fc020ab97cd6332f44e12a6ad72909 [file] [log] [blame]
// -*- C++ -*-
/***************************************************************************
*
* _specialized.h - definitions of specialized algorithms
*
* This is an internal header file used to implement the C++ Standard
* Library. It should never be #included directly by a program.
*
* $Id$
*
***************************************************************************
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
***************************************************************************
*
* Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
* Software division. Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0. Unless required by
* applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under
* the License.
*
**************************************************************************/
#ifndef _RWSTD_SPECIALIZED_H_INCLUDED
#define _RWSTD_SPECIALIZED_H_INCLUDED
#include <rw/_new.h>
#include <rw/_defs.h>
_RWSTD_NAMESPACE (__rw) {
#ifndef _RWSTD_NO_NONDEDUCED_CONTEXT
# define _RWSTD_CONTAINER_SIZE_TYPE _TYPENAME _Container::size_type
#else
# define _RWSTD_CONTAINER_SIZE_TYPE _RWSTD_SIZE_T
#endif // _RWSTD_NO_NONDEDUCED_CONTEXT
// returns a suggested new capacity for a container needing more space
template <class _Container>
inline _RWSTD_CONTAINER_SIZE_TYPE
__rw_new_capacity (_RWSTD_CONTAINER_SIZE_TYPE __size, const _Container*)
{
typedef _RWSTD_CONTAINER_SIZE_TYPE _RWSizeT;
_RWSizeT __cap = _RWSTD_STATIC_CAST (_RWSizeT,
__size * _RWSTD_NEW_CAPACITY_RATIO);
return (__size += _RWSTD_MINIMUM_NEW_CAPACITY) > __cap ? __size : __cap;
}
#undef _RWSTD_CONTAINER_SIZE_TYPE
template <class _TypeT>
inline void __rw_destroy (_TypeT &__ref)
{
__ref.~_TypeT ();
}
template <class _TypeT, class _TypeU>
inline void __rw_construct (_TypeT* __p, const _TypeU& __val)
{
::new (__p) _TypeT (__val);
}
template <class _ForwardIterator>
inline void __rw_destroy (_ForwardIterator __first, _ForwardIterator __last)
{
for (; __first != __last; ++__first)
__rw_destroy (*__first);
}
#ifndef _RWSTD_NO_PTR_VALUE_TEMPLATE_OVERLOAD
// for compilers that don't optimize "empty" loops
template <class _TypeT>
inline void __rw_destroy (_TypeT**, _TypeT**)
{ }
#endif // _RWSTD_NO_PTR_VALUE_TEMPLATE_OVERLOAD
} // namespace __rw
_RWSTD_NAMESPACE (std) {
template <class _TypeT> class
allocator;
// 20.4.4.1
template <class _InputIterator, class _ForwardIterator>
inline _ForwardIterator
uninitialized_copy (_InputIterator __first, _InputIterator __last,
_ForwardIterator __res)
{
const _ForwardIterator __start = __res;
_TRY {
for (; __first != __last; ++__first, ++__res)
_RW::__rw_construct (&*__res, *__first);
}
_CATCH (...) {
_RW::__rw_destroy (__start, __res);
_RETHROW;
}
return __res;
}
#ifdef _RWSTD_ALLOCATOR
// extension
template <class _InputIterator, class _ForwardIterator, class _Allocator>
inline _ForwardIterator
uninitialized_copy (_InputIterator __first, _InputIterator __last,
_ForwardIterator __res, _Allocator &__alloc)
{
_ForwardIterator __start = __res;
_TRY {
for (; __first != __last; ++__first, ++__res)
__alloc.construct (__alloc.address (*__res), *__first);
}
_CATCH (...) {
for (; __start != __res; ++__start)
__alloc.destroy (__alloc.address (*__start));
_RETHROW;
}
return __res;
}
#endif // _RWSTD_ALLOCATOR
// 20.4.4.2
template <class _ForwardIterator, class _TypeT>
inline void
uninitialized_fill (_ForwardIterator __first, _ForwardIterator __last,
const _TypeT& __x)
{
const _ForwardIterator __start = __first;
_TRY {
for (; __first != __last; ++__first)
_RW::__rw_construct (&*__first, __x);
}
_CATCH (...) {
_RW::__rw_destroy (__start, __first);
_RETHROW;
}
}
// 20.4.4.3
template <class _ForwardIterator, class _Size, class _TypeT>
inline void
uninitialized_fill_n (_ForwardIterator __first, _Size __n, const _TypeT& __x)
{
const _ForwardIterator __start = __first;
_TRY {
for (; __n; --__n, ++__first)
_RW::__rw_construct (&*__first, __x);
}
_CATCH (...) {
_RW::__rw_destroy (__start, __first);
_RETHROW;
}
}
#ifdef _RWSTD_ALLOCATOR
// extension
template <class _ForwardIter, class _Size, class _TypeT, class _Allocator>
inline void
uninitialized_fill_n (_ForwardIter __first, _Size __n,
const _TypeT& __x, _Allocator& __alloc)
{
_ForwardIter __start = __first;
_TRY {
for (; __n; --__n, ++__first)
__alloc.construct (__alloc.address (*__first), __x);
}
_CATCH (...) {
for (; __start != __first; ++__start)
__alloc.destroy (__alloc.address (*__start));
_RETHROW;
}
}
#else // if !defined (_RWSTD_ALLOCATOR)
template <class _Allocator, class _TypeT>
class allocator_interface;
// Specializations for non-standard allocators. When vector calls
// uninitialized_{copy,fill_n} with non-standard allocator, a temporary
// instance of allocator_interface is passed to these functions. Since
// C++ forbids temporaries to be passed as non-const references, we
// use these specializations to pass a const reference (and we can force
// allocator_interface members construct & destroy to be const).
template <class _InputIterator, class _ForwardIterator,
class _Allocator, class _TypeT>
inline _ForwardIterator
uninitialized_copy (_InputIterator __first,
_InputIterator __last,
_ForwardIterator __res,
allocator_interface<_Allocator, _TypeT> &__alloc)
{
_ForwardIterator __start = __res;
_TRY {
for (; __first != __last; ++__first, ++__res)
__alloc.construct (__alloc.address (*__res), *__first);
}
_CATCH (...) {
for (; __start != __res; ++__start)
__alloc.destroy (__alloc.address (*__start));
_RETHROW;
}
return __res;
}
template <class _ForwardIter, class _Size,
class _TypeT, class _Allocator, class _TypeU>
inline void
uninitialized_fill_n (_ForwardIter __first, _Size __n,
const _TypeT& __x,
allocator_interface<_Allocator, _TypeU> &__alloc)
{
_ForwardIter __start = __first;
_TRY {
for (; __n; --__n, ++__first)
__alloc.construct (__alloc.address (*__first), __x);
}
_CATCH (...) {
for (; __start != __first; ++__start)
__alloc.destroy (__alloc.address (*__start));
_RETHROW;
}
}
#endif // _RWSTD_ALLOCATOR
} // namespace std
#endif // _RWSTD_SPECIALIZED_H_INCLUDED