// since may lead to accidental buffer overruns. This // implementation follows the C++ standard fairly directly as // outlined in 22.2.2.2 [lib.locale.num.put] template template _OutIter num_put<_CharT, _OutIter>:: _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); // Use default precision if out of range. const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision(); const int __max_digits = __gnu_cxx::__numeric_traits<_ValueT>::__digits10; // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; // Long enough for the max format spec. char __fbuf[16]; __num_base::_S_format_float(__io, __fbuf, __mod); #ifdef _GLIBCXX_USE_C99 // First try a buffer perhaps big enough (most probably sufficient // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast(__builtin_alloca(__cs_size)); __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf, __prec, __v); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf, __prec, __v); } #else // Consider the possibility of long ios_base::fixed outputs const bool __fixed = __io.flags() & ios_base::fixed; const int __max_exp = __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10; // The size of the output string is computed as follows. // ios_base::fixed outputs may need up to __max_exp + 1 chars // for the integer part + __prec chars for the fractional part // + 3 chars for sign, decimal point, '\0'. On the other hand, // for non-fixed outputs __max_digits * 2 + __prec chars are // largely sufficient. const int __cs_size = __fixed ? __max_exp + __prec + 4 : __max_digits * 2 + __prec; char* __cs = static_cast(__builtin_alloca(__cs_size)); __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, __prec, __v); #endif // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const ctype<_CharT>& __ctype = use_facet >(__loc); _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); __ctype.widen(__cs, __cs + __len, __ws); // Replace decimal point. _CharT* __wp = 0; const char* __p = char_traits::find(__cs, __len, '.'); if (__p) { __wp = __ws + (__p - __cs); *__wp = __lc->_M_decimal_point; } // Add grouping, if necessary. // N.B. Make sure to not group things like 2e20, i.e., no decimal // point, scientific notation. if (__lc->_M_use_grouping && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9' && __cs[1] >= '0' && __cs[2] >= '0'))) { // Grouping can add (almost) as many separators as the // number of digits, but no more. _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len * 2)); streamsize __off = 0; if (__cs[0] == '-' || __cs[0] == '+') { __off = 1; __ws2[0] = __ws[0]; __len -= 1; } _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, __lc->_M_thousands_sep, __wp, __ws2 + __off, __ws + __off, __len); __len += __off; __ws = __ws2; } // Pad. const streamsize __w = __io.width(); if (__w > static_cast(__len)) { _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); _M_pad(__fill, __w, __io, __ws3, __ws, __len); __ws = __ws3; } __io.width(0); // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. return std::__write(__s, __ws, __len); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const { const ios_base::fmtflags __flags = __io.flags(); if ((__flags & ios_base::boolalpha) == 0) { const long __l = __v; __s = _M_insert_int(__s, __io, __fill, __l); } else { typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __name = __v ? __lc->_M_truename : __lc->_M_falsename; int __len = __v ? __lc->_M_truename_size : __lc->_M_falsename_size; const streamsize __w = __io.width(); if (__w > static_cast(__len)) { _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); _M_pad(__fill, __w, __io, __cs, __name, __len); __name = __cs; } __io.width(0); __s = std::__write(__s, __name, __len); } return __s; } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const { return _M_insert_int(__s, __io, __fill, __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const { return _M_insert_int(__s, __io, __fill, __v); } #ifdef _GLIBCXX_USE_LONG_LONG template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const { return _M_insert_int(__s, __io, __fill, __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long long __v) const { return _M_insert_int(__s, __io, __fill, __v); } #endif template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const { return _M_insert_float(__s, __io, __fill, char(), __v); } #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ template _OutIter num_put<_CharT, _OutIter>:: __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const { return _M_insert_float(__s, __io, __fill, char(), __v); } #endif template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long double __v) const { return _M_insert_float(__s, __io, __fill, 'L', __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, const void* __v) const { const ios_base::fmtflags __flags = __io.flags(); const ios_base::fmtflags __fmt = ~(ios_base::basefield | ios_base::uppercase | ios_base::internal); __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase)); typedef __gnu_cxx::__conditional_type<(sizeof(const void*) <= sizeof(unsigned long)), unsigned long, unsigned long long>::__type _UIntPtrType; __s = _M_insert_int(__s, __io, __fill, reinterpret_cast<_UIntPtrType>(__v)); __io.flags(__flags); return __s; } _GLIBCXX_END_LDBL_NAMESPACE // Construct correctly padded string, as per 22.2.2.2.2 // Assumes // __newlen > __oldlen // __news is allocated for __newlen size // NB: Of the two parameters, _CharT can be deduced from the // function arguments. The other (_Traits) has to be explicitly specified. template void __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds, const streamsize __newlen, const streamsize __oldlen) { const size_t __plen = static_cast(__newlen - __oldlen); const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; // Padding last. if (__adjust == ios_base::left) { _Traits::copy(__news, __olds, __oldlen); _Traits::assign(__news + __oldlen, __plen, __fill); return; } size_t __mod = 0; if (__adjust == ios_base::internal) { // Pad after the sign, if there is one. // Pad after 0[xX], if there is one. // Who came up with these rules, anyway? Jeeze. const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); if (__ctype.widen('-') == __olds[0] || __ctype.widen('+') == __olds[0]) { __news[0] = __olds[0]; __mod = 1; ++__news; } else if (__ctype.widen('0') == __olds[0] && __oldlen > 1 && (__ctype.widen('x') == __olds[1] || __ctype.widen('X') == __olds[1])) { __news[0] = __olds[0]; __news[1] = __olds[1]; __mod = 2; __news += 2; } // else Padding first. } _Traits::assign(__news, __plen, __fill); _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod); } template _CharT* __add_grouping(_CharT* __s, _CharT __sep, const char* __gbeg, size_t __gsize, const _CharT* __first, const _CharT* __last) { size_t __idx = 0; size_t __ctr = 0; while (__last - __first > __gbeg[__idx] && static_cast(__gbeg[__idx]) > 0) { __last -= __gbeg[__idx]; __idx < __gsize - 1 ? ++__idx : ++__ctr; } while (__first != __last) *__s++ = *__first++; while (__ctr--) { *__s++ = __sep; for (char __i = __gbeg[__idx]; __i > 0; --__i) *__s++ = *__first++; } while (__idx--) { *__s++ = __sep; for (char __i = __gbeg[__idx]; __i > 0; --__i) *__s++ = *__first++; } return __s; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. #if _GLIBCXX_EXTERN_TEMPLATE extern template class numpunct; extern template class numpunct_byname; extern template class _GLIBCXX_LDBL_NAMESPACE num_get; extern template class _GLIBCXX_LDBL_NAMESPACE num_put; extern template class ctype_byname; extern template const numpunct& use_facet >(const locale&); extern template const num_put& use_facet >(const locale&); extern template const num_get& use_facet >(const locale&); extern template bool has_facet >(const locale&); extern template bool has_facet >(const locale&); extern template bool has_facet >(const locale&); extern template bool has_facet >(const locale&); #ifdef _GLIBCXX_USE_WCHAR_T extern template class numpunct; extern template class numpunct_byname; extern template class _GLIBCXX_LDBL_NAMESPACE num_get; extern template class _GLIBCXX_LDBL_NAMESPACE num_put; extern template class ctype_byname; extern template const numpunct& use_facet >(const locale&); extern template const num_put& use_facet >(const locale&); extern template const num_get& use_facet >(const locale&); extern template bool has_facet >(const locale&); extern template bool has_facet >(const locale&); extern template bool has_facet >(const locale&); extern template bool has_facet >(const locale&); #endif #endif _GLIBCXX_END_NAMESPACE #endif // Vector implementation -*- C++ -*- // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /* * * 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) 1996 * Silicon Graphics Computer Systems, Inc. * * 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. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file stl_vector.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. */ #ifndef _STL_VECTOR_H #define _STL_VECTOR_H 1 #include #include #include _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) /// See bits/stl_deque.h's _Deque_base for an explanation. template struct _Vector_base { typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; struct _Vector_impl : public _Tp_alloc_type { _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; _Vector_impl() : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } _Vector_impl(_Tp_alloc_type const& __a) : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } }; public: typedef _Alloc allocator_type; _Tp_alloc_type& _M_get_Tp_allocator() { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } const _Tp_alloc_type& _M_get_Tp_allocator() const { return *static_cast(&this->_M_impl); } allocator_type get_allocator() const { return allocator_type(_M_get_Tp_allocator()); } _Vector_base() : _M_impl() { } _Vector_base(const allocator_type& __a) : _M_impl(__a) { } _Vector_base(size_t __n, const allocator_type& __a) : _M_impl(__a) { this->_M_impl._M_start = this->_M_allocate(__n); this->_M_impl._M_finish = this->_M_impl._M_start; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } #ifdef __GXX_EXPERIMENTAL_CXX0X__ _Vector_base(_Vector_base&& __x) : _M_impl(__x._M_get_Tp_allocator()) { this->_M_impl._M_start = __x._M_impl._M_start; this->_M_impl._M_finish = __x._M_impl._M_finish; this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; __x._M_impl._M_start = 0; __x._M_impl._M_finish = 0; __x._M_impl._M_end_of_storage = 0; } #endif ~_Vector_base() { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } public: _Vector_impl _M_impl; _Tp* _M_allocate(size_t __n) { return __n != 0 ? _M_impl.allocate(__n) : 0; } void _M_deallocate(_Tp* __p, size_t __n) { if (__p) _M_impl.deallocate(__p, __n); } }; /** * @brief A standard container which offers fixed time access to * individual elements in any order. * * @ingroup Containers * @ingroup Sequences * * Meets the requirements of a container, a * reversible container, and a * sequence, including the * optional sequence requirements with the * %exception of @c push_front and @c pop_front. * * In some terminology a %vector can be described as a dynamic * C-style array, it offers fast and efficient access to individual * elements in any order and saves the user from worrying about * memory and size allocation. Subscripting ( @c [] ) access is * also provided as with C-style arrays. */ template > class vector : protected _Vector_base<_Tp, _Alloc> { // Concept requirements. typedef typename _Alloc::value_type _Alloc_value_type; __glibcxx_class_requires(_Tp, _SGIAssignableConcept) __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) typedef _Vector_base<_Tp, _Alloc> _Base; typedef vector<_Tp, _Alloc> vector_type; typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; public: typedef _Tp value_type; typedef typename _Tp_alloc_type::pointer pointer; typedef typename _Tp_alloc_type::const_pointer const_pointer; typedef typename _Tp_alloc_type::reference reference; typedef typename _Tp_alloc_type::const_reference const_reference; typedef __gnu_cxx::__normal_iterator iterator; typedef __gnu_cxx::__normal_iterator const_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef std::reverse_iterator reverse_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Alloc allocator_type; protected: using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_impl; using _Base::_M_get_Tp_allocator; public: // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** * @brief Default constructor creates no elements. */ vector() : _Base() { } /** * @brief Creates a %vector with no elements. * @param a An allocator object. */ explicit vector(const allocator_type& __a) : _Base(__a) { } /** * @brief Creates a %vector with copies of an exemplar element. * @param n The number of elements to initially create. * @param value An element to copy. * @param a An allocator. * * This constructor fills the %vector with @a n copies of @a value. */ explicit vector(size_type __n, const value_type& __value = value_type(), const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_fill_initialize(__n, __value); } /** * @brief %Vector copy constructor. * @param x A %vector of identical element and allocator types. * * The newly-created %vector uses a copy of the allocation * object used by @a x. All the elements of @a x are copied, * but any extra memory in * @a x (for fast expansion) will not be copied. */ vector(const vector& __x) : _Base(__x.size(), __x._M_get_Tp_allocator()) { this->_M_impl._M_finish = std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ /** * @brief %Vector move constructor. * @param x A %vector of identical element and allocator types. * * The newly-created %vector contains the exact contents of @a x. * The contents of @a x are a valid, but unspecified %vector. */ vector(vector&& __x) : _Base(std::forward<_Base>(__x)) { } #endif /** * @brief Builds a %vector from a range. * @param first An input iterator. * @param last An input iterator. * @param a An allocator. * * Create a %vector consisting of copies of the elements from * [first,last). * * If the iterators are forward, bidirectional, or * random-access, then this will call the elements' copy * constructor N times (where N is distance(first,last)) and do * no memory reallocation. But if only input iterators are * used, then this will do at most 2N calls to the copy * constructor, and logN memory reallocations. */ template vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } /** * The dtor only erases the elements, and note that if the * elements themselves are pointers, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); } /** * @brief %Vector assignment operator. * @param x A %vector of identical element and allocator types. * * All the elements of @a x are copied, but any extra memory in * @a x (for fast expansion) will not be copied. Unlike the * copy constructor, the allocator object is not copied. */ vector& operator=(const vector& __x); #ifdef __GXX_EXPERIMENTAL_CXX0X__ /** * @brief %Vector move assignment operator. * @param x A %vector of identical element and allocator types. * * The contents of @a x are moved into this %vector (without copying). * @a x is a valid, but unspecified %vector. */ vector& operator=(vector&& __x) { // NB: DR 675. this->clear(); this->swap(__x); return *this; } #endif /** * @brief Assigns a given value to a %vector. * @param n Number of elements to be assigned. * @param val Value to be assigned. * * This function fills a %vector with @a n copies of the given * value. Note that the assignment completely changes the * %vector and that the resulting %vector's size is the same as * the number of elements assigned. Old data may be lost. */ void assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } /** * @brief Assigns a range to a %vector. * ****************************@param first An input iterator. * @param last An input iterator. * * This function fills a %vector with copies of the elements in the * range [first,last). * * Note that the assignment completely changes the %vector and * that the resulting %vector's size is the same as the number * of elements assigned. Old data may be lost. */ template void assign(_InputIterator __first, _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } /// Get a copy of the memory allocation object. using _Base::get_allocator; // iterators /** * Returns a read/write iterator that points to the first * element in the %vector. Iteration is done in ordinary * element order. */ iterator begin() { return iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ const_iterator begin() const { return const_iterator(this->_M_impl._M_start); } /** * Returns a read/write iterator that points one past the last * element in the %vector. Iteration is done in ordinary * element order. */ iterator end() { return iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %vector. Iteration is done in * ordinary element order. */ const_iterator end() const { return const_iterator(this->_M_impl._M_finish); } /** * Returns a read/write reverse iterator that points to the * last element in the %vector. Iteration is done in reverse * element order. */ reverse_iterator rbegin() { return reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %vector. Iteration is done in * reverse element order. */ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } /** * Returns a read/write reverse iterator that points to one * before the first element in the %vector. Iteration is done * in reverse element order. */ reverse_iterator rend() { return reverse_iterator(begin()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %vector. Iteration * is done in reverse element order. */ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ const_iterator cbegin() const { return const_iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %vector. Iteration is done in * ordinary element order. */ const_iterator cend() const { return const_iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %vector. Iteration is done in * reverse element order. */ const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %vector. Iteration * is done in reverse element order. */ const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } #endif // [23.2.4.2] capacity /** Returns the number of elements in the %vector. */ size_type size() const { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } /** Returns the size() of the largest possible %vector. */ size_type max_size() const { return _M_get_Tp_allocator().max_size(); } /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. * @param x Data with which new elements should be populated. * * This function will %resize the %vector to the specified * number of elements. If the number is smaller than the * %vector's current size the %vector is truncated, otherwise * the %vector is extended and new elements are populated with * given data. */ void resize(size_type __new_size, value_type __x = value_type()) { if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); else insert(end(), __new_size - size(), __x); } /** * Returns the total number of elements that the %vector can * hold before needing to allocate more memory. */ size_type capacity() const { return size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } /** * Returns true if the %vector is empty. (Thus begin() would * equal end().) */ bool empty() const { return begin() == end(); } /** * @brief Attempt to preallocate enough memory for specified number of * elements. * @param n Number of elements required. * @throw std::length_error If @a n exceeds @c max_size(). * * This function attempts to reserve enough memory for the * %vector to hold the specified number of elements. If the * number requested is more than max_size(), length_error is * thrown. * * The advantage of this function is that if optimal code is a * necessity and the user can determine the number of elements * that will be required, the user can reserve the memory in * %advance, and thus prevent a possible reallocation of memory * and copying of %vector data. */ void reserve(size_type __n); // element access /** * @brief Subscript access to the data contained in the %vector. * @param n The index of the element for which data should be * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ reference operator[](size_type __n) { return *(this->_M_impl._M_start + __n); } /** * @brief Subscript access to the data contained in the %vector. * @param n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference operator[](size_type __n) const { return *(this->_M_impl._M_start + __n); } protected: /// Safety check used only from at(). void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range(__N("vector::_M_range_check")); } public: /** * @brief Provides access to the data contained in the %vector. * @param n The index of the element for which data should be * accessed. * @return Read/write reference to data. * @throw std::out_of_range If @a n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the vector. The * function throws out_of_range if the check fails. */ reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } /** * @brief Provides access to the data contained in the %vector. * @param n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * @throw std::out_of_range If @a n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the vector. The * function throws out_of_range if the check fails. */ const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } /** * Returns a read/write reference to the data at the first * element of the %vector. */ reference front() { return *begin(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %vector. */ const_reference front() const { return *begin(); } /** * Returns a read/write reference to the data at the last * element of the %vector. */ reference back() { return *(end() - 1); } /** * Returns a read-only (constant) reference to the data at the * last element of the %vector. */ const_reference back() const { return *(end() - 1); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. // data access /** * Returns a pointer such that [data(), data() + size()) is a valid * range. For a non-empty %vector, data() == &front(). */ pointer data() { return pointer(this->_M_impl._M_start); } const_pointer data() const { return const_pointer(this->_M_impl._M_start); } // [23.2.4.3] modifiers /** * @brief Add data to the end of the %vector. * @param x Data to be added. * * This is a typical stack operation. The function creates an * element at the end of the %vector and assigns the given data * to it. Due to the nature of a %vector this operation can be * done in constant time if the %vector has preallocated space * available. */ #ifndef __GXX_EXPERIMENTAL_CXX0X__ void push_back(const value_type& __x) { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { this->_M_impl.construct(this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; } else _M_insert_aux(end(), __x); } #else template void push_back(_Args&&... __args) { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { this->_M_impl.construct(this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; } else _M_insert_aux(end(), std::forward<_Args>(__args)...); } #endif /** * @brief Removes last element. * * This is a typical stack operation. It shrinks the %vector by one. * * Note that no data is returned, and if the last element's * data is needed, it should be retrieved before pop_back() is * called. */ void pop_back() { --this->_M_impl._M_finish; this->_M_impl.destroy(this->_M_impl._M_finish); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ /** * @brief Inserts an object in %vector before specified iterator. * @param position An iterator into the %vector. * @param args Arguments. * @return An iterator that points to the inserted data. * * This function will insert an object of type T constructed * with T(std::forward(args)...) before the specified location. * Note that this kind of operation could be expensive for a %vector * and if it is frequently used the user should consider using * std::list. */ template iterator emplace(iterator __position, _Args&&... __args); #endif /** * @brief Inserts given value into %vector before specified iterator. * @param position An iterator into the %vector. * @param x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before * the specified location. Note that this kind of operation * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ iterator insert(iterator __position, const value_type& __x); #ifdef __GXX_EXPERIMENTAL_CXX0X__ /** * @brief Inserts given rvalue into %vector before specified iterator. * @param position An iterator into the %vector. * @param x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given rvalue before * the specified location. Note that this kind of operation * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ iterator insert(iterator __position, value_type&& __x) { return emplace(__position, std::move(__x)); } #endif /** * @brief Inserts a number of copies of given data into the %vector. * @param position An iterator into the %vector. * @param n Number of elements to be inserted. * @param x Data to be inserted. * * This function will insert a specified number of copies of * the given data before the location specified by @a position. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ void insert(iterator __position, size_type __n, const value_type& __x) { _M_fill_insert(__position, __n, __x); } /** * @brief Inserts a range into the %vector. * @param position An iterator into the %vector. * @param first An input iterator. * @param last An input iterator. * * This function will insert copies of the data in the range * [first,last) into the %vector before the location specified * by @a pos. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ template void insert(iterator __position, _InputIterator __first, _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } /** * @brief Remove element at given position. * @param position Iterator pointing to element to be erased. * @return An iterator pointing to the next element (or end()). * * This function will erase the element at the given position and thus * shorten the %vector by one. * * Note This operation could be expensive and if it is * frequently used the user should consider using std::list. * The user is also cautioned that this function only erases * the element, and that if the element is itself a pointer, * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibility. */ iterator erase(iterator __position); /** * @brief Remove a range of elements. * @param first Iterator pointing to the first element to be erased. * @param last Iterator pointing to one past the last element to be * erased. * @return An iterator pointing to the element pointed to by @a last * prior to erasing (or end()). * * This function will erase the elements in the range [first,last) and * shorten the %vector accordingly. * * Note This operation could be expensive and if it is * frequently used the user should consider using std::list. * The user is also cautioned that this function only erases * the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ iterator erase(iterator __first, iterator __last); /** * @brief Swaps data with another %vector. * @param x A %vector of the same element and allocator types. * * This exchanges the elements between two vectors in constant time. * (Three pointers, so it should be quite fast.) * Note that the global std::swap() function is specialized such that * std::swap(v1,v2) will feed to this function. */ void #ifdef __GXX_EXPERIMENTAL_CXX0X__ swap(vector&& __x) #else swap(vector& __x) #endif { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 431. Swapping containers with unequal allocators. std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } /** * Erases all the elements. Note that this function only erases the * elements, and that if the elements themselves are pointers, the * pointed-to memory is not touched in any way. Managing the pointer is * the user's responsibility. */ void clear() { _M_erase_at_end(this->_M_impl._M_start); } protected: /** * Memory expansion handler. Uses the member allocation function to * obtain @a n bytes of memory, and then copies [first,last) into it. */ template pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { pointer __result = this->_M_allocate(__n); try { std::__uninitialized_copy_a(__first, __last, __result, _M_get_Tp_allocator()); return __result; } catch(...) { _M_deallocate(__result, __n); __throw_exception_again; } } // Internal constructor functions follow. // Called by the range constructor to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template void _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) { this->_M_impl._M_start = _M_allocate(static_cast(__n)); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + static_cast(__n); _M_fill_initialize(static_cast(__n), __value); } // Called by the range constructor to implement [23.1.1]/9 template void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_range_initialize(__first, __last, _IterCategory()); } // Called by the second initialize_dispatch above template void _M_range_initialize(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { for (; __first != __last; ++__first) push_back(*__first); } // Called by the second initialize_dispatch above template void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); this->_M_impl._M_start = this->_M_allocate(__n); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; this->_M_impl._M_finish = std::__uninitialized_copy_a(__first, __last, this->_M_impl._M_start, _M_get_Tp_allocator()); } // Called by the first initialize_dispatch above and by the // vector(n,value,a) constructor. void _M_fill_initialize(size_type __n, const value_type& __value) { std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, _M_get_Tp_allocator()); this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; } // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. // Called by the range assign to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign(__n, __val); } // Called by the range assign to implement [23.1.1]/9 template void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_assign_aux(__first, __last, _IterCategory()); } // Called by the second assign_dispatch above template void _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag); // Called by the second assign_dispatch above template void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); // Called by assign(n,t), and the range assign when it turns out // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val); // Internal insert functions follow. // Called by the range insert to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) { _M_fill_insert(__pos, __n, __val); } // Called by the range insert to implement [23.1.1]/9 template void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_range_insert(__pos, __first, __last, _IterCategory()); } // Called by the second insert_dispatch above template void _M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag); // Called by the second insert_dispatch above template void _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); // Called by insert(p,n,x), and the range insert when it turns out to be // the same thing. void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); // Called by insert(p,x) #ifndef __GXX_EXPERIMENTAL_CXX0X__ void _M_insert_aux(iterator __position, const value_type& __x); #else template void _M_insert_aux(iterator __position, _Args&&... __args); #endif // Called by the latter. size_type _M_check_len(size_type __n, const char* __s) const { if (max_size() - size() < __n) __throw_length_error(__N(__s)); const size_type __len = size() + std::max(size(), __n); return (__len < size() || __len > max_size()) ? max_size() : __len; } // Internal erase functions follow. // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, // _M_assign_aux. void _M_erase_at_end(pointer __pos) { std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __pos; } }; /** * @brief Vector equality comparison. * @param x A %vector. * @param y A %vector of the same type as @a x. * @return True iff the size and elements of the vectors are equal. * * This is an equivalence relation. It is linear in the size of the * vectors. Vectors are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ template inline bool operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return (__x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin())); } /** * @brief Vector ordering relation. * @param x A %vector. * @param y A %vector of the same type as @a x. * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * vectors. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template inline bool operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } /// Based on operator== template inline bool operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< template inline bool operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return __y < __x; } /// Based on operator< template inline bool operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< template inline bool operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x < __y); } /// See std::vector::swap(). template inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) { __x.swap(__y); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ template inline void swap(vector<_Tp, _Alloc>&& __x, vector<_Tp, _Alloc>& __y) { __x.swap(__y); } template inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>&& __y) { __x.swap(__y); } #endif _GLIBCXX_END_NESTED_NAMESPACE #endif /* _STL_VECTOR_H */ // Locale support -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, // 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 2, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. /** @file locale_classes.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. */ // // ISO C++ 14882: 22.1 Locales // #ifndef _LOCALE_CLASSES_H #define _LOCALE_CLASSES_H 1 #pragma GCC system_header #include #include #include _GLIBCXX_BEGIN_NAMESPACE(std) // 22.1.1 Class locale /** * @brief Container class for localization functionality. * * The locale class is first a class wrapper for C library locales. It is * also an extensible container for user-defined localization. A locale is * a collection of facets that implement various localization features such * as money, time, and number printing. * * Constructing C++ locales does not change the C library locale. * * This library supports efficient construction and copying of locales * through a reference counting implementation of the locale class. */ class locale { public: // Types: /// Definition of locale::category. typedef int category; // Forward decls and friends: class facet; class id; class _Impl; friend class facet; friend class _Impl; template friend bool has_facet(const locale&) throw(); template friend const _Facet& use_facet(const locale&); template friend struct __use_cache; //@{ /** * @brief Category values. * * The standard category values are none, ctype, numeric, collate, time, * monetary, and messages. They form a bitmask that supports union and * intersection. The category all is the union of these values. * * NB: Order must match _S_facet_categories definition in locale.cc */ static const category none = 0; static const category ctype = 1L << 0; static const category numeric = 1L << 1; static const category collate = 1L << 2; static const category time = 1L << 3; static const category monetary = 1L << 4; static const category messages = 1L << 5; static const category all = (ctype | numeric | collate | time | monetary | messages); //@} // Construct/copy/destroy: /** * @brief Default constructor. * * Constructs a copy of the global locale. If no locale has been * explicitly set, this is the "C" locale. */ locale() throw(); /** * @brief Copy constructor. * * Constructs a copy of @a other. * * @param other The locale to copy. */ locale(const locale& __other) throw(); /** * @brief Named locale constructor. * * Constructs a copy of the named C library locale. * * @param s Name of the locale to construct. * @throw std::runtime_error if s is null or an undefined locale. */ explicit locale(const char* __s); /** * @brief Construct locale with facets from another locale. * * Constructs a copy of the locale @a base. The facets specified by @a * cat are replaced with those from the locale named by @a s. If base is * named, this locale instance will also be named. * * @param base The locale to copy. * @param s Name of the locale to use facets from. * @param cat Set of categories defining the facets to use from s. * @throw std::runtime_error if s is null or an undefined locale. */ locale(const locale& __base, const char* __s, category __cat); /** * @brief Construct locale with facets from another locale. * * Constructs a copy of the locale @a base. The facets specified by @a * cat are replaced with those from the locale @a add. If @a base and @a * add are named, this locale instance will also be named. * * @param base The locale to copy. * @param add The locale to use facets from. * @param cat Set of categories defining the facets to use from add. */ locale(const locale& __base, const locale& __add, category __cat); /** * @brief Construct locale with another facet. * * Constructs a copy of the locale @a other. The facet @f is added to * @other, replacing an existing facet of type Facet if there is one. If * @f is null, this locale is a copy of @a other. * * @param other The locale to copy. * @param f The facet to add in. */ template locale(const locale& __other, _Facet* __f); /// Locale destructor. ~locale() throw(); /** * @brief Assignment operator. * * Set this locale to be a copy of @a other. * * @param other The locale to copy. * @return A reference to this locale. */ const locale& operator=(const locale& __other) throw(); /** * @brief Construct locale with another facet. * * Constructs and returns a new copy of this locale. Adds or replaces an * existing facet of type Facet from the locale @a other into the new * locale. * * @param Facet The facet type to copy from other * @param other The locale to copy from. * @return Newly constructed locale. * @throw std::runtime_error if other has no facet of type Facet. */ template locale combine(const locale& __other) const; // Locale operations: /** * @brief Return locale name. * @return Locale name or "*" if unnamed. */ string name() const; /** * @brief Locale equality. * * @param other The locale to compare against. * @return True if other and this refer to the same locale instance, are * copies, or have the same name. False otherwise. */ bool operator==(const locale& __other) const throw (); /** * @brief Locale inequality. * * @param other The locale to compare against. * @return ! (*this == other) */ bool operator!=(const locale& __other) const throw () { return !(this->operator==(__other)); } /** * @brief Compare two strings according to collate. * * Template operator to compare two strings using the compare function of * the collate facet in this locale. One use is to provide the locale to * the sort function. For example, a vector v of strings could be sorted * according to locale loc by doing: * @code * std::sort(v.begin(), v.end(), loc); * @endcode * * @param s1 First string to compare. * @param s2 Second string to compare. * @return True if collate facet compares s1 < s2, else false. */ template bool operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, const basic_string<_Char, _Traits, _Alloc>& __s2) const; // Global locale objects: /** * @brief Set global locale * * This function sets the global locale to the argument and returns a * copy of the previous global locale. If the argument has a name, it * will also call std::setlocale(LC_ALL, loc.name()). * * @param locale The new locale to make global. * @return Copy of the old global locale. */ static locale global(const locale&); /** * @brief Return reference to the "C" locale. */ static const locale& classic(); private: // The (shared) implementation _Impl* _M_impl; // The "C" reference locale static _Impl* _S_classic; // Current global locale static _Impl* _S_global; // Names of underlying locale categories. // NB: locale::global() has to know how to modify all the // underlying categories, not just the ones required by the C++ // standard. static const char* const* const _S_categories; // Number of standard categories. For C++, these categories are // collate, ctype, monetary, numeric, time, and messages. These // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE // 1003.1-2001) specifies LC_MESSAGES. // In addition to the standard categories, the underlying // operating system is allowed to define extra LC_* // macros. For GNU systems, the following are also valid: // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, // and LC_IDENTIFICATION. enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES }; #ifdef __GTHREADS static __gthread_once_t _S_once; #endif explicit lo