// -*- 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: _specialized.h 605548 2007-12-19 14:19:33Z faridz $ * *************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you 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. * * Copyright 1994-2006 Rogue Wave Software. * *************************************************************************** * * 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. * **************************************************************************/ #ifndef _RWSTD_RW_SPECIALIZED_H_INCLUDED #define _RWSTD_RW_SPECIALIZED_H_INCLUDED #ifndef _RWSTD_RW_NEW_H_INCLUDED # include #endif // _RWSTD_RW_NEW_H_INCLUDED _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 inline _RWSTD_CONTAINER_SIZE_TYPE __rw_new_capacity (_RWSTD_CONTAINER_SIZE_TYPE __size, const _Container*) { typedef _RWSTD_CONTAINER_SIZE_TYPE _RWSizeT; const _RWSizeT __ratio = _RWSizeT ( (_RWSTD_NEW_CAPACITY_RATIO << 10) / _RWSTD_RATIO_DIVIDER); const _RWSizeT __cap = (__size >> 10) * __ratio + (((__size & 0x3ff) * __ratio) >> 10); return (__size += _RWSTD_MINIMUM_NEW_CAPACITY) > __cap ? __size : __cap; } #undef _RWSTD_CONTAINER_SIZE_TYPE #ifndef _RWSTD_NO_PART_SPEC_OVERLOAD template inline void __rw_construct (_TypeT* __p, _TypeU& __val) { ::new (_RWSTD_STATIC_CAST (void*, __p)) _TypeT (__val); } template inline void __rw_construct (volatile _TypeT* __p, _TypeU& __val) { // remove volatile before invoking operator new __rw_construct (_RWSTD_CONST_CAST (_TypeT*, __p), __val); } #else // #ifdef _RWSTD_NO_PART_SPEC_OVERLOAD template inline void __rw_construct_impl (_TypeT* __p, _TypeU& __val) { ::new (_RWSTD_STATIC_CAST (void*, __p)) _TypeT (__val); } template inline void __rw_construct (volatile _TypeT* __p, _TypeU& __val) { // remove volatile before invoking operator new __rw_construct_impl (_RWSTD_CONST_CAST (_TypeT*, __p), __val); } #endif // _RWSTD_NO_PART_SPEC_OVERLOAD template inline void __rw_destroy (_TypeT &__ref) { __ref.~_TypeT (); } template 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 inline void __rw_destroy (_TypeT**, _TypeT**) { } #endif // _RWSTD_NO_PTR_VALUE_TEMPLATE_OVERLOAD } // namespace __rw _RWSTD_NAMESPACE (std) { template class allocator; // 20.4.4.1 template 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 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 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 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 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_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 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 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_RW_SPECIALIZED_H_INCLUDED