diff options
author | kan <kan@FreeBSD.org> | 2004-08-12 16:41:42 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2004-08-12 16:41:42 +0000 |
commit | d42790ccc00a70f00d10a3b8f17967a5b396bd4d (patch) | |
tree | 05895ca3fdba11097afd624bf6f64962995c416e /contrib/libstdc++/include/bits | |
parent | d42b9316c71d1b89b1b05d36be366eadf7bd8cdf (diff) | |
download | FreeBSD-src-d42790ccc00a70f00d10a3b8f17967a5b396bd4d.zip FreeBSD-src-d42790ccc00a70f00d10a3b8f17967a5b396bd4d.tar.gz |
Remove files that are not part of GCC 3.4.x from the vendor branch.
Diffstat (limited to 'contrib/libstdc++/include/bits')
-rw-r--r-- | contrib/libstdc++/include/bits/fpos.h | 127 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/pthread_allocimpl.h | 525 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/stl_alloc.h | 974 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/stl_pthread_alloc.h | 60 | ||||
-rw-r--r-- | contrib/libstdc++/include/bits/valarray_meta.h | 1147 |
5 files changed, 0 insertions, 2833 deletions
diff --git a/contrib/libstdc++/include/bits/fpos.h b/contrib/libstdc++/include/bits/fpos.h deleted file mode 100644 index 5432527..0000000 --- a/contrib/libstdc++/include/bits/fpos.h +++ /dev/null @@ -1,127 +0,0 @@ -// File position object and stream types - -// Copyright (C) 1997, 1998, 1999, 2000, 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// 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. - -// -// ISO C++ 14882: 27 Input/output library -// - -/** @file fpos.h - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. - */ - -#ifndef _CPP_BITS_FPOS_H -#define _CPP_BITS_FPOS_H 1 - -#pragma GCC system_header - -#include <bits/c++io.h> -#include <cwchar> // For mbstate_t. - -namespace std -{ - // 27.4.1 Types - - // [27.4.3] template class fpos - /** - * @doctodo - */ - template<typename _StateT> - class fpos - { - public: - // Types: - typedef _StateT __state_type; - - private: - streamoff _M_off; - __state_type _M_st; - - public: - __state_type - state() const { return _M_st; } - - void - state(__state_type __st) { _M_st = __st; } - - // NB: The standard defines only the implicit copy ctor and the - // previous two members. The rest is a "conforming extension". - fpos(): _M_off(streamoff()), _M_st(__state_type()) { } - - fpos(streamoff __off, __state_type __st = __state_type()) - : _M_off(__off), _M_st(__st) { } - - operator streamoff() const { return _M_off; } - - fpos& - operator+=(streamoff __off) { _M_off += __off; return *this; } - - fpos& - operator-=(streamoff __off) { _M_off -= __off; return *this; } - - fpos - operator+(streamoff __off) - { - fpos __t(*this); - __t += __off; - return __t; - } - - fpos - operator-(streamoff __off) - { - fpos __t(*this); - __t -= __off; - return __t; - } - - bool - operator==(const fpos& __pos) const - { return _M_off == __pos._M_off; } - - bool - operator!=(const fpos& __pos) const - { return _M_off != __pos._M_off; } - - streamoff - _M_position() const { return _M_off; } - - void - _M_position(streamoff __off) { _M_off = __off; } - }; - - /// 27.2, paragraph 10 about fpos/char_traits circularity - typedef fpos<mbstate_t> streampos; -# ifdef _GLIBCPP_USE_WCHAR_T - /// 27.2, paragraph 10 about fpos/char_traits circularity - typedef fpos<mbstate_t> wstreampos; -# endif -} // namespace std - -#endif diff --git a/contrib/libstdc++/include/bits/pthread_allocimpl.h b/contrib/libstdc++/include/bits/pthread_allocimpl.h deleted file mode 100644 index 050b206..0000000 --- a/contrib/libstdc++/include/bits/pthread_allocimpl.h +++ /dev/null @@ -1,525 +0,0 @@ -// POSIX thread-related memory allocation -*- C++ -*- - -// Copyright (C) 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// 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) 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 pthread_allocimpl.h - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. - */ - -#ifndef _CPP_BITS_PTHREAD_ALLOCIMPL_H -#define _CPP_BITS_PTHREAD_ALLOCIMPL_H 1 - -// Pthread-specific node allocator. -// This is similar to the default allocator, except that free-list -// information is kept separately for each thread, avoiding locking. -// This should be reasonably fast even in the presence of threads. -// The down side is that storage may not be well-utilized. -// It is not an error to allocate memory in thread A and deallocate -// it in thread B. But this effectively transfers ownership of the memory, -// so that it can only be reallocated by thread B. Thus this can effectively -// result in a storage leak if it's done on a regular basis. -// It can also result in frequent sharing of -// cache lines among processors, with potentially serious performance -// consequences. - -#include <bits/c++config.h> -#include <cerrno> -#include <bits/stl_alloc.h> -#ifndef __RESTRICT -# define __RESTRICT -#endif - -#include <new> - -namespace std -{ - -#define __STL_DATA_ALIGNMENT 8 - -union _Pthread_alloc_obj { - union _Pthread_alloc_obj * __free_list_link; - char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */ -}; - -// Pthread allocators don't appear to the client to have meaningful -// instances. We do in fact need to associate some state with each -// thread. That state is represented by -// _Pthread_alloc_per_thread_state<_Max_size>. - -template<size_t _Max_size> -struct _Pthread_alloc_per_thread_state { - typedef _Pthread_alloc_obj __obj; - enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT }; - _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; - _Pthread_alloc_per_thread_state<_Max_size> * __next; - // Free list link for list of available per thread structures. - // When one of these becomes available for reuse due to thread - // termination, any objects in its free list remain associated - // with it. The whole structure may then be used by a newly - // created thread. - _Pthread_alloc_per_thread_state() : __next(0) - { - memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *)); - } - // Returns an object of size __n, and possibly adds to size n free list. - void *_M_refill(size_t __n); -}; - -// Pthread-specific allocator. -// The argument specifies the largest object size allocated from per-thread -// free lists. Larger objects are allocated using malloc_alloc. -// Max_size must be a power of 2. -template <size_t _Max_size = 128> -class _Pthread_alloc_template { - -public: // but only for internal use: - - typedef _Pthread_alloc_obj __obj; - - // Allocates a chunk for nobjs of size size. nobjs may be reduced - // if it is inconvenient to allocate the requested number. - static char *_S_chunk_alloc(size_t __size, int &__nobjs); - - enum {_S_ALIGN = __STL_DATA_ALIGNMENT}; - - static size_t _S_round_up(size_t __bytes) { - return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1)); - } - static size_t _S_freelist_index(size_t __bytes) { - return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1); - } - -private: - // Chunk allocation state. And other shared state. - // Protected by _S_chunk_allocator_lock. - static pthread_mutex_t _S_chunk_allocator_lock; - static char *_S_start_free; - static char *_S_end_free; - static size_t _S_heap_size; - static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states; - static pthread_key_t _S_key; - static bool _S_key_initialized; - // Pthread key under which per thread state is stored. - // Allocator instances that are currently unclaimed by any thread. - static void _S_destructor(void *instance); - // Function to be called on thread exit to reclaim per thread - // state. - static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state(); - // Return a recycled or new per thread state. - static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state(); - // ensure that the current thread has an associated - // per thread state. - class _M_lock; - friend class _M_lock; - class _M_lock { - public: - _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); } - ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); } - }; - -public: - - /* n must be > 0 */ - static void * allocate(size_t __n) - { - __obj * volatile * __my_free_list; - __obj * __RESTRICT __result; - _Pthread_alloc_per_thread_state<_Max_size>* __a; - - if (__n > _Max_size) { - return(malloc_alloc::allocate(__n)); - } - if (!_S_key_initialized || - !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*) - pthread_getspecific(_S_key))) { - __a = _S_get_per_thread_state(); - } - __my_free_list = __a -> __free_list + _S_freelist_index(__n); - __result = *__my_free_list; - if (__result == 0) { - void *__r = __a -> _M_refill(_S_round_up(__n)); - return __r; - } - *__my_free_list = __result -> __free_list_link; - return (__result); - }; - - /* p may not be 0 */ - static void deallocate(void *__p, size_t __n) - { - __obj *__q = (__obj *)__p; - __obj * volatile * __my_free_list; - _Pthread_alloc_per_thread_state<_Max_size>* __a; - - if (__n > _Max_size) { - malloc_alloc::deallocate(__p, __n); - return; - } - if (!_S_key_initialized || - !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *) - pthread_getspecific(_S_key))) { - __a = _S_get_per_thread_state(); - } - __my_free_list = __a->__free_list + _S_freelist_index(__n); - __q -> __free_list_link = *__my_free_list; - *__my_free_list = __q; - } - - static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz); - -} ; - -typedef _Pthread_alloc_template<> pthread_alloc; - - -template <size_t _Max_size> -void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance) -{ - _M_lock __lock_instance; // Need to acquire lock here. - _Pthread_alloc_per_thread_state<_Max_size>* __s = - (_Pthread_alloc_per_thread_state<_Max_size> *)__instance; - __s -> __next = _S_free_per_thread_states; - _S_free_per_thread_states = __s; -} - -template <size_t _Max_size> -_Pthread_alloc_per_thread_state<_Max_size> * -_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state() -{ - /* lock already held here. */ - if (0 != _S_free_per_thread_states) { - _Pthread_alloc_per_thread_state<_Max_size> *__result = - _S_free_per_thread_states; - _S_free_per_thread_states = _S_free_per_thread_states -> __next; - return __result; - } else { - return new _Pthread_alloc_per_thread_state<_Max_size>; - } -} - -template <size_t _Max_size> -_Pthread_alloc_per_thread_state<_Max_size> * -_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state() -{ - /*REFERENCED*/ - _M_lock __lock_instance; // Need to acquire lock here. - int __ret_code; - _Pthread_alloc_per_thread_state<_Max_size> * __result; - if (!_S_key_initialized) { - if (pthread_key_create(&_S_key, _S_destructor)) { - std::__throw_bad_alloc(); // defined in funcexcept.h - } - _S_key_initialized = true; - } - __result = _S_new_per_thread_state(); - __ret_code = pthread_setspecific(_S_key, __result); - if (__ret_code) { - if (__ret_code == ENOMEM) { - std::__throw_bad_alloc(); - } else { - // EINVAL - abort(); - } - } - return __result; -} - -/* We allocate memory in large chunks in order to avoid fragmenting */ -/* the malloc heap too much. */ -/* We assume that size is properly aligned. */ -template <size_t _Max_size> -char *_Pthread_alloc_template<_Max_size> -::_S_chunk_alloc(size_t __size, int &__nobjs) -{ - { - char * __result; - size_t __total_bytes; - size_t __bytes_left; - /*REFERENCED*/ - _M_lock __lock_instance; // Acquire lock for this routine - - __total_bytes = __size * __nobjs; - __bytes_left = _S_end_free - _S_start_free; - if (__bytes_left >= __total_bytes) { - __result = _S_start_free; - _S_start_free += __total_bytes; - return(__result); - } else if (__bytes_left >= __size) { - __nobjs = __bytes_left/__size; - __total_bytes = __size * __nobjs; - __result = _S_start_free; - _S_start_free += __total_bytes; - return(__result); - } else { - size_t __bytes_to_get = - 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); - // Try to make use of the left-over piece. - if (__bytes_left > 0) { - _Pthread_alloc_per_thread_state<_Max_size>* __a = - (_Pthread_alloc_per_thread_state<_Max_size>*) - pthread_getspecific(_S_key); - __obj * volatile * __my_free_list = - __a->__free_list + _S_freelist_index(__bytes_left); - - ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list; - *__my_free_list = (__obj *)_S_start_free; - } -# ifdef _SGI_SOURCE - // Try to get memory that's aligned on something like a - // cache line boundary, so as to avoid parceling out - // parts of the same line to different threads and thus - // possibly different processors. - { - const int __cache_line_size = 128; // probable upper bound - __bytes_to_get &= ~(__cache_line_size-1); - _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); - if (0 == _S_start_free) { - _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); - } - } -# else /* !SGI_SOURCE */ - _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); -# endif - _S_heap_size += __bytes_to_get; - _S_end_free = _S_start_free + __bytes_to_get; - } - } - // lock is released here - return(_S_chunk_alloc(__size, __nobjs)); -} - - -/* Returns an object of size n, and optionally adds to size n free list.*/ -/* We assume that n is properly aligned. */ -/* We hold the allocation lock. */ -template <size_t _Max_size> -void *_Pthread_alloc_per_thread_state<_Max_size> -::_M_refill(size_t __n) -{ - int __nobjs = 128; - char * __chunk = - _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs); - __obj * volatile * __my_free_list; - __obj * __result; - __obj * __current_obj, * __next_obj; - int __i; - - if (1 == __nobjs) { - return(__chunk); - } - __my_free_list = __free_list - + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n); - - /* Build free list in chunk */ - __result = (__obj *)__chunk; - *__my_free_list = __next_obj = (__obj *)(__chunk + __n); - for (__i = 1; ; __i++) { - __current_obj = __next_obj; - __next_obj = (__obj *)((char *)__next_obj + __n); - if (__nobjs - 1 == __i) { - __current_obj -> __free_list_link = 0; - break; - } else { - __current_obj -> __free_list_link = __next_obj; - } - } - return(__result); -} - -template <size_t _Max_size> -void *_Pthread_alloc_template<_Max_size> -::reallocate(void *__p, size_t __old_sz, size_t __new_sz) -{ - void * __result; - size_t __copy_sz; - - if (__old_sz > _Max_size - && __new_sz > _Max_size) { - return(realloc(__p, __new_sz)); - } - if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); - __result = allocate(__new_sz); - __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; - memcpy(__result, __p, __copy_sz); - deallocate(__p, __old_sz); - return(__result); -} - -template <size_t _Max_size> -_Pthread_alloc_per_thread_state<_Max_size> * -_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; - -template <size_t _Max_size> -pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; - -template <size_t _Max_size> -bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; - -template <size_t _Max_size> -pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock -= PTHREAD_MUTEX_INITIALIZER; - -template <size_t _Max_size> -char *_Pthread_alloc_template<_Max_size> -::_S_start_free = 0; - -template <size_t _Max_size> -char *_Pthread_alloc_template<_Max_size> -::_S_end_free = 0; - -template <size_t _Max_size> -size_t _Pthread_alloc_template<_Max_size> -::_S_heap_size = 0; - - -template <class _Tp> -class pthread_allocator { - typedef pthread_alloc _S_Alloc; // The underlying allocator. -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp* pointer; - typedef const _Tp* const_pointer; - typedef _Tp& reference; - typedef const _Tp& const_reference; - typedef _Tp value_type; - - template <class _NewType> struct rebind { - typedef pthread_allocator<_NewType> other; - }; - - pthread_allocator() throw() {} - pthread_allocator(const pthread_allocator& a) throw() {} - template <class _OtherType> - pthread_allocator(const pthread_allocator<_OtherType>&) - throw() {} - ~pthread_allocator() throw() {} - - pointer address(reference __x) const { return &__x; } - const_pointer address(const_reference __x) const { return &__x; } - - // __n is permitted to be 0. The C++ standard says nothing about what - // the return value is when __n == 0. - _Tp* allocate(size_type __n, const void* = 0) { - return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp))) - : 0; - } - - // p is not permitted to be a null pointer. - void deallocate(pointer __p, size_type __n) - { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); } - - size_type max_size() const throw() - { return size_t(-1) / sizeof(_Tp); } - - void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } - void destroy(pointer _p) { _p->~_Tp(); } -}; - -template<> -class pthread_allocator<void> { -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template <class _NewType> struct rebind { - typedef pthread_allocator<_NewType> other; - }; -}; - -template <size_t _Max_size> -inline bool operator==(const _Pthread_alloc_template<_Max_size>&, - const _Pthread_alloc_template<_Max_size>&) -{ - return true; -} - -template <class _T1, class _T2> -inline bool operator==(const pthread_allocator<_T1>&, - const pthread_allocator<_T2>& a2) -{ - return true; -} - -template <class _T1, class _T2> -inline bool operator!=(const pthread_allocator<_T1>&, - const pthread_allocator<_T2>&) -{ - return false; -} - -template <class _Tp, size_t _Max_size> -struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type; - typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > - allocator_type; -}; - -template <class _Tp, class _Atype, size_t _Max> -struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type; - typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type; -}; - -template <class _Tp, class _Atype> -struct _Alloc_traits<_Tp, pthread_allocator<_Atype> > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type; - typedef pthread_allocator<_Tp> allocator_type; -}; - - -} // namespace std - -#endif /* _CPP_BITS_PTHREAD_ALLOCIMPL_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/contrib/libstdc++/include/bits/stl_alloc.h b/contrib/libstdc++/include/bits/stl_alloc.h deleted file mode 100644 index 9677c3e..0000000 --- a/contrib/libstdc++/include/bits/stl_alloc.h +++ /dev/null @@ -1,974 +0,0 @@ -// Allocators -*- C++ -*- - -// Copyright (C) 2001, 2002, 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// 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) 1996-1997 - * 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_alloc.h - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. - */ - -#ifndef __GLIBCPP_INTERNAL_ALLOC_H -#define __GLIBCPP_INTERNAL_ALLOC_H - -/** - * @defgroup Allocators Memory Allocators - * @if maint - * stl_alloc.h implements some node allocators. These are NOT the same as - * allocators in the C++ standard, nor in the original H-P STL. They do not - * encapsulate different pointer types; we assume that there is only one - * pointer type. The C++ standard allocators are intended to allocate - * individual objects, not pools or arenas. - * - * In this file allocators are of two different styles: "standard" and - * "SGI" (quotes included). "Standard" allocators conform to 20.4. "SGI" - * allocators differ in AT LEAST the following ways (add to this list as you - * discover them): - * - * - "Standard" allocate() takes two parameters (n_count,hint=0) but "SGI" - * allocate() takes one paramter (n_size). - * - Likewise, "standard" deallocate()'s argument is a count, but in "SGI" - * is a byte size. - * - max_size(), construct(), and destroy() are missing in "SGI" allocators. - * - reallocate(p,oldsz,newsz) is added in "SGI", and behaves as - * if p=realloc(p,newsz). - * - * "SGI" allocators may be wrapped in __allocator to convert the interface - * into a "standard" one. - * @endif - * - * @note The @c reallocate member functions have been deprecated for 3.2 - * and will be removed in 3.4. You must define @c _GLIBCPP_DEPRECATED - * to make this visible in 3.2; see c++config.h. - * - * The canonical description of these classes is in docs/html/ext/howto.html - * or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3 -*/ - -#include <cstddef> -#include <cstdlib> -#include <cstring> -#include <bits/functexcept.h> // For __throw_bad_alloc -#include <bits/stl_threads.h> - -#include <bits/atomicity.h> - -namespace std -{ - /** - * @if maint - * A new-based allocator, as required by the standard. Allocation and - * deallocation forward to global new and delete. "SGI" style, minus - * reallocate(). - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - class __new_alloc - { - public: - static void* - allocate(size_t __n) - { return ::operator new(__n); } - - static void - deallocate(void* __p, size_t) - { ::operator delete(__p); } - }; - - - /** - * @if maint - * A malloc-based allocator. Typically slower than the - * __default_alloc_template (below). Typically thread-safe and more - * storage efficient. The template argument is unused and is only present - * to permit multiple instantiations (but see __default_alloc_template - * for caveats). "SGI" style, plus __set_malloc_handler for OOM conditions. - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - template<int __inst> - class __malloc_alloc_template - { - private: - static void* _S_oom_malloc(size_t); - static void* _S_oom_realloc(void*, size_t); - static void (* __malloc_alloc_oom_handler)(); - - public: - static void* - allocate(size_t __n) - { - void* __result = malloc(__n); - if (__builtin_expect(__result == 0, 0)) - __result = _S_oom_malloc(__n); - return __result; - } - - static void - deallocate(void* __p, size_t /* __n */) - { free(__p); } - - static void* - reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) - { - void* __result = realloc(__p, __new_sz); - if (__builtin_expect(__result == 0, 0)) - __result = _S_oom_realloc(__p, __new_sz); - return __result; - } - - static void (* __set_malloc_handler(void (*__f)()))() - { - void (* __old)() = __malloc_alloc_oom_handler; - __malloc_alloc_oom_handler = __f; - return __old; - } - }; - - // malloc_alloc out-of-memory handling - template<int __inst> - void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; - - template<int __inst> - void* - __malloc_alloc_template<__inst>:: - _S_oom_malloc(size_t __n) - { - void (* __my_malloc_handler)(); - void* __result; - - for (;;) - { - __my_malloc_handler = __malloc_alloc_oom_handler; - if (__builtin_expect(__my_malloc_handler == 0, 0)) - __throw_bad_alloc(); - (*__my_malloc_handler)(); - __result = malloc(__n); - if (__result) - return __result; - } - } - - template<int __inst> - void* - __malloc_alloc_template<__inst>:: - _S_oom_realloc(void* __p, size_t __n) - { - void (* __my_malloc_handler)(); - void* __result; - - for (;;) - { - __my_malloc_handler = __malloc_alloc_oom_handler; - if (__builtin_expect(__my_malloc_handler == 0, 0)) - __throw_bad_alloc(); - (*__my_malloc_handler)(); - __result = realloc(__p, __n); - if (__result) - return __result; - } - } - - // Should not be referenced within the library anymore. - typedef __new_alloc __mem_interface; - - /** - * @if maint - * This is used primarily (only?) in _Alloc_traits and other places to - * help provide the _Alloc_type typedef. All it does is forward the - * requests after some minimal checking. - * - * This is neither "standard"-conforming nor "SGI". The _Alloc parameter - * must be "SGI" style. - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - template<typename _Tp, typename _Alloc> - class __simple_alloc - { - public: - static _Tp* - allocate(size_t __n) - { - _Tp* __ret = 0; - if (__n) - __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); - return __ret; - } - - static _Tp* - allocate() - { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } - - static void - deallocate(_Tp* __p, size_t __n) - { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } - - static void - deallocate(_Tp* __p) - { _Alloc::deallocate(__p, sizeof (_Tp)); } - }; - - - /** - * @if maint - * An adaptor for an underlying allocator (_Alloc) to check the size - * arguments for debugging. - * - * "There is some evidence that this can confuse Purify." - SGI comment - * - * This adaptor is "SGI" style. The _Alloc parameter must also be "SGI". - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - template<typename _Alloc> - class __debug_alloc - { - private: - // Size of space used to store size. Note that this must be - // large enough to preserve alignment. - enum {_S_extra = 8}; - - public: - static void* - allocate(size_t __n) - { - char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra); - *(size_t*)__result = __n; - return __result + (int) _S_extra; - } - - static void - deallocate(void* __p, size_t __n) - { - char* __real_p = (char*)__p - (int) _S_extra; - if (*(size_t*)__real_p != __n) - abort(); - _Alloc::deallocate(__real_p, __n + (int) _S_extra); - } - - static void* - reallocate(void* __p, size_t __old_sz, size_t __new_sz) - { - char* __real_p = (char*)__p - (int) _S_extra; - if (*(size_t*)__real_p != __old_sz) - abort(); - char* __result = (char*) _Alloc::reallocate(__real_p, - __old_sz + (int) _S_extra, - __new_sz + (int) _S_extra); - *(size_t*)__result = __new_sz; - return __result + (int) _S_extra; - } - }; - - - /** - * @if maint - * Default node allocator. "SGI" style. Uses various allocators to - * fulfill underlying requests (and makes as few requests as possible - * when in default high-speed pool mode). - * - * Important implementation properties: - * 0. If globally mandated, then allocate objects from __new_alloc - * 1. If the clients request an object of size > _MAX_BYTES, the resulting - * object will be obtained directly from __new_alloc - * 2. In all other cases, we allocate an object of size exactly - * _S_round_up(requested_size). Thus the client has enough size - * information that we can return the object to the proper free list - * without permanently losing part of the object. - * - * The first template parameter specifies whether more than one thread may - * use this allocator. It is safe to allocate an object from one instance - * of a default_alloc and deallocate it with another one. This effectively - * transfers its ownership to the second one. This may have undesirable - * effects on reference locality. - * - * The second parameter is unused and serves only to allow the creation of - * multiple default_alloc instances. Note that containers built on different - * allocator instances have different types, limiting the utility of this - * approach. If you do not wish to share the free lists with the main - * default_alloc instance, instantiate this with a non-zero __inst. - * - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - template<bool __threads, int __inst> - class __default_alloc_template - { - private: - enum {_ALIGN = 8}; - enum {_MAX_BYTES = 128}; - enum {_NFREELISTS = _MAX_BYTES / _ALIGN}; - - union _Obj - { - union _Obj* _M_free_list_link; - char _M_client_data[1]; // The client sees this. - }; - - static _Obj* volatile _S_free_list[_NFREELISTS]; - - // Chunk allocation state. - static char* _S_start_free; - static char* _S_end_free; - static size_t _S_heap_size; - - static _STL_mutex_lock _S_node_allocator_lock; - - static size_t - _S_round_up(size_t __bytes) - { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); } - - static size_t - _S_freelist_index(size_t __bytes) - { return (((__bytes) + (size_t)_ALIGN - 1)/(size_t)_ALIGN - 1); } - - // Returns an object of size __n, and optionally adds to size __n - // free list. - static void* - _S_refill(size_t __n); - - // Allocates a chunk for nobjs of size size. nobjs may be reduced - // if it is inconvenient to allocate the requested number. - static char* - _S_chunk_alloc(size_t __size, int& __nobjs); - - // It would be nice to use _STL_auto_lock here. But we need a - // test whether threads are in use. - struct _Lock - { - _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); } - ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); } - } __attribute__ ((__unused__)); - friend struct _Lock; - - static _Atomic_word _S_force_new; - - public: - // __n must be > 0 - static void* - allocate(size_t __n) - { - void* __ret = 0; - - // If there is a race through here, assume answer from getenv - // will resolve in same direction. Inspired by techniques - // to efficiently support threading found in basic_string.h. - if (_S_force_new == 0) - { - if (getenv("GLIBCPP_FORCE_NEW")) - __atomic_add(&_S_force_new, 1); - else - __atomic_add(&_S_force_new, -1); - } - - if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0)) - __ret = __new_alloc::allocate(__n); - else - { - _Obj* volatile* __my_free_list = _S_free_list - + _S_freelist_index(__n); - // Acquire the lock here with a constructor call. This - // ensures that it is released in exit or during stack - // unwinding. - _Lock __lock_instance; - _Obj* __restrict__ __result = *__my_free_list; - if (__builtin_expect(__result == 0, 0)) - __ret = _S_refill(_S_round_up(__n)); - else - { - *__my_free_list = __result -> _M_free_list_link; - __ret = __result; - } - if (__builtin_expect(__ret == 0, 0)) - __throw_bad_alloc(); - } - return __ret; - } - - // __p may not be 0 - static void - deallocate(void* __p, size_t __n) - { - if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0)) - __new_alloc::deallocate(__p, __n); - else - { - _Obj* volatile* __my_free_list = _S_free_list - + _S_freelist_index(__n); - _Obj* __q = (_Obj*)__p; - - // Acquire the lock here with a constructor call. This - // ensures that it is released in exit or during stack - // unwinding. - _Lock __lock_instance; - __q -> _M_free_list_link = *__my_free_list; - *__my_free_list = __q; - } - } - - static void* - reallocate(void* __p, size_t __old_sz, size_t __new_sz); - }; - - template<bool __threads, int __inst> _Atomic_word - __default_alloc_template<__threads, __inst>::_S_force_new = 0; - - template<bool __threads, int __inst> - inline bool - operator==(const __default_alloc_template<__threads,__inst>&, - const __default_alloc_template<__threads,__inst>&) - { return true; } - - template<bool __threads, int __inst> - inline bool - operator!=(const __default_alloc_template<__threads,__inst>&, - const __default_alloc_template<__threads,__inst>&) - { return false; } - - - // We allocate memory in large chunks in order to avoid fragmenting the - // heap too much. We assume that __size is properly aligned. We hold - // the allocation lock. - template<bool __threads, int __inst> - char* - __default_alloc_template<__threads, __inst>:: - _S_chunk_alloc(size_t __size, int& __nobjs) - { - char* __result; - size_t __total_bytes = __size * __nobjs; - size_t __bytes_left = _S_end_free - _S_start_free; - - if (__bytes_left >= __total_bytes) - { - __result = _S_start_free; - _S_start_free += __total_bytes; - return __result ; - } - else if (__bytes_left >= __size) - { - __nobjs = (int)(__bytes_left/__size); - __total_bytes = __size * __nobjs; - __result = _S_start_free; - _S_start_free += __total_bytes; - return __result; - } - else - { - size_t __bytes_to_get = - 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); - // Try to make use of the left-over piece. - if (__bytes_left > 0) - { - _Obj* volatile* __my_free_list = - _S_free_list + _S_freelist_index(__bytes_left); - - ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list; - *__my_free_list = (_Obj*)(void*)_S_start_free; - } - _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get); - if (_S_start_free == 0) - { - size_t __i; - _Obj* volatile* __my_free_list; - _Obj* __p; - // Try to make do with what we have. That can't hurt. We - // do not try smaller requests, since that tends to result - // in disaster on multi-process machines. - __i = __size; - for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) - { - __my_free_list = _S_free_list + _S_freelist_index(__i); - __p = *__my_free_list; - if (__p != 0) - { - *__my_free_list = __p -> _M_free_list_link; - _S_start_free = (char*)__p; - _S_end_free = _S_start_free + __i; - return _S_chunk_alloc(__size, __nobjs); - // Any leftover piece will eventually make it to the - // right free list. - } - } - _S_end_free = 0; // In case of exception. - _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get); - // This should either throw an exception or remedy the situation. - // Thus we assume it succeeded. - } - _S_heap_size += __bytes_to_get; - _S_end_free = _S_start_free + __bytes_to_get; - return _S_chunk_alloc(__size, __nobjs); - } - } - - - // Returns an object of size __n, and optionally adds to "size - // __n"'s free list. We assume that __n is properly aligned. We - // hold the allocation lock. - template<bool __threads, int __inst> - void* - __default_alloc_template<__threads, __inst>::_S_refill(size_t __n) - { - int __nobjs = 20; - char* __chunk = _S_chunk_alloc(__n, __nobjs); - _Obj* volatile* __my_free_list; - _Obj* __result; - _Obj* __current_obj; - _Obj* __next_obj; - int __i; - - if (1 == __nobjs) - return __chunk; - __my_free_list = _S_free_list + _S_freelist_index(__n); - - // Build free list in chunk. - __result = (_Obj*)(void*)__chunk; - *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n); - for (__i = 1; ; __i++) - { - __current_obj = __next_obj; - __next_obj = (_Obj*)(void*)((char*)__next_obj + __n); - if (__nobjs - 1 == __i) - { - __current_obj -> _M_free_list_link = 0; - break; - } - else - __current_obj -> _M_free_list_link = __next_obj; - } - return __result; - } - - - template<bool threads, int inst> - void* - __default_alloc_template<threads, inst>:: - reallocate(void* __p, size_t __old_sz, size_t __new_sz) - { - void* __result; - size_t __copy_sz; - - if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) - return(realloc(__p, __new_sz)); - if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) - return(__p); - __result = allocate(__new_sz); - __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; - memcpy(__result, __p, __copy_sz); - deallocate(__p, __old_sz); - return __result; - } - - template<bool __threads, int __inst> - _STL_mutex_lock - __default_alloc_template<__threads,__inst>::_S_node_allocator_lock - __STL_MUTEX_INITIALIZER; - - template<bool __threads, int __inst> - char* __default_alloc_template<__threads,__inst>::_S_start_free = 0; - - template<bool __threads, int __inst> - char* __default_alloc_template<__threads,__inst>::_S_end_free = 0; - - template<bool __threads, int __inst> - size_t __default_alloc_template<__threads,__inst>::_S_heap_size = 0; - - template<bool __threads, int __inst> - typename __default_alloc_template<__threads,__inst>::_Obj* volatile - __default_alloc_template<__threads,__inst>::_S_free_list[_NFREELISTS]; - - typedef __default_alloc_template<true,0> __alloc; - typedef __default_alloc_template<false,0> __single_client_alloc; - - - /** - * @brief The "standard" allocator, as per [20.4]. - * - * The private _Alloc is "SGI" style. (See comments at the top - * of stl_alloc.h.) - * - * The underlying allocator behaves as follows. - * - __default_alloc_template is used via two typedefs - * - "__single_client_alloc" typedef does no locking for threads - * - "__alloc" typedef is threadsafe via the locks - * - __new_alloc is used for memory requests - * - * (See @link Allocators allocators info @endlink for more.) - */ - template<typename _Tp> - class allocator - { - typedef __alloc _Alloc; // The underlying allocator. - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp* pointer; - typedef const _Tp* const_pointer; - typedef _Tp& reference; - typedef const _Tp& const_reference; - typedef _Tp value_type; - - template<typename _Tp1> - struct rebind - { typedef allocator<_Tp1> other; }; - - allocator() throw() {} - allocator(const allocator&) throw() {} - template<typename _Tp1> - allocator(const allocator<_Tp1>&) throw() {} - ~allocator() throw() {} - - pointer - address(reference __x) const { return &__x; } - - const_pointer - address(const_reference __x) const { return &__x; } - - // NB: __n is permitted to be 0. The C++ standard says nothing - // about what the return value is when __n == 0. - _Tp* - allocate(size_type __n, const void* = 0) - { - _Tp* __ret = 0; - if (__n) - { - if (__n <= this->max_size()) - __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); - else - __throw_bad_alloc(); - } - return __ret; - } - - // __p is not permitted to be a null pointer. - void - deallocate(pointer __p, size_type __n) - { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } - - size_type - max_size() const throw() { return size_t(-1) / sizeof(_Tp); } - - void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } - void destroy(pointer __p) { __p->~_Tp(); } - }; - - template<> - class allocator<void> - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template<typename _Tp1> - struct rebind - { typedef allocator<_Tp1> other; }; - }; - - - template<typename _T1, typename _T2> - inline bool - operator==(const allocator<_T1>&, const allocator<_T2>&) - { return true; } - - template<typename _T1, typename _T2> - inline bool - operator!=(const allocator<_T1>&, const allocator<_T2>&) - { return false; } - - - /** - * @if maint - * Allocator adaptor to turn an "SGI" style allocator (e.g., - * __alloc, __malloc_alloc_template) into a "standard" conforming - * allocator. Note that this adaptor does *not* assume that all - * objects of the underlying alloc class are identical, nor does it - * assume that all of the underlying alloc's member functions are - * static member functions. Note, also, that __allocator<_Tp, - * __alloc> is essentially the same thing as allocator<_Tp>. - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - template<typename _Tp, typename _Alloc> - struct __allocator - { - _Alloc __underlying_alloc; - - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp* pointer; - typedef const _Tp* const_pointer; - typedef _Tp& reference; - typedef const _Tp& const_reference; - typedef _Tp value_type; - - template<typename _Tp1> - struct rebind - { typedef __allocator<_Tp1, _Alloc> other; }; - - __allocator() throw() {} - __allocator(const __allocator& __a) throw() - : __underlying_alloc(__a.__underlying_alloc) {} - - template<typename _Tp1> - __allocator(const __allocator<_Tp1, _Alloc>& __a) throw() - : __underlying_alloc(__a.__underlying_alloc) {} - - ~__allocator() throw() {} - - pointer - address(reference __x) const { return &__x; } - - const_pointer - address(const_reference __x) const { return &__x; } - - // NB: __n is permitted to be 0. The C++ standard says nothing - // about what the return value is when __n == 0. - _Tp* - allocate(size_type __n, const void* = 0) - { - _Tp* __ret = 0; - if (__n) - __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); - return __ret; - } - - // __p is not permitted to be a null pointer. - void - deallocate(pointer __p, size_type __n) - { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } - - size_type - max_size() const throw() { return size_t(-1) / sizeof(_Tp); } - - void - construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } - - void - destroy(pointer __p) { __p->~_Tp(); } - }; - - template<typename _Alloc> - struct __allocator<void, _Alloc> - { - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template<typename _Tp1> - struct rebind - { typedef __allocator<_Tp1, _Alloc> other; }; - }; - - template<typename _Tp, typename _Alloc> - inline bool - operator==(const __allocator<_Tp,_Alloc>& __a1, - const __allocator<_Tp,_Alloc>& __a2) - { return __a1.__underlying_alloc == __a2.__underlying_alloc; } - - template<typename _Tp, typename _Alloc> - inline bool - operator!=(const __allocator<_Tp, _Alloc>& __a1, - const __allocator<_Tp, _Alloc>& __a2) - { return __a1.__underlying_alloc != __a2.__underlying_alloc; } - - - //@{ - /** Comparison operators for all of the predifined SGI-style allocators. - * This ensures that __allocator<malloc_alloc> (for example) will work - * correctly. As required, all allocators compare equal. - */ - template<int inst> - inline bool - operator==(const __malloc_alloc_template<inst>&, - const __malloc_alloc_template<inst>&) - { return true; } - - template<int __inst> - inline bool - operator!=(const __malloc_alloc_template<__inst>&, - const __malloc_alloc_template<__inst>&) - { return false; } - - template<typename _Alloc> - inline bool - operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&) - { return true; } - - template<typename _Alloc> - inline bool - operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&) - { return false; } - //@} - - - /** - * @if maint - * Another allocator adaptor: _Alloc_traits. This serves two purposes. - * First, make it possible to write containers that can use either "SGI" - * style allocators or "standard" allocators. Second, provide a mechanism - * so that containers can query whether or not the allocator has distinct - * instances. If not, the container can avoid wasting a word of memory to - * store an empty object. For examples of use, see stl_vector.h, etc, or - * any of the other classes derived from this one. - * - * This adaptor uses partial specialization. The general case of - * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a - * standard-conforming allocator, possibly with non-equal instances and - * non-static members. (It still behaves correctly even if _Alloc has - * static member and if all instances are equal. Refinements affect - * performance, not correctness.) - * - * There are always two members: allocator_type, which is a standard- - * conforming allocator type for allocating objects of type _Tp, and - * _S_instanceless, a static const member of type bool. If - * _S_instanceless is true, this means that there is no difference - * between any two instances of type allocator_type. Furthermore, if - * _S_instanceless is true, then _Alloc_traits has one additional - * member: _Alloc_type. This type encapsulates allocation and - * deallocation of objects of type _Tp through a static interface; it - * has two member functions, whose signatures are - * - * - static _Tp* allocate(size_t) - * - static void deallocate(_Tp*, size_t) - * - * The size_t parameters are "standard" style (see top of stl_alloc.h) in - * that they take counts, not sizes. - * - * @endif - * (See @link Allocators allocators info @endlink for more.) - */ - //@{ - // The fully general version. - template<typename _Tp, typename _Allocator> - struct _Alloc_traits - { - static const bool _S_instanceless = false; - typedef typename _Allocator::template rebind<_Tp>::other allocator_type; - }; - - template<typename _Tp, typename _Allocator> - const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; - - /// The version for the default allocator. - template<typename _Tp, typename _Tp1> - struct _Alloc_traits<_Tp, allocator<_Tp1> > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __alloc> _Alloc_type; - typedef allocator<_Tp> allocator_type; - }; - //@} - - //@{ - /// Versions for the predefined "SGI" style allocators. - template<typename _Tp, int __inst> - struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; - typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; - }; - - template<typename _Tp, bool __threads, int __inst> - struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > - _Alloc_type; - typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > - allocator_type; - }; - - template<typename _Tp, typename _Alloc> - struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type; - typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; - }; - //@} - - //@{ - /// Versions for the __allocator adaptor used with the predefined - /// "SGI" style allocators. - template<typename _Tp, typename _Tp1, int __inst> - struct _Alloc_traits<_Tp, - __allocator<_Tp1, __malloc_alloc_template<__inst> > > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; - typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; - }; - - template<typename _Tp, typename _Tp1, bool __thr, int __inst> - struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > - _Alloc_type; - typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > - allocator_type; - }; - - template<typename _Tp, typename _Tp1, typename _Alloc> - struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > > - { - static const bool _S_instanceless = true; - typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type; - typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type; - }; - //@} - - // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. - // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE - extern template class allocator<char>; - extern template class allocator<wchar_t>; - extern template class __default_alloc_template<true,0>; -#endif -} // namespace std - -#endif diff --git a/contrib/libstdc++/include/bits/stl_pthread_alloc.h b/contrib/libstdc++/include/bits/stl_pthread_alloc.h deleted file mode 100644 index 09b7d72..0000000 --- a/contrib/libstdc++/include/bits/stl_pthread_alloc.h +++ /dev/null @@ -1,60 +0,0 @@ -// Wrapper of pthread allocation header -*- C++ -*- - -// Copyright (C) 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// 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) 1996-1997 - * 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_pthread_alloc.h - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. - */ - -#ifndef _CPP_BITS_STL_PTHREAD_ALLOC_H -#define _CPP_BITS_STL_PTHREAD_ALLOC_H 1 - -#include <bits/pthread_allocimpl.h> - -using std::_Pthread_alloc_template; -using std::pthread_alloc; - -#endif /* _CPP_BITS_STL_PTHREAD_ALLOC_H */ - -// Local Variables: -// mode:C++ -// End: diff --git a/contrib/libstdc++/include/bits/valarray_meta.h b/contrib/libstdc++/include/bits/valarray_meta.h deleted file mode 100644 index 29a2dac..0000000 --- a/contrib/libstdc++/include/bits/valarray_meta.h +++ /dev/null @@ -1,1147 +0,0 @@ -// The template and inlines for the -*- C++ -*- internal _Meta class. - -// Copyright (C) 1997, 1998, 1999, 2000, 2001 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// 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. - -// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> - -/** @file valarray_meta.h - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. - */ - -#ifndef _CPP_VALARRAY_META_H -#define _CPP_VALARRAY_META_H 1 - -#pragma GCC system_header - -namespace std -{ - // - // Implementing a loosened valarray return value is tricky. - // First we need to meet 26.3.1/3: we should not add more than - // two levels of template nesting. Therefore we resort to template - // template to "flatten" loosened return value types. - // At some point we use partial specialization to remove one level - // template nesting due to _Expr<> - // - - // This class is NOT defined. It doesn't need to. - template<typename _Tp1, typename _Tp2> class _Constant; - - // Implementations of unary functions applied to valarray<>s. - // I use hard-coded object functions here instead of a generic - // approach like pointers to function: - // 1) correctness: some functions take references, others values. - // we can't deduce the correct type afterwards. - // 2) efficiency -- object functions can be easily inlined - // 3) be Koenig-lookup-friendly - - struct __abs - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return abs(__t); } - }; - - struct __cos - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return cos(__t); } - }; - - struct __acos - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return acos(__t); } - }; - - struct __cosh - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return cosh(__t); } - }; - - struct __sin - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return sin(__t); } - }; - - struct __asin - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return asin(__t); } - }; - - struct __sinh - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return sinh(__t); } - }; - - struct __tan - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return tan(__t); } - }; - - struct __atan - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return atan(__t); } - }; - - struct __tanh - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return tanh(__t); } - }; - - struct __exp - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return exp(__t); } - }; - - struct __log - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return log(__t); } - }; - - struct __log10 - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return log10(__t); } - }; - - struct __sqrt - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return sqrt(__t); } - }; - - // In the past, we used to tailor operator applications semantics - // to the specialization of standard function objects (i.e. plus<>, etc.) - // That is incorrect. Therefore we provide our own surrogates. - - struct __unary_plus - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return +__t; } - }; - - struct __negate - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return -__t; } - }; - - struct __bitwise_not - { - template<typename _Tp> - _Tp operator()(const _Tp& __t) const { return ~__t; } - }; - - struct __plus - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x + __y; } - }; - - struct __minus - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x - __y; } - }; - - struct __multiplies - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x * __y; } - }; - - struct __divides - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x / __y; } - }; - - struct __modulus - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x % __y; } - }; - - struct __bitwise_xor - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x ^ __y; } - }; - - struct __bitwise_and - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x & __y; } - }; - - struct __bitwise_or - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x | __y; } - }; - - struct __shift_left - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x << __y; } - }; - - struct __shift_right - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return __x >> __y; } - }; - - struct __logical_and - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x && __y; } - }; - - struct __logical_or - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x || __y; } - }; - - struct __logical_not - { - template<typename _Tp> - bool operator()(const _Tp& __x) const { return !__x; } - }; - - struct __equal_to - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x == __y; } - }; - - struct __not_equal_to - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x != __y; } - }; - - struct __less - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x < __y; } - }; - - struct __greater - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x > __y; } - }; - - struct __less_equal - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x <= __y; } - }; - - struct __greater_equal - { - template<typename _Tp> - bool operator()(const _Tp& __x, const _Tp& __y) const - { return __x >= __y; } - }; - - // The few binary functions we miss. - struct __atan2 - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return atan2(__x, __y); } - }; - - struct __pow - { - template<typename _Tp> - _Tp operator()(const _Tp& __x, const _Tp& __y) const - { return pow(__x, __y); } - }; - - - // We need these bits in order to recover the return type of - // some functions/operators now that we're no longer using - // function templates. - template<typename, typename _Tp> - struct __fun - { - typedef _Tp result_type; - }; - - // several specializations for relational operators. - template<typename _Tp> - struct __fun<__logical_not, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__logical_and, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__logical_or, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__less, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__greater, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__less_equal, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__greater_equal, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__equal_to, _Tp> - { - typedef bool result_type; - }; - - template<typename _Tp> - struct __fun<__not_equal_to, _Tp> - { - typedef bool result_type; - }; - - // - // Apply function taking a value/const reference closure - // - - template<typename _Dom, typename _Arg> - class _FunBase - { - public: - typedef typename _Dom::value_type value_type; - - _FunBase(const _Dom& __e, value_type __f(_Arg)) - : _M_expr(__e), _M_func(__f) {} - - value_type operator[](size_t __i) const - { return _M_func (_M_expr[__i]); } - - size_t size() const { return _M_expr.size ();} - - private: - const _Dom& _M_expr; - value_type (*_M_func)(_Arg); - }; - - template<class _Dom> - struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> - { - typedef _FunBase<_Dom, typename _Dom::value_type> _Base; - typedef typename _Base::value_type value_type; - typedef value_type _Tp; - - _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} - }; - - template<typename _Tp> - struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> - { - typedef _FunBase<valarray<_Tp>, _Tp> _Base; - typedef _Tp value_type; - - _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} - }; - - template<class _Dom> - struct _RefFunClos<_Expr,_Dom> : - _FunBase<_Dom, const typename _Dom::value_type&> - { - typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; - typedef typename _Base::value_type value_type; - typedef value_type _Tp; - - _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) - : _Base(__e, __f) {} - }; - - template<typename _Tp> - struct _RefFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, const _Tp&> - { - typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; - typedef _Tp value_type; - - _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) - : _Base(__v, __f) {} - }; - - // - // Unary expression closure. - // - - template<class _Oper, class _Arg> - class _UnBase - { - public: - typedef typename _Arg::value_type _Vt; - typedef typename __fun<_Oper, _Vt>::result_type value_type; - - _UnBase(const _Arg& __e) : _M_expr(__e) {} - - value_type operator[](size_t __i) const - { return _Oper()(_M_expr[__i]); } - - size_t size() const { return _M_expr.size(); } - - private: - const _Arg& _M_expr; - }; - - template<class _Oper, class _Dom> - struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> - { - typedef _Dom _Arg; - typedef _UnBase<_Oper, _Dom> _Base; - typedef typename _Base::value_type value_type; - - _UnClos(const _Arg& __e) : _Base(__e) {} - }; - - template<class _Oper, typename _Tp> - struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > - { - typedef valarray<_Tp> _Arg; - typedef _UnBase<_Oper, valarray<_Tp> > _Base; - typedef typename _Base::value_type value_type; - - _UnClos(const _Arg& __e) : _Base(__e) {} - }; - - - // - // Binary expression closure. - // - - template<class _Oper, class _FirstArg, class _SecondArg> - class _BinBase - { - public: - typedef typename _FirstArg::value_type _Vt; - typedef typename __fun<_Oper, _Vt>::result_type value_type; - - _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) - : _M_expr1(__e1), _M_expr2(__e2) {} - - value_type operator[](size_t __i) const - { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } - - size_t size() const { return _M_expr1.size(); } - - private: - const _FirstArg& _M_expr1; - const _SecondArg& _M_expr2; - }; - - - template<class _Oper, class _Clos> - class _BinBase2 - { - public: - typedef typename _Clos::value_type _Vt; - typedef typename __fun<_Oper, _Vt>::result_type value_type; - - _BinBase2(const _Clos& __e, const _Vt& __t) - : _M_expr1(__e), _M_expr2(__t) {} - - value_type operator[](size_t __i) const - { return _Oper()(_M_expr1[__i], _M_expr2); } - - size_t size() const { return _M_expr1.size(); } - - private: - const _Clos& _M_expr1; - const _Vt& _M_expr2; - }; - - template<class _Oper, class _Clos> - class _BinBase1 - { - public: - typedef typename _Clos::value_type _Vt; - typedef typename __fun<_Oper, _Vt>::result_type value_type; - - _BinBase1(const _Vt& __t, const _Clos& __e) - : _M_expr1(__t), _M_expr2(__e) {} - - value_type operator[](size_t __i) const - { return _Oper()(_M_expr1, _M_expr2[__i]); } - - size_t size() const { return _M_expr2.size(); } - - private: - const _Vt& _M_expr1; - const _Clos& _M_expr2; - }; - - template<class _Oper, class _Dom1, class _Dom2> - struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> - : _BinBase<_Oper,_Dom1,_Dom2> - { - typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} - }; - - template<class _Oper, typename _Tp> - struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> - : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > - { - typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; - typedef _Tp value_type; - - _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) - : _Base(__v, __w) {} - }; - - template<class _Oper, class _Dom> - struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> - : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > - { - typedef typename _Dom::value_type _Tp; - typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) - : _Base(__e1, __e2) {} - }; - - template<class _Oper, class _Dom> - struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> - : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> - { - typedef typename _Dom::value_type _Tp; - typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) - : _Base(__e1, __e2) {} - }; - - template<class _Oper, class _Dom> - struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> - : _BinBase2<_Oper,_Dom> - { - typedef typename _Dom::value_type _Tp; - typedef _BinBase2<_Oper,_Dom> _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} - }; - - template<class _Oper, class _Dom> - struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> - : _BinBase1<_Oper,_Dom> - { - typedef typename _Dom::value_type _Tp; - typedef _BinBase1<_Oper,_Dom> _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} - }; - - template<class _Oper, typename _Tp> - struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> - : _BinBase2<_Oper,valarray<_Tp> > - { - typedef _BinBase2<_Oper,valarray<_Tp> > _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} - }; - - template<class _Oper, typename _Tp> - struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> - : _BinBase1<_Oper,valarray<_Tp> > - { - typedef _BinBase1<_Oper,valarray<_Tp> > _Base; - typedef typename _Base::value_type value_type; - - _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} - }; - - - // - // slice_array closure. - // - template<typename _Dom> class _SBase { - public: - typedef typename _Dom::value_type value_type; - - _SBase (const _Dom& __e, const slice& __s) - : _M_expr (__e), _M_slice (__s) {} - value_type operator[] (size_t __i) const - { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } - size_t size() const { return _M_slice.size (); } - - private: - const _Dom& _M_expr; - const slice& _M_slice; - }; - - template<typename _Tp> class _SBase<_Array<_Tp> > { - public: - typedef _Tp value_type; - - _SBase (_Array<_Tp> __a, const slice& __s) - : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), - _M_stride (__s.stride()) {} - value_type operator[] (size_t __i) const - { return _M_array._M_data[__i * _M_stride]; } - size_t size() const { return _M_size; } - - private: - const _Array<_Tp> _M_array; - const size_t _M_size; - const size_t _M_stride; - }; - - template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> { - typedef _SBase<_Dom> _Base; - typedef typename _Base::value_type value_type; - - _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} - }; - - template<typename _Tp> - struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { - typedef _SBase<_Array<_Tp> > _Base; - typedef _Tp value_type; - - _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} - }; - - // - // gslice_array closure. - // - template<class _Dom> class _GBase { - public: - typedef typename _Dom::value_type value_type; - - _GBase (const _Dom& __e, const valarray<size_t>& __i) - : _M_expr (__e), _M_index(__i) {} - value_type operator[] (size_t __i) const - { return _M_expr[_M_index[__i]]; } - size_t size () const { return _M_index.size(); } - - private: - const _Dom& _M_expr; - const valarray<size_t>& _M_index; - }; - - template<typename _Tp> class _GBase<_Array<_Tp> > { - public: - typedef _Tp value_type; - - _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) - : _M_array (__a), _M_index(__i) {} - value_type operator[] (size_t __i) const - { return _M_array._M_data[_M_index[__i]]; } - size_t size () const { return _M_index.size(); } - - private: - const _Array<_Tp> _M_array; - const valarray<size_t>& _M_index; - }; - - template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> { - typedef _GBase<_Dom> _Base; - typedef typename _Base::value_type value_type; - - _GClos (const _Dom& __e, const valarray<size_t>& __i) - : _Base (__e, __i) {} - }; - - template<typename _Tp> - struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { - typedef _GBase<_Array<_Tp> > _Base; - typedef typename _Base::value_type value_type; - - _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) - : _Base (__a, __i) {} - }; - - // - // indirect_array closure - // - - template<class _Dom> class _IBase { - public: - typedef typename _Dom::value_type value_type; - - _IBase (const _Dom& __e, const valarray<size_t>& __i) - : _M_expr (__e), _M_index (__i) {} - value_type operator[] (size_t __i) const - { return _M_expr[_M_index[__i]]; } - size_t size() const { return _M_index.size(); } - - private: - const _Dom& _M_expr; - const valarray<size_t>& _M_index; - }; - - template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> { - typedef _IBase<_Dom> _Base; - typedef typename _Base::value_type value_type; - - _IClos (const _Dom& __e, const valarray<size_t>& __i) - : _Base (__e, __i) {} - }; - - template<typename _Tp> - struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > { - typedef _IBase<valarray<_Tp> > _Base; - typedef _Tp value_type; - - _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) - : _Base (__a, __i) {} - }; - - // - // class _Expr - // - template<class _Clos, typename _Tp> - class _Expr - { - public: - typedef _Tp value_type; - - _Expr(const _Clos&); - - const _Clos& operator()() const; - - value_type operator[](size_t) const; - valarray<value_type> operator[](slice) const; - valarray<value_type> operator[](const gslice&) const; - valarray<value_type> operator[](const valarray<bool>&) const; - valarray<value_type> operator[](const valarray<size_t>&) const; - - _Expr<_UnClos<__unary_plus,std::_Expr,_Clos>, value_type> - operator+() const; - - _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type> - operator-() const; - - _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type> - operator~() const; - - _Expr<_UnClos<__logical_not,std::_Expr,_Clos>, bool> - operator!() const; - - size_t size() const; - value_type sum() const; - - valarray<value_type> shift(int) const; - valarray<value_type> cshift(int) const; - - value_type min() const; - value_type max() const; - - valarray<value_type> apply(value_type (*)(const value_type&)) const; - valarray<value_type> apply(value_type (*)(value_type)) const; - - private: - const _Clos _M_closure; - }; - - template<class _Clos, typename _Tp> - inline - _Expr<_Clos,_Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} - - template<class _Clos, typename _Tp> - inline const _Clos& - _Expr<_Clos,_Tp>::operator()() const - { return _M_closure; } - - template<class _Clos, typename _Tp> - inline _Tp - _Expr<_Clos,_Tp>::operator[](size_t __i) const - { return _M_closure[__i]; } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos,_Tp>::operator[](slice __s) const - { return _M_closure[__s]; } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos,_Tp>::operator[](const gslice& __gs) const - { return _M_closure[__gs]; } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos,_Tp>::operator[](const valarray<bool>& __m) const - { return _M_closure[__m]; } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos,_Tp>::operator[](const valarray<size_t>& __i) const - { return _M_closure[__i]; } - - template<class _Clos, typename _Tp> - inline size_t - _Expr<_Clos,_Tp>::size() const { return _M_closure.size (); } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos, _Tp>::shift(int __n) const - { return valarray<_Tp>(_M_closure).shift(__n); } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos, _Tp>::cshift(int __n) const - { return valarray<_Tp>(_M_closure).cshift(__n); } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const - { return valarray<_Tp>(_M_closure).apply(__f); } - - template<class _Clos, typename _Tp> - inline valarray<_Tp> - _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const - { return valarray<_Tp>(_M_closure).apply(__f); } - - // XXX: replace this with a more robust summation algorithm. - template<class _Clos, typename _Tp> - inline _Tp - _Expr<_Clos,_Tp>::sum() const - { - size_t __n = _M_closure.size(); - if (__n == 0) - return _Tp(); - else - { - _Tp __s = _M_closure[--__n]; - while (__n != 0) - __s += _M_closure[--__n]; - return __s; - } - } - - template<class _Clos, typename _Tp> - inline _Tp - _Expr<_Clos, _Tp>::min() const - { return __valarray_min(_M_closure); } - - template<class _Clos, typename _Tp> - inline _Tp - _Expr<_Clos, _Tp>::max() const - { return __valarray_max(_M_closure); } - - template<class _Dom, typename _Tp> - inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool> - _Expr<_Dom,_Tp>::operator!() const - { - typedef _UnClos<__logical_not,std::_Expr,_Dom> _Closure; - return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); - } - -#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ - template<class _Dom, typename _Tp> \ - inline _Expr<_UnClos<_Name,std::_Expr,_Dom>,_Tp> \ - _Expr<_Dom,_Tp>::operator _Op() const \ - { \ - typedef _UnClos<_Name,std::_Expr,_Dom> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(this->_M_closure)); \ - } - - _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) - _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) - _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) - -#undef _DEFINE_EXPR_UNARY_OPERATOR - - -#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ - template<class _Dom1, class _Dom2> \ - inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ - typename __fun<_Name, typename _Dom1::value_type>::result_type>\ - operator _Op(const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ - const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ - { \ - typedef typename _Dom1::value_type _Arg; \ - typedef typename __fun<_Name, _Arg>::result_type _Value; \ - typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ - return _Expr<_Closure,_Value>(_Closure(__v(), __w())); \ - } \ - \ -template<class _Dom> \ -inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>,\ - typename __fun<_Name, typename _Dom::value_type>::result_type>\ -operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __v, \ - const typename _Dom::value_type& __t) \ -{ \ - typedef typename _Dom::value_type _Arg; \ - typedef typename __fun<_Name, _Arg>::result_type _Value; \ - typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ - return _Expr<_Closure,_Value>(_Closure(__v(), __t)); \ -} \ - \ -template<class _Dom> \ -inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>,\ - typename __fun<_Name, typename _Dom::value_type>::result_type>\ -operator _Op(const typename _Dom::value_type& __t, \ - const _Expr<_Dom,typename _Dom::value_type>& __v) \ -{ \ - typedef typename _Dom::value_type _Arg; \ - typedef typename __fun<_Name, _Arg>::result_type _Value; \ - typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ - return _Expr<_Closure,_Value>(_Closure(__t, __v())); \ -} \ - \ -template<class _Dom> \ -inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>,\ - typename __fun<_Name, typename _Dom::value_type>::result_type>\ -operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ - const valarray<typename _Dom::value_type>& __v) \ -{ \ - typedef typename _Dom::value_type _Arg; \ - typedef typename __fun<_Name, _Arg>::result_type _Value; \ - typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ - return _Expr<_Closure,_Value>(_Closure(__e(), __v)); \ -} \ - \ -template<class _Dom> \ -inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>,\ - typename __fun<_Name, typename _Dom::value_type>::result_type>\ -operator _Op(const valarray<typename _Dom::value_type>& __v, \ - const _Expr<_Dom,typename _Dom::value_type>& __e) \ -{ \ - typedef typename _Dom::value_type _Tp; \ - typedef typename __fun<_Name, _Tp>::result_type _Value; \ - typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ - return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ -} - - _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) - _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) - _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) - _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) - _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) - _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) - _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) - _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) - _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) - _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) - _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) - _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) - _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) - _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) - _DEFINE_EXPR_BINARY_OPERATOR(<, __less) - _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) - _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) - _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) - -#undef _DEFINE_EXPR_BINARY_OPERATOR - -#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ - template<class _Dom> \ - inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\ - _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ - { \ - typedef typename _Dom::value_type _Tp; \ - typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__e())); \ - } \ - \ - template<typename _Tp> \ - inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \ - _Name(const valarray<_Tp>& __v) \ - { \ - typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__v)); \ - } - - _DEFINE_EXPR_UNARY_FUNCTION(abs) - _DEFINE_EXPR_UNARY_FUNCTION(cos) - _DEFINE_EXPR_UNARY_FUNCTION(acos) - _DEFINE_EXPR_UNARY_FUNCTION(cosh) - _DEFINE_EXPR_UNARY_FUNCTION(sin) - _DEFINE_EXPR_UNARY_FUNCTION(asin) - _DEFINE_EXPR_UNARY_FUNCTION(sinh) - _DEFINE_EXPR_UNARY_FUNCTION(tan) - _DEFINE_EXPR_UNARY_FUNCTION(tanh) - _DEFINE_EXPR_UNARY_FUNCTION(atan) - _DEFINE_EXPR_UNARY_FUNCTION(exp) - _DEFINE_EXPR_UNARY_FUNCTION(log) - _DEFINE_EXPR_UNARY_FUNCTION(log10) - _DEFINE_EXPR_UNARY_FUNCTION(sqrt) - -#undef _DEFINE_EXPR_UNARY_FUNCTION - -#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ - template<class _Dom1, class _Dom2> \ - inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \ - typename _Dom1::value_type> \ - _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ - const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ - { \ - typedef typename _Dom1::value_type _Tp; \ - typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \ - } \ - \ - template<class _Dom> \ - inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ - typename _Dom::value_type>, \ - typename _Dom::value_type> \ - _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \ - const valarray<typename _Dom::value_type>& __v) \ - { \ - typedef typename _Dom::value_type _Tp; \ - typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\ - return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \ - } \ - \ - template<class _Dom> \ - inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ - typename _Dom::value_type,_Dom>, \ - typename _Dom::value_type> \ - _Fun(const valarray<typename _Dom::valarray>& __v, \ - const _Expr<_Dom,typename _Dom::value_type>& __e) \ - { \ - typedef typename _Dom::value_type _Tp; \ - typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \ - } \ - \ - template<class _Dom> \ - inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \ - typename _Dom::value_type>, \ - typename _Dom::value_type> \ - _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ - const typename _Dom::value_type& __t) \ - { \ - typedef typename _Dom::value_type _Tp; \ - typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \ - } \ - \ - template<class _Dom> \ - inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \ - typename _Dom::value_type,_Dom>, \ - typename _Dom::value_type> \ - _Fun(const typename _Dom::value_type& __t, \ - const _Expr<_Dom,typename _Dom::value_type>& __e) \ - { \ - typedef typename _Dom::value_type _Tp; \ - typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \ - } \ - \ - template<typename _Tp> \ - inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ - _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ - { \ - typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \ - } \ - \ - template<typename _Tp> \ - inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ - _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ - { \ - typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \ - } \ - \ - template<typename _Tp> \ - inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ - _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ - { \ - typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \ - return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \ - } - -_DEFINE_EXPR_BINARY_FUNCTION(atan2) -_DEFINE_EXPR_BINARY_FUNCTION(pow) - -#undef _DEFINE_EXPR_BINARY_FUNCTION - -} // std:: - - -#endif /* _CPP_VALARRAY_META_H */ - -// Local Variables: -// mode:c++ -// End: |