feat: multi-user system, bug fixes, security & performance fixes, and more

This commit is contained in:
2026-03-14 13:28:46 +01:00
parent 576ad34f95
commit 261b536041
389 changed files with 231853 additions and 591 deletions
@@ -0,0 +1,128 @@
// Aligned memory buffer -*- C++ -*-
// Copyright (C) 2013-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/aligned_buffer.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _ALIGNED_BUFFER_H
#define _ALIGNED_BUFFER_H 1
#pragma GCC system_header
#if __cplusplus >= 201103L
# include <type_traits>
#else
# include <bits/c++0x_warning.h>
#endif
namespace __gnu_cxx
{
// A utility type containing a POD object that can hold an object of type
// _Tp initialized via placement new or allocator_traits::construct.
// Intended for use as a data member subobject, use __aligned_buffer for
// complete objects.
template<typename _Tp>
struct __aligned_membuf
{
// Target macro ADJUST_FIELD_ALIGN can produce different alignment for
// types when used as class members. __aligned_membuf is intended
// for use as a class member, so align the buffer as for a class member.
// Since GCC 8 we could just use alignof(_Tp) instead, but older
// versions of non-GNU compilers might still need this trick.
struct _Tp2 { _Tp _M_t; };
alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
__aligned_membuf() = default;
// Can be used to avoid value-initialization zeroing _M_storage.
__aligned_membuf(std::nullptr_t) { }
void*
_M_addr() noexcept
{ return static_cast<void*>(&_M_storage); }
const void*
_M_addr() const noexcept
{ return static_cast<const void*>(&_M_storage); }
_Tp*
_M_ptr() noexcept
{ return static_cast<_Tp*>(_M_addr()); }
const _Tp*
_M_ptr() const noexcept
{ return static_cast<const _Tp*>(_M_addr()); }
};
#if _GLIBCXX_INLINE_VERSION
template<typename _Tp>
using __aligned_buffer = __aligned_membuf<_Tp>;
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// Similar to __aligned_membuf but aligned for complete objects, not members.
// This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
// and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
// instead, as it has smaller size for some types on some targets.
// This type is still used to avoid an ABI change.
template<typename _Tp>
struct __aligned_buffer
: std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>
{
typename
std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage;
__aligned_buffer() = default;
// Can be used to avoid value-initialization
__aligned_buffer(std::nullptr_t) { }
void*
_M_addr() noexcept
{
return static_cast<void*>(&_M_storage);
}
const void*
_M_addr() const noexcept
{
return static_cast<const void*>(&_M_storage);
}
_Tp*
_M_ptr() noexcept
{ return static_cast<_Tp*>(_M_addr()); }
const _Tp*
_M_ptr() const noexcept
{ return static_cast<const _Tp*>(_M_addr()); }
};
#pragma GCC diagnostic pop
#endif
} // namespace
#endif /* _ALIGNED_BUFFER_H */
+185
View File
@@ -0,0 +1,185 @@
// Allocator traits -*- C++ -*-
// Copyright (C) 2011-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/alloc_traits.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _EXT_ALLOC_TRAITS_H
#define _EXT_ALLOC_TRAITS_H 1
#pragma GCC system_header
# include <bits/alloc_traits.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Uniform interface to C++98 and C++11 allocators.
* @ingroup allocators
*/
template<typename _Alloc, typename = typename _Alloc::value_type>
struct __alloc_traits
#if __cplusplus >= 201103L
: std::allocator_traits<_Alloc>
#endif
{
typedef _Alloc allocator_type;
#if __cplusplus >= 201103L
typedef std::allocator_traits<_Alloc> _Base_type;
typedef typename _Base_type::value_type value_type;
typedef typename _Base_type::pointer pointer;
typedef typename _Base_type::const_pointer const_pointer;
typedef typename _Base_type::size_type size_type;
typedef typename _Base_type::difference_type difference_type;
// C++11 allocators do not define reference or const_reference
typedef value_type& reference;
typedef const value_type& const_reference;
using _Base_type::allocate;
using _Base_type::deallocate;
using _Base_type::construct;
using _Base_type::destroy;
using _Base_type::max_size;
private:
template<typename _Ptr>
using __is_custom_pointer
= std::__and_<std::is_same<pointer, _Ptr>,
std::__not_<std::is_pointer<_Ptr>>>;
public:
// overload construct for non-standard pointer types
template<typename _Ptr, typename... _Args>
[[__gnu__::__always_inline__]]
static _GLIBCXX14_CONSTEXPR
std::__enable_if_t<__is_custom_pointer<_Ptr>::value>
construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
noexcept(noexcept(_Base_type::construct(__a, std::__to_address(__p),
std::forward<_Args>(__args)...)))
{
_Base_type::construct(__a, std::__to_address(__p),
std::forward<_Args>(__args)...);
}
// overload destroy for non-standard pointer types
template<typename _Ptr>
[[__gnu__::__always_inline__]]
static _GLIBCXX14_CONSTEXPR
std::__enable_if_t<__is_custom_pointer<_Ptr>::value>
destroy(_Alloc& __a, _Ptr __p)
noexcept(noexcept(_Base_type::destroy(__a, std::__to_address(__p))))
{ _Base_type::destroy(__a, std::__to_address(__p)); }
[[__gnu__::__always_inline__]]
static constexpr _Alloc _S_select_on_copy(const _Alloc& __a)
{ return _Base_type::select_on_container_copy_construction(__a); }
[[__gnu__::__always_inline__]]
static _GLIBCXX14_CONSTEXPR void _S_on_swap(_Alloc& __a, _Alloc& __b)
{ std::__alloc_on_swap(__a, __b); }
[[__gnu__::__always_inline__]]
static constexpr bool _S_propagate_on_copy_assign()
{ return _Base_type::propagate_on_container_copy_assignment::value; }
[[__gnu__::__always_inline__]]
static constexpr bool _S_propagate_on_move_assign()
{ return _Base_type::propagate_on_container_move_assignment::value; }
[[__gnu__::__always_inline__]]
static constexpr bool _S_propagate_on_swap()
{ return _Base_type::propagate_on_container_swap::value; }
[[__gnu__::__always_inline__]]
static constexpr bool _S_always_equal()
{ return _Base_type::is_always_equal::value; }
__attribute__((__always_inline__))
static constexpr bool _S_nothrow_move()
{ return _S_propagate_on_move_assign() || _S_always_equal(); }
template<typename _Tp>
struct rebind
{ typedef typename _Base_type::template rebind_alloc<_Tp> other; };
#else // ! C++11
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
typedef typename _Alloc::value_type value_type;
typedef typename _Alloc::reference reference;
typedef typename _Alloc::const_reference const_reference;
typedef typename _Alloc::size_type size_type;
typedef typename _Alloc::difference_type difference_type;
__attribute__((__always_inline__)) _GLIBCXX_NODISCARD
static pointer
allocate(_Alloc& __a, size_type __n)
{ return __a.allocate(__n); }
template<typename _Hint>
__attribute__((__always_inline__)) _GLIBCXX_NODISCARD
static pointer
allocate(_Alloc& __a, size_type __n, _Hint __hint)
{ return __a.allocate(__n, __hint); }
__attribute__((__always_inline__))
static void deallocate(_Alloc& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
template<typename _Tp>
__attribute__((__always_inline__))
static void construct(_Alloc& __a, pointer __p, const _Tp& __arg)
{ __a.construct(__p, __arg); }
__attribute__((__always_inline__))
static void destroy(_Alloc& __a, pointer __p)
{ __a.destroy(__p); }
__attribute__((__always_inline__))
static size_type max_size(const _Alloc& __a)
{ return __a.max_size(); }
__attribute__((__always_inline__))
static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; }
__attribute__((__always_inline__))
static void _S_on_swap(_Alloc& __a, _Alloc& __b)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 431. Swapping containers with unequal allocators.
std::__alloc_swap<_Alloc>::_S_do_it(__a, __b);
}
template<typename _Tp>
struct rebind
{ typedef typename _Alloc::template rebind<_Tp>::other other; };
#endif // C++11
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx
#endif
+127
View File
@@ -0,0 +1,127 @@
// Support for atomic operations -*- C++ -*-
// Copyright (C) 2004-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/atomicity.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_ATOMICITY_H
#define _GLIBCXX_ATOMICITY_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/gthr.h>
#include <bits/atomic_word.h>
#if __has_include(<sys/single_threaded.h>)
# include <sys/single_threaded.h>
#endif
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
__attribute__((__always_inline__))
inline bool
__is_single_threaded() _GLIBCXX_NOTHROW
{
#ifndef __GTHREADS
return true;
#elif __has_include(<sys/single_threaded.h>)
return ::__libc_single_threaded;
#else
return !__gthread_active_p();
#endif
}
// Functions for portable atomic access.
// To abstract locking primitives across all thread policies, use:
// __exchange_and_add_dispatch
// __atomic_add_dispatch
#ifdef _GLIBCXX_ATOMIC_BUILTINS
inline _Atomic_word
__attribute__((__always_inline__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
inline void
__attribute__((__always_inline__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
#else
_Atomic_word
__exchange_and_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW;
void
__atomic_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW;
#endif
inline _Atomic_word
__attribute__((__always_inline__))
__exchange_and_add_single(_Atomic_word* __mem, int __val)
{
_Atomic_word __result = *__mem;
*__mem += __val;
return __result;
}
inline void
__attribute__((__always_inline__))
__atomic_add_single(_Atomic_word* __mem, int __val)
{ *__mem += __val; }
inline _Atomic_word
__attribute__ ((__always_inline__))
__exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
{
if (__is_single_threaded())
return __exchange_and_add_single(__mem, __val);
else
return __exchange_and_add(__mem, __val);
}
inline void
__attribute__ ((__always_inline__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
if (__is_single_threaded())
__atomic_add_single(__mem, __val);
else
__atomic_add(__mem, __val);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
// Even if the CPU doesn't need a memory barrier, we need to ensure
// that the compiler doesn't reorder memory accesses across the
// barriers.
#ifndef _GLIBCXX_READ_MEM_BARRIER
#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
#endif
#ifndef _GLIBCXX_WRITE_MEM_BARRIER
#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
#endif
#endif
+121
View File
@@ -0,0 +1,121 @@
// <cast.h> -*- C++ -*-
// Copyright (C) 2008-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/cast.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ext/pointer.h}
*/
#ifndef _GLIBCXX_CAST_H
#define _GLIBCXX_CAST_H 1
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* These functions are here to allow containers to support non standard
* pointer types. For normal pointers, these resolve to the use of the
* standard cast operation. For other types the functions will perform
* the appropriate cast to/from the custom pointer class so long as that
* class meets the following conditions:
* 1) has a typedef element_type which names tehe type it points to.
* 2) has a get() const method which returns element_type*.
* 3) has a constructor which can take one element_type* argument.
*/
/**
* This type supports the semantics of the pointer cast operators (below.)
*/
template<typename _ToType>
struct _Caster
{ typedef typename _ToType::element_type* type; };
template<typename _ToType>
struct _Caster<_ToType*>
{ typedef _ToType* type; };
/**
* Casting operations for cases where _FromType is not a standard pointer.
* _ToType can be a standard or non-standard pointer. Given that _FromType
* is not a pointer, it must have a get() method that returns the standard
* pointer equivalent of the address it points to, and must have an
* element_type typedef which names the type it points to.
*/
template<typename _ToType, typename _FromType>
inline _ToType
__static_pointer_cast(const _FromType& __arg)
{ return _ToType(static_cast<typename _Caster<_ToType>::
type>(__arg.get())); }
template<typename _ToType, typename _FromType>
inline _ToType
__dynamic_pointer_cast(const _FromType& __arg)
{ return _ToType(dynamic_cast<typename _Caster<_ToType>::
type>(__arg.get())); }
template<typename _ToType, typename _FromType>
inline _ToType
__const_pointer_cast(const _FromType& __arg)
{ return _ToType(const_cast<typename _Caster<_ToType>::
type>(__arg.get())); }
template<typename _ToType, typename _FromType>
inline _ToType
__reinterpret_pointer_cast(const _FromType& __arg)
{ return _ToType(reinterpret_cast<typename _Caster<_ToType>::
type>(__arg.get())); }
/**
* Casting operations for cases where _FromType is a standard pointer.
* _ToType can be a standard or non-standard pointer.
*/
template<typename _ToType, typename _FromType>
inline _ToType
__static_pointer_cast(_FromType* __arg)
{ return _ToType(static_cast<typename _Caster<_ToType>::
type>(__arg)); }
template<typename _ToType, typename _FromType>
inline _ToType
__dynamic_pointer_cast(_FromType* __arg)
{ return _ToType(dynamic_cast<typename _Caster<_ToType>::
type>(__arg)); }
template<typename _ToType, typename _FromType>
inline _ToType
__const_pointer_cast(_FromType* __arg)
{ return _ToType(const_cast<typename _Caster<_ToType>::
type>(__arg)); }
template<typename _ToType, typename _FromType>
inline _ToType
__reinterpret_pointer_cast(_FromType* __arg)
{ return _ToType(reinterpret_cast<typename _Caster<_ToType>::
type>(__arg)); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _GLIBCXX_CAST_H
+315
View File
@@ -0,0 +1,315 @@
// Support for concurrent programing -*- C++ -*-
// Copyright (C) 2003-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/concurrence.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _CONCURRENCE_H
#define _CONCURRENCE_H 1
#pragma GCC system_header
#include <exception>
#include <bits/gthr.h>
#include <bits/functexcept.h>
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Available locking policies:
// _S_single single-threaded code that doesn't need to be locked.
// _S_mutex multi-threaded code that requires additional support
// from gthr.h or abstraction layers in concurrence.h.
// _S_atomic multi-threaded code using atomic operations.
enum _Lock_policy { _S_single, _S_mutex, _S_atomic };
// Compile time constant that indicates prefered locking policy in
// the current configuration.
_GLIBCXX17_INLINE const _Lock_policy __default_lock_policy =
#ifndef __GTHREADS
_S_single;
#elif defined _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY
_S_atomic;
#else
_S_mutex;
#endif
// NB: As this is used in libsupc++, need to only depend on
// exception. No stdexception classes, no use of std::string.
class __concurrence_lock_error : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "__gnu_cxx::__concurrence_lock_error"; }
};
class __concurrence_unlock_error : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "__gnu_cxx::__concurrence_unlock_error"; }
};
class __concurrence_broadcast_error : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "__gnu_cxx::__concurrence_broadcast_error"; }
};
class __concurrence_wait_error : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "__gnu_cxx::__concurrence_wait_error"; }
};
// Substitute for concurrence_error object in the case of -fno-exceptions.
inline void
__throw_concurrence_lock_error()
{ _GLIBCXX_THROW_OR_ABORT(__concurrence_lock_error()); }
inline void
__throw_concurrence_unlock_error()
{ _GLIBCXX_THROW_OR_ABORT(__concurrence_unlock_error()); }
#ifdef __GTHREAD_HAS_COND
inline void
__throw_concurrence_broadcast_error()
{ _GLIBCXX_THROW_OR_ABORT(__concurrence_broadcast_error()); }
inline void
__throw_concurrence_wait_error()
{ _GLIBCXX_THROW_OR_ABORT(__concurrence_wait_error()); }
#endif
class __mutex
{
private:
#if __GTHREADS && defined __GTHREAD_MUTEX_INIT
__gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT;
#else
__gthread_mutex_t _M_mutex;
#endif
__mutex(const __mutex&);
__mutex& operator=(const __mutex&);
public:
__mutex()
{
#if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
if (__gthread_active_p())
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
#endif
}
#if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
~__mutex()
{
if (__gthread_active_p())
__gthread_mutex_destroy(&_M_mutex);
}
#endif
void lock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_mutex_lock(&_M_mutex) != 0)
__throw_concurrence_lock_error();
}
#endif
}
void unlock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_mutex_unlock(&_M_mutex) != 0)
__throw_concurrence_unlock_error();
}
#endif
}
__gthread_mutex_t* gthread_mutex(void)
{ return &_M_mutex; }
};
class __recursive_mutex
{
private:
#if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT
__gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
#else
__gthread_recursive_mutex_t _M_mutex;
#endif
__recursive_mutex(const __recursive_mutex&);
__recursive_mutex& operator=(const __recursive_mutex&);
public:
__recursive_mutex()
{
#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
if (__gthread_active_p())
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
#endif
}
#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
~__recursive_mutex()
{
if (__gthread_active_p())
__gthread_recursive_mutex_destroy(&_M_mutex);
}
#endif
void lock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
__throw_concurrence_lock_error();
}
#endif
}
void unlock()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
__throw_concurrence_unlock_error();
}
#endif
}
__gthread_recursive_mutex_t* gthread_recursive_mutex(void)
{ return &_M_mutex; }
};
/// Scoped lock idiom.
// Acquire the mutex here with a constructor call, then release with
// the destructor call in accordance with RAII style.
class __scoped_lock
{
public:
typedef __mutex __mutex_type;
private:
__mutex_type& _M_device;
__scoped_lock(const __scoped_lock&);
__scoped_lock& operator=(const __scoped_lock&);
public:
explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
{ _M_device.lock(); }
~__scoped_lock() throw()
{ _M_device.unlock(); }
};
#ifdef __GTHREAD_HAS_COND
class __cond
{
private:
#if __GTHREADS && defined __GTHREAD_COND_INIT
__gthread_cond_t _M_cond = __GTHREAD_COND_INIT;
#else
__gthread_cond_t _M_cond;
#endif
__cond(const __cond&);
__cond& operator=(const __cond&);
public:
__cond()
{
#if __GTHREADS && ! defined __GTHREAD_COND_INIT
if (__gthread_active_p())
__GTHREAD_COND_INIT_FUNCTION(&_M_cond);
#endif
}
#if __GTHREADS && ! defined __GTHREAD_COND_INIT
~__cond()
{
if (__gthread_active_p())
__gthread_cond_destroy(&_M_cond);
}
#endif
void broadcast()
{
#if __GTHREADS
if (__gthread_active_p())
{
if (__gthread_cond_broadcast(&_M_cond) != 0)
__throw_concurrence_broadcast_error();
}
#endif
}
void wait(__mutex *mutex)
{
#if __GTHREADS
{
if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
__throw_concurrence_wait_error();
}
#endif
}
void wait_recursive(__recursive_mutex *mutex)
{
#if __GTHREADS
{
if (__gthread_cond_wait_recursive(&_M_cond,
mutex->gthread_recursive_mutex())
!= 0)
__throw_concurrence_wait_error();
}
#endif
}
};
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+116
View File
@@ -0,0 +1,116 @@
// HP/SGI iterator extensions -*- C++ -*-
// Copyright (C) 2001-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* 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-1998
* 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 ext/iterator
* This file is a GNU extension to the Standard C++ Library (possibly
* containing extensions from the HP/SGI STL subset).
*/
#ifndef _EXT_ITERATOR
#define _EXT_ITERATOR 1
#pragma GCC system_header
#include <bits/concept_check.h>
#include <iterator>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// There are two signatures for distance. In addition to the one
// taking two iterators and returning a result, there is another
// taking two iterators and a reference-to-result variable, and
// returning nothing. The latter seems to be an SGI extension.
// -- pedwards
template<typename _InputIterator, typename _Distance>
inline void
__distance(_InputIterator __first, _InputIterator __last,
_Distance& __n, std::input_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
while (__first != __last)
{
++__first;
++__n;
}
}
template<typename _RandomAccessIterator, typename _Distance>
inline void
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Distance& __n, std::random_access_iterator_tag)
{
// concept requirements
__glibcxx_function_requires(_RandomAccessIteratorConcept<
_RandomAccessIterator>)
__n += __last - __first;
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _InputIterator, typename _Distance>
inline void
distance(_InputIterator __first, _InputIterator __last,
_Distance& __n)
{
// concept requirements -- taken care of in __distance
__distance(__first, __last, __n, std::__iterator_category(__first));
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
@@ -0,0 +1,241 @@
// -*- C++ -*-
// Copyright (C) 2007-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/numeric_traits.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _EXT_NUMERIC_TRAITS
#define _EXT_NUMERIC_TRAITS 1
#pragma GCC system_header
#include <bits/cpp_type_traits.h>
#include <ext/type_traits.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Compile time constants for builtin types.
// In C++98 std::numeric_limits member functions are not constant expressions
// (that changed in C++11 with the addition of 'constexpr').
// Even for C++11, this header is smaller than <limits> and can be used
// when only is_signed, digits, min, or max values are needed for integers,
// or is_signed, digits10, max_digits10, or max_exponent10 for floats.
// Unlike __is_integer (and std::is_integral) this trait is true for
// non-standard built-in integer types such as __int128 and __int20.
template<typename _Tp>
struct __is_integer_nonstrict
: public std::__is_integer<_Tp>
{
using std::__is_integer<_Tp>::__value;
// The number of bits in the value representation.
enum { __width = __value ? sizeof(_Tp) * __CHAR_BIT__ : 0 };
};
template<typename _Value>
struct __numeric_traits_integer
{
#if __cplusplus >= 201103L
static_assert(__is_integer_nonstrict<_Value>::__value,
"invalid specialization");
#endif
// NB: these two are also available in std::numeric_limits as compile
// time constants, but <limits> is big and we can avoid including it.
static const bool __is_signed = (_Value)(-1) < 0;
static const int __digits
= __is_integer_nonstrict<_Value>::__width - __is_signed;
// The initializers must be constants so that __max and __min are too.
static const _Value __max = __is_signed
? (((((_Value)1 << (__digits - 1)) - 1) << 1) + 1)
: ~(_Value)0;
static const _Value __min = __is_signed ? -__max - 1 : (_Value)0;
};
template<typename _Value>
const _Value __numeric_traits_integer<_Value>::__min;
template<typename _Value>
const _Value __numeric_traits_integer<_Value>::__max;
template<typename _Value>
const bool __numeric_traits_integer<_Value>::__is_signed;
template<typename _Value>
const int __numeric_traits_integer<_Value>::__digits;
// Enable __numeric_traits_integer for types where the __is_integer_nonstrict
// primary template doesn't give the right answer.
#define _GLIBCXX_INT_N_TRAITS(T, WIDTH) \
__extension__ \
template<> struct __is_integer_nonstrict<T> \
{ \
enum { __value = 1 }; \
typedef std::__true_type __type; \
enum { __width = WIDTH }; \
}; \
__extension__ \
template<> struct __is_integer_nonstrict<unsigned T> \
{ \
enum { __value = 1 }; \
typedef std::__true_type __type; \
enum { __width = WIDTH }; \
};
// We need to specify the width for some __intNN types because they
// have padding bits, e.g. the object representation of __int20 has 32 bits,
// but its width (number of bits in the value representation) is only 20.
#if defined __GLIBCXX_TYPE_INT_N_0 && __GLIBCXX_BITSIZE_INT_N_0 % __CHAR_BIT__
_GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0)
#endif
#if defined __GLIBCXX_TYPE_INT_N_1 && __GLIBCXX_BITSIZE_INT_N_1 % __CHAR_BIT__
_GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1)
#endif
#if defined __GLIBCXX_TYPE_INT_N_2 && __GLIBCXX_BITSIZE_INT_N_2 % __CHAR_BIT__
_GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2)
#endif
#if defined __GLIBCXX_TYPE_INT_N_3 && __GLIBCXX_BITSIZE_INT_N_3 % __CHAR_BIT__
_GLIBCXX_INT_N_TRAITS(__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3)
#endif
#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
// In strict modes __is_integer<__int128> is false,
// but we still want to define __numeric_traits_integer<__int128>.
_GLIBCXX_INT_N_TRAITS(__int128, 128)
#endif
#undef _GLIBCXX_INT_N_TRAITS
#if __cplusplus >= 201103L
/// Convenience alias for __numeric_traits<integer-type>.
template<typename _Tp>
using __int_traits = __numeric_traits_integer<_Tp>;
#endif
#define __glibcxx_floating(_Tp, _Fval, _Dval, _LDval) \
(std::__are_same<_Tp, float>::__value ? _Fval \
: std::__are_same<_Tp, double>::__value ? _Dval : _LDval)
#define __glibcxx_max_digits10(_Tp) \
(2 + __glibcxx_floating(_Tp, __FLT_MANT_DIG__, __DBL_MANT_DIG__, \
__LDBL_MANT_DIG__) * 643L / 2136)
#define __glibcxx_digits10(_Tp) \
__glibcxx_floating(_Tp, __FLT_DIG__, __DBL_DIG__, __LDBL_DIG__)
#define __glibcxx_max_exponent10(_Tp) \
__glibcxx_floating(_Tp, __FLT_MAX_10_EXP__, __DBL_MAX_10_EXP__, \
__LDBL_MAX_10_EXP__)
// N.B. this only supports float, double and long double (no __float128 etc.)
template<typename _Value>
struct __numeric_traits_floating
{
// Only floating point types. See N1822.
static const int __max_digits10 = __glibcxx_max_digits10(_Value);
// See above comment...
static const bool __is_signed = true;
static const int __digits10 = __glibcxx_digits10(_Value);
static const int __max_exponent10 = __glibcxx_max_exponent10(_Value);
};
template<typename _Value>
const int __numeric_traits_floating<_Value>::__max_digits10;
template<typename _Value>
const bool __numeric_traits_floating<_Value>::__is_signed;
template<typename _Value>
const int __numeric_traits_floating<_Value>::__digits10;
template<typename _Value>
const int __numeric_traits_floating<_Value>::__max_exponent10;
#undef __glibcxx_floating
#undef __glibcxx_max_digits10
#undef __glibcxx_digits10
#undef __glibcxx_max_exponent10
template<typename _Value>
struct __numeric_traits
: public __numeric_traits_integer<_Value>
{ };
template<>
struct __numeric_traits<float>
: public __numeric_traits_floating<float>
{ };
template<>
struct __numeric_traits<double>
: public __numeric_traits_floating<double>
{ };
template<>
struct __numeric_traits<long double>
: public __numeric_traits_floating<long double>
{ };
#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
# if defined __LONG_DOUBLE_IEEE128__
// long double is __ieee128, define traits for __ibm128
template<>
struct __numeric_traits_floating<__ibm128>
{
static const int __max_digits10 = 33;
static const bool __is_signed = true;
static const int __digits10 = 31;
static const int __max_exponent10 = 308;
};
template<>
struct __numeric_traits<__ibm128>
: public __numeric_traits_floating<__ibm128>
{ };
# elif defined __LONG_DOUBLE_IBM128__
// long double is __ibm128, define traits for __ieee128
template<>
struct __numeric_traits_floating<__ieee128>
{
static const int __max_digits10 = 36;
static const bool __is_signed = true;
static const int __digits10 = 33;
static const int __max_exponent10 = 4932;
};
template<>
struct __numeric_traits<__ieee128>
: public __numeric_traits_floating<__ieee128>
{ };
# endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+611
View File
@@ -0,0 +1,611 @@
// Custom pointer adapter and sample storage policies
// Copyright (C) 2008-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file ext/pointer.h
* This file is a GNU extension to the Standard C++ Library.
*
* @author Bob Walters
*
* Provides reusable _Pointer_adapter for assisting in the development of
* custom pointer types that can be used with the standard containers via
* the allocator::pointer and allocator::const_pointer typedefs.
*/
#ifndef _POINTER_H
#define _POINTER_H 1
#pragma GCC system_header
#if _GLIBCXX_HOSTED
# include <iosfwd>
#endif
#include <bits/stl_iterator_base_types.h>
#include <ext/cast.h>
#include <ext/type_traits.h>
#if __cplusplus >= 201103L
# include <bits/move.h>
# include <bits/ptr_traits.h>
#endif
#if __cplusplus > 201703L
# include <iterator> // for indirectly_readable_traits
#endif
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief A storage policy for use with _Pointer_adapter<> which yields a
* standard pointer.
*
* A _Storage_policy is required to provide 4 things:
* 1) A get() API for returning the stored pointer value.
* 2) An set() API for storing a pointer value.
* 3) An element_type typedef to define the type this points to.
* 4) An operator<() to support pointer comparison.
* 5) An operator==() to support pointer comparison.
*/
template<typename _Tp>
class _Std_pointer_impl
{
public:
// the type this pointer points to.
typedef _Tp element_type;
// A method to fetch the pointer value as a standard T* value;
inline _Tp*
get() const
{ return _M_value; }
// A method to set the pointer value, from a standard T* value;
inline void
set(element_type* __arg)
{ _M_value = __arg; }
// Comparison of pointers
inline bool
operator<(const _Std_pointer_impl& __rarg) const
{ return (_M_value < __rarg._M_value); }
inline bool
operator==(const _Std_pointer_impl& __rarg) const
{ return (_M_value == __rarg._M_value); }
private:
element_type* _M_value;
};
/**
* @brief A storage policy for use with _Pointer_adapter<> which stores
* the pointer's address as an offset value which is relative to
* its own address.
*
* This is intended for pointers within shared memory regions which
* might be mapped at different addresses by different processes.
* For null pointers, a value of 1 is used. (0 is legitimate
* sometimes for nodes in circularly linked lists) This value was
* chosen as the least likely to generate an incorrect null, As
* there is no reason why any normal pointer would point 1 byte into
* its own pointer address.
*/
template<typename _Tp>
class _Relative_pointer_impl
{
public:
typedef _Tp element_type;
_Tp*
get() const
{
if (_M_diff == 1)
return 0;
else
return reinterpret_cast<_Tp*>(reinterpret_cast<uintptr_t>(this)
+ _M_diff);
}
void
set(_Tp* __arg)
{
if (!__arg)
_M_diff = 1;
else
_M_diff = reinterpret_cast<uintptr_t>(__arg)
- reinterpret_cast<uintptr_t>(this);
}
// Comparison of pointers
inline bool
operator<(const _Relative_pointer_impl& __rarg) const
{ return (reinterpret_cast<uintptr_t>(this->get())
< reinterpret_cast<uintptr_t>(__rarg.get())); }
inline bool
operator==(const _Relative_pointer_impl& __rarg) const
{ return (reinterpret_cast<uintptr_t>(this->get())
== reinterpret_cast<uintptr_t>(__rarg.get())); }
private:
typedef __UINTPTR_TYPE__ uintptr_t;
uintptr_t _M_diff;
};
/**
* Relative_pointer_impl needs a specialization for const T because of
* the casting done during pointer arithmetic.
*/
template<typename _Tp>
class _Relative_pointer_impl<const _Tp>
{
public:
typedef const _Tp element_type;
const _Tp*
get() const
{
if (_M_diff == 1)
return 0;
else
return reinterpret_cast<const _Tp*>
(reinterpret_cast<uintptr_t>(this) + _M_diff);
}
void
set(const _Tp* __arg)
{
if (!__arg)
_M_diff = 1;
else
_M_diff = reinterpret_cast<uintptr_t>(__arg)
- reinterpret_cast<uintptr_t>(this);
}
// Comparison of pointers
inline bool
operator<(const _Relative_pointer_impl& __rarg) const
{ return (reinterpret_cast<uintptr_t>(this->get())
< reinterpret_cast<uintptr_t>(__rarg.get())); }
inline bool
operator==(const _Relative_pointer_impl& __rarg) const
{ return (reinterpret_cast<uintptr_t>(this->get())
== reinterpret_cast<uintptr_t>(__rarg.get())); }
private:
typedef __UINTPTR_TYPE__ uintptr_t;
uintptr_t _M_diff;
};
/**
* The specialization on this type helps resolve the problem of
* reference to void, and eliminates the need to specialize
* _Pointer_adapter for cases of void*, const void*, and so on.
*/
struct _Invalid_type { };
template<typename _Tp>
struct _Reference_type
{ typedef _Tp& reference; };
template<>
struct _Reference_type<void>
{ typedef _Invalid_type& reference; };
template<>
struct _Reference_type<const void>
{ typedef const _Invalid_type& reference; };
template<>
struct _Reference_type<volatile void>
{ typedef volatile _Invalid_type& reference; };
template<>
struct _Reference_type<volatile const void>
{ typedef const volatile _Invalid_type& reference; };
/**
* This structure accommodates the way in which
* std::iterator_traits<> is normally specialized for const T*, so
* that value_type is still T.
*/
template<typename _Tp>
struct _Unqualified_type
{ typedef _Tp type; };
template<typename _Tp>
struct _Unqualified_type<const _Tp>
{ typedef _Tp type; };
/**
* The following provides an 'alternative pointer' that works with
* the containers when specified as the pointer typedef of the
* allocator.
*
* The pointer type used with the containers doesn't have to be this
* class, but it must support the implicit conversions, pointer
* arithmetic, comparison operators, etc. that are supported by this
* class, and avoid raising compile-time ambiguities. Because
* creating a working pointer can be challenging, this pointer
* template was designed to wrapper an easier storage policy type,
* so that it becomes reusable for creating other pointer types.
*
* A key point of this class is also that it allows container
* writers to 'assume' Allocator::pointer is a typedef for a normal
* pointer. This class supports most of the conventions of a true
* pointer, and can, for instance handle implicit conversion to
* const and base class pointer types. The only impositions on
* container writers to support extended pointers are: 1) use the
* Allocator::pointer typedef appropriately for pointer types. 2)
* if you need pointer casting, use the __pointer_cast<> functions
* from ext/cast.h. This allows pointer cast operations to be
* overloaded as necessary by custom pointers.
*
* Note: The const qualifier works with this pointer adapter as
* follows:
*
* _Tp* == _Pointer_adapter<_Std_pointer_impl<_Tp> >;
* const _Tp* == _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
* _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >;
* const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >;
*/
template<typename _Storage_policy>
class _Pointer_adapter : public _Storage_policy
{
public:
typedef typename _Storage_policy::element_type element_type;
// These are needed for iterator_traits
typedef std::random_access_iterator_tag iterator_category;
typedef typename _Unqualified_type<element_type>::type value_type;
typedef std::ptrdiff_t difference_type;
typedef _Pointer_adapter pointer;
typedef typename _Reference_type<element_type>::reference reference;
// Reminder: 'const' methods mean that the method is valid when the
// pointer is immutable, and has nothing to do with whether the
// 'pointee' is const.
// Default Constructor (Convert from element_type*)
_Pointer_adapter(element_type* __arg = 0)
{ _Storage_policy::set(__arg); }
// Copy constructor from _Pointer_adapter of same type.
_Pointer_adapter(const _Pointer_adapter& __arg)
{ _Storage_policy::set(__arg.get()); }
// Convert from _Up* if conversion to element_type* is valid.
template<typename _Up>
_Pointer_adapter(_Up* __arg)
{ _Storage_policy::set(__arg); }
// Conversion from another _Pointer_adapter if _Up if static cast is
// valid.
template<typename _Up>
_Pointer_adapter(const _Pointer_adapter<_Up>& __arg)
{ _Storage_policy::set(__arg.get()); }
// Destructor
~_Pointer_adapter() { }
// Assignment operator
_Pointer_adapter&
operator=(const _Pointer_adapter& __arg)
{
_Storage_policy::set(__arg.get());
return *this;
}
template<typename _Up>
_Pointer_adapter&
operator=(const _Pointer_adapter<_Up>& __arg)
{
_Storage_policy::set(__arg.get());
return *this;
}
template<typename _Up>
_Pointer_adapter&
operator=(_Up* __arg)
{
_Storage_policy::set(__arg);
return *this;
}
// Operator*, returns element_type&
inline reference
operator*() const
{ return *(_Storage_policy::get()); }
// Operator->, returns element_type*
inline element_type*
operator->() const
{ return _Storage_policy::get(); }
// Operator[], returns a element_type& to the item at that loc.
inline reference
operator[](std::ptrdiff_t __index) const
{ return _Storage_policy::get()[__index]; }
// To allow implicit conversion to "bool", for "if (ptr)..."
#if __cplusplus >= 201103L
explicit operator bool() const { return _Storage_policy::get() != 0; }
#else
private:
typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const;
public:
operator __unspecified_bool_type() const
{
return _Storage_policy::get() == 0 ? 0 :
&_Pointer_adapter::operator->;
}
// ! operator (for: if (!ptr)...)
inline bool
operator!() const
{ return (_Storage_policy::get() == 0); }
#endif
// Pointer differences
inline friend std::ptrdiff_t
operator-(const _Pointer_adapter& __lhs, element_type* __rhs)
{ return (__lhs.get() - __rhs); }
inline friend std::ptrdiff_t
operator-(element_type* __lhs, const _Pointer_adapter& __rhs)
{ return (__lhs - __rhs.get()); }
template<typename _Up>
inline friend std::ptrdiff_t
operator-(const _Pointer_adapter& __lhs, _Up* __rhs)
{ return (__lhs.get() - __rhs); }
template<typename _Up>
inline friend std::ptrdiff_t
operator-(_Up* __lhs, const _Pointer_adapter& __rhs)
{ return (__lhs - __rhs.get()); }
template<typename _Up>
inline std::ptrdiff_t
operator-(const _Pointer_adapter<_Up>& __rhs) const
{ return (_Storage_policy::get() - __rhs.get()); }
// Pointer math
// Note: There is a reason for all this overloading based on different
// integer types. In some libstdc++-v3 test cases, a templated
// operator+ is declared which can match any types. This operator
// tends to "steal" the recognition of _Pointer_adapter's own operator+
// unless the integer type matches perfectly.
#define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \
inline friend _Pointer_adapter \
operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
{ return _Pointer_adapter(__lhs.get() + __offset); } \
\
inline friend _Pointer_adapter \
operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \
{ return _Pointer_adapter(__rhs.get() + __offset); } \
\
inline friend _Pointer_adapter \
operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \
{ return _Pointer_adapter(__lhs.get() - __offset); } \
\
inline _Pointer_adapter& \
operator+=(INT_TYPE __offset) \
{ \
_Storage_policy::set(_Storage_policy::get() + __offset); \
return *this; \
} \
\
inline _Pointer_adapter& \
operator-=(INT_TYPE __offset) \
{ \
_Storage_policy::set(_Storage_policy::get() - __offset); \
return *this; \
} \
// END of _CXX_POINTER_ARITH_OPERATOR_SET macro
// Expand into the various pointer arithmetic operators needed.
_CXX_POINTER_ARITH_OPERATOR_SET(short);
_CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
_CXX_POINTER_ARITH_OPERATOR_SET(int);
_CXX_POINTER_ARITH_OPERATOR_SET(unsigned int);
_CXX_POINTER_ARITH_OPERATOR_SET(long);
_CXX_POINTER_ARITH_OPERATOR_SET(unsigned long);
#ifdef _GLIBCXX_USE_LONG_LONG
_CXX_POINTER_ARITH_OPERATOR_SET(long long);
_CXX_POINTER_ARITH_OPERATOR_SET(unsigned long long);
#endif
// Mathematical Manipulators
inline _Pointer_adapter&
operator++()
{
_Storage_policy::set(_Storage_policy::get() + 1);
return *this;
}
inline _Pointer_adapter
operator++(int)
{
_Pointer_adapter __tmp(*this);
_Storage_policy::set(_Storage_policy::get() + 1);
return __tmp;
}
inline _Pointer_adapter&
operator--()
{
_Storage_policy::set(_Storage_policy::get() - 1);
return *this;
}
inline _Pointer_adapter
operator--(int)
{
_Pointer_adapter __tmp(*this);
_Storage_policy::set(_Storage_policy::get() - 1);
return __tmp;
}
#if __cpp_lib_three_way_comparison
friend std::strong_ordering
operator<=>(const _Pointer_adapter& __lhs, const _Pointer_adapter& __rhs)
noexcept
{ return __lhs.get() <=> __rhs.get(); }
#endif
}; // class _Pointer_adapter
#define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \
template<typename _Tp1, typename _Tp2> \
inline bool \
operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \
{ return __lhs.get() OPERATOR __rhs; } \
\
template<typename _Tp1, typename _Tp2> \
inline bool \
operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \
{ return __lhs OPERATOR __rhs.get(); } \
\
template<typename _Tp1, typename _Tp2> \
inline bool \
operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \
const _Pointer_adapter<_Tp2>& __rhs) \
{ return __lhs.get() OPERATOR __rhs.get(); } \
\
// End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro
// Expand into the various comparison operators needed.
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==)
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=)
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<)
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=)
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>)
_GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=)
// These are here for expressions like "ptr == 0", "ptr != 0"
template<typename _Tp>
inline bool
operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
{ return __lhs.get() == reinterpret_cast<void*>(__rhs); }
template<typename _Tp>
inline bool
operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
{ return __rhs.get() == reinterpret_cast<void*>(__lhs); }
template<typename _Tp>
inline bool
operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs)
{ return __lhs.get() != reinterpret_cast<void*>(__rhs); }
template<typename _Tp>
inline bool
operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs)
{ return __rhs.get() != reinterpret_cast<void*>(__lhs); }
/**
* Comparison operators for _Pointer_adapter defer to the base class'
* comparison operators, when possible.
*/
template<typename _Tp>
inline bool
operator==(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return __lhs._Tp::operator==(__rhs); }
template<typename _Tp>
inline bool
operator<=(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); }
template<typename _Tp>
inline bool
operator!=(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return !(__lhs._Tp::operator==(__rhs)); }
template<typename _Tp>
inline bool
operator>(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); }
template<typename _Tp>
inline bool
operator>=(const _Pointer_adapter<_Tp>& __lhs,
const _Pointer_adapter<_Tp>& __rhs)
{ return !(__lhs._Tp::operator<(__rhs)); }
#if _GLIBCXX_HOSTED
template<typename _CharT, typename _Traits, typename _StoreT>
inline std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const _Pointer_adapter<_StoreT>& __p)
{ return (__os << __p.get()); }
#endif // HOSTED
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if __cplusplus >= 201103L
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Storage_policy>
struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>>
{
/// The pointer type
typedef __gnu_cxx::_Pointer_adapter<_Storage_policy> pointer;
/// The type pointed to
typedef typename pointer::element_type element_type;
/// Type used to represent the difference between two pointers
typedef typename pointer::difference_type difference_type;
template<typename _Up>
using rebind = typename __gnu_cxx::_Pointer_adapter<
typename pointer_traits<_Storage_policy>::template rebind<_Up>>;
static pointer pointer_to(typename pointer::reference __r) noexcept
{ return pointer(std::addressof(__r)); }
};
#if __cpp_lib_concepts
template<typename _Policy>
struct indirectly_readable_traits<__gnu_cxx::_Pointer_adapter<_Policy>>
{
using value_type
= typename __gnu_cxx::_Pointer_adapter<_Policy>::value_type;
};
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
#endif // _POINTER_H
+273
View File
@@ -0,0 +1,273 @@
// -*- C++ -*-
// Copyright (C) 2005-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/type_traits.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _EXT_TYPE_TRAITS
#define _EXT_TYPE_TRAITS 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/cpp_type_traits.h>
extern "C++" {
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Define a nested type if some predicate holds.
template<bool, typename>
struct __enable_if
{ };
template<typename _Tp>
struct __enable_if<true, _Tp>
{ typedef _Tp __type; };
// Conditional expression for types. If true, first, if false, second.
template<bool _Cond, typename _Iftrue, typename _Iffalse>
struct __conditional_type
{ typedef _Iftrue __type; };
template<typename _Iftrue, typename _Iffalse>
struct __conditional_type<false, _Iftrue, _Iffalse>
{ typedef _Iffalse __type; };
// Given an integral builtin type, return the corresponding unsigned type.
template<typename _Tp>
struct __add_unsigned
{
private:
typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
public:
typedef typename __if_type::__type __type;
};
template<>
struct __add_unsigned<char>
{ typedef unsigned char __type; };
template<>
struct __add_unsigned<signed char>
{ typedef unsigned char __type; };
template<>
struct __add_unsigned<short>
{ typedef unsigned short __type; };
template<>
struct __add_unsigned<int>
{ typedef unsigned int __type; };
template<>
struct __add_unsigned<long>
{ typedef unsigned long __type; };
template<>
struct __add_unsigned<long long>
{ typedef unsigned long long __type; };
// Declare but don't define.
template<>
struct __add_unsigned<bool>;
template<>
struct __add_unsigned<wchar_t>;
// Given an integral builtin type, return the corresponding signed type.
template<typename _Tp>
struct __remove_unsigned
{
private:
typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
public:
typedef typename __if_type::__type __type;
};
template<>
struct __remove_unsigned<char>
{ typedef signed char __type; };
template<>
struct __remove_unsigned<unsigned char>
{ typedef signed char __type; };
template<>
struct __remove_unsigned<unsigned short>
{ typedef short __type; };
template<>
struct __remove_unsigned<unsigned int>
{ typedef int __type; };
template<>
struct __remove_unsigned<unsigned long>
{ typedef long __type; };
template<>
struct __remove_unsigned<unsigned long long>
{ typedef long long __type; };
// Declare but don't define.
template<>
struct __remove_unsigned<bool>;
template<>
struct __remove_unsigned<wchar_t>;
// For use in string and vstring.
template<typename _Type>
_GLIBCXX_CONSTEXPR
inline bool
__is_null_pointer(_Type* __ptr)
{ return __ptr == 0; }
template<typename _Type>
_GLIBCXX_CONSTEXPR
inline bool
__is_null_pointer(_Type)
{ return false; }
#if __cplusplus >= 201103L
constexpr bool
__is_null_pointer(std::nullptr_t)
{ return true; }
#endif
// For arithmetic promotions in <complex> and <cmath>
template<typename _Tp, bool = std::__is_integer<_Tp>::__value>
struct __promote
{ typedef double __type; };
// No nested __type member for non-integer non-floating point types,
// allows this type to be used for SFINAE to constrain overloads in
// <cmath> and <complex> to only the intended types.
template<typename _Tp>
struct __promote<_Tp, false>
{ };
template<>
struct __promote<long double>
{ typedef long double __type; };
template<>
struct __promote<double>
{ typedef double __type; };
template<>
struct __promote<float>
{ typedef float __type; };
#ifdef __STDCPP_FLOAT16_T__
template<>
struct __promote<_Float16>
{ typedef _Float16 __type; };
#endif
#ifdef __STDCPP_FLOAT32_T__
template<>
struct __promote<_Float32>
{ typedef _Float32 __type; };
#endif
#ifdef __STDCPP_FLOAT64_T__
template<>
struct __promote<_Float64>
{ typedef _Float64 __type; };
#endif
#ifdef __STDCPP_FLOAT128_T__
template<>
struct __promote<_Float128>
{ typedef _Float128 __type; };
#endif
#ifdef __STDCPP_BFLOAT16_T__
template<>
struct __promote<__gnu_cxx::__bfloat16_t>
{ typedef __gnu_cxx::__bfloat16_t __type; };
#endif
#if __cpp_fold_expressions
template<typename... _Tp>
using __promoted_t = decltype((typename __promote<_Tp>::__type(0) + ...));
// Deducing the promoted type is done by __promoted_t<_Tp...>,
// then __promote is used to provide the nested __type member.
template<typename _Tp, typename _Up>
using __promote_2 = __promote<__promoted_t<_Tp, _Up>>;
template<typename _Tp, typename _Up, typename _Vp>
using __promote_3 = __promote<__promoted_t<_Tp, _Up, _Vp>>;
template<typename _Tp, typename _Up, typename _Vp, typename _Wp>
using __promote_4 = __promote<__promoted_t<_Tp, _Up, _Vp, _Wp>>;
#else
template<typename _Tp, typename _Up,
typename _Tp2 = typename __promote<_Tp>::__type,
typename _Up2 = typename __promote<_Up>::__type>
struct __promote_2
{
typedef __typeof__(_Tp2() + _Up2()) __type;
};
template<typename _Tp, typename _Up, typename _Vp,
typename _Tp2 = typename __promote<_Tp>::__type,
typename _Up2 = typename __promote<_Up>::__type,
typename _Vp2 = typename __promote<_Vp>::__type>
struct __promote_3
{
typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type;
};
template<typename _Tp, typename _Up, typename _Vp, typename _Wp,
typename _Tp2 = typename __promote<_Tp>::__type,
typename _Up2 = typename __promote<_Up>::__type,
typename _Vp2 = typename __promote<_Vp>::__type,
typename _Wp2 = typename __promote<_Wp>::__type>
struct __promote_4
{
typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type;
};
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
} // extern "C++"
#endif
+538
View File
@@ -0,0 +1,538 @@
// -*- C++ -*-
// Copyright (C) 2005-2024 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 3, 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice and
// this permission notice appear in supporting documentation. None of
// the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied warranty.
/**
* @file ext/typelist.h
* This file is a GNU extension to the Standard C++ Library.
*
* Contains typelist_chain definitions.
* Typelists are an idea by Andrei Alexandrescu.
*/
#ifndef _TYPELIST_H
#define _TYPELIST_H 1
#include <ext/type_traits.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @namespace __gnu_cxx::typelist
* @brief GNU typelist extensions for public compile-time use.
*/
namespace typelist
{
struct null_type { };
template<typename Root>
struct node
{
typedef Root root;
};
// Forward declarations of functors.
template<typename Hd, typename Typelist>
struct chain
{
typedef Hd head;
typedef Typelist tail;
};
// Apply all typelist types to unary functor.
template<typename Fn, typename Typelist>
void
apply(Fn&, Typelist);
/// Apply all typelist types to generator functor.
template<typename Gn, typename Typelist>
void
apply_generator(Gn&, Typelist);
// Apply all typelist types and values to generator functor.
template<typename Gn, typename TypelistT, typename TypelistV>
void
apply_generator(Gn&, TypelistT, TypelistV);
template<typename Typelist0, typename Typelist1>
struct append;
template<typename Typelist_Typelist>
struct append_typelist;
template<typename Typelist, typename T>
struct contains;
template<typename Typelist, template<typename T> class Pred>
struct filter;
template<typename Typelist, int i>
struct at_index;
template<typename Typelist, template<typename T> class Transform>
struct transform;
template<typename Typelist_Typelist>
struct flatten;
template<typename Typelist>
struct from_first;
template<typename T1>
struct create1;
template<typename T1, typename T2>
struct create2;
template<typename T1, typename T2, typename T3>
struct create3;
template<typename T1, typename T2, typename T3, typename T4>
struct create4;
template<typename T1, typename T2, typename T3, typename T4, typename T5>
struct create5;
template<typename T1, typename T2, typename T3,
typename T4, typename T5, typename T6>
struct create6;
namespace detail
{
template<typename Fn, typename Typelist_Chain>
struct apply_;
template<typename Fn, typename Hd, typename Tl>
struct apply_<Fn, chain<Hd, Tl> >
{
void
operator()(Fn& f)
{
f.operator()(Hd());
apply_<Fn, Tl> next;
next(f);
}
};
template<typename Fn>
struct apply_<Fn, null_type>
{
void
operator()(Fn&) { }
};
template<typename Gn, typename Typelist_Chain>
struct apply_generator1_;
template<typename Gn, typename Hd, typename Tl>
struct apply_generator1_<Gn, chain<Hd, Tl> >
{
void
operator()(Gn& g)
{
g.template operator()<Hd>();
apply_generator1_<Gn, Tl> next;
next(g);
}
};
template<typename Gn>
struct apply_generator1_<Gn, null_type>
{
void
operator()(Gn&) { }
};
template<typename Gn, typename TypelistT_Chain, typename TypelistV_Chain>
struct apply_generator2_;
template<typename Gn, typename Hd1, typename TlT, typename Hd2, typename TlV>
struct apply_generator2_<Gn, chain<Hd1, TlT>, chain<Hd2, TlV> >
{
void
operator()(Gn& g)
{
g.template operator()<Hd1, Hd2>();
apply_generator2_<Gn, TlT, TlV> next;
next(g);
}
};
template<typename Gn>
struct apply_generator2_<Gn, null_type, null_type>
{
void
operator()(Gn&) { }
};
template<typename Typelist_Chain0, typename Typelist_Chain1>
struct append_;
template<typename Hd, typename Tl, typename Typelist_Chain>
struct append_<chain<Hd, Tl>, Typelist_Chain>
{
private:
typedef append_<Tl, Typelist_Chain> append_type;
public:
typedef chain<Hd, typename append_type::type> type;
};
template<typename Typelist_Chain>
struct append_<null_type, Typelist_Chain>
{
typedef Typelist_Chain type;
};
template<typename Hd, typename Tl>
struct append_<chain<Hd, Tl>, null_type>
{
typedef chain<Hd, Tl> type;
};
template<>
struct append_<null_type, null_type>
{
typedef null_type type;
};
template<typename Typelist_Typelist_Chain>
struct append_typelist_;
template<typename Hd>
struct append_typelist_<chain<Hd, null_type> >
{
typedef chain<Hd, null_type> type;
};
template<typename Hd, typename Tl>
struct append_typelist_<chain< Hd, Tl> >
{
private:
typedef typename append_typelist_<Tl>::type rest_type;
public:
typedef typename append<Hd, node<rest_type> >::type::root type;
};
template<typename Typelist_Chain, typename T>
struct contains_;
template<typename T>
struct contains_<null_type, T>
{
enum
{
value = false
};
};
template<typename Hd, typename Tl, typename T>
struct contains_<chain<Hd, Tl>, T>
{
enum
{
value = contains_<Tl, T>::value
};
};
template<typename Tl, typename T>
struct contains_<chain<T, Tl>, T>
{
enum
{
value = true
};
};
template<typename Typelist_Chain, template<typename T> class Pred>
struct chain_filter_;
template<template<typename T> class Pred>
struct chain_filter_<null_type, Pred>
{
typedef null_type type;
};
template<typename Hd, typename Tl, template<typename T> class Pred>
struct chain_filter_<chain<Hd, Tl>, Pred>
{
private:
enum
{
include_hd = Pred<Hd>::value
};
typedef typename chain_filter_<Tl, Pred>::type rest_type;
typedef chain<Hd, rest_type> chain_type;
public:
typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type;
};
template<typename Typelist_Chain, int i>
struct chain_at_index_;
template<typename Hd, typename Tl>
struct chain_at_index_<chain<Hd, Tl>, 0>
{
typedef Hd type;
};
template<typename Hd, typename Tl, int i>
struct chain_at_index_<chain<Hd, Tl>, i>
{
typedef typename chain_at_index_<Tl, i - 1>::type type;
};
template<class Typelist_Chain, template<typename T> class Transform>
struct chain_transform_;
template<template<typename T> class Transform>
struct chain_transform_<null_type, Transform>
{
typedef null_type type;
};
template<class Hd, class Tl, template<typename T> class Transform>
struct chain_transform_<chain<Hd, Tl>, Transform>
{
private:
typedef typename chain_transform_<Tl, Transform>::type rest_type;
typedef typename Transform<Hd>::type transform_type;
public:
typedef chain<transform_type, rest_type> type;
};
template<typename Typelist_Typelist_Chain>
struct chain_flatten_;
template<typename Hd_Tl>
struct chain_flatten_<chain<Hd_Tl, null_type> >
{
typedef typename Hd_Tl::root type;
};
template<typename Hd_Typelist, class Tl_Typelist>
struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> >
{
private:
typedef typename chain_flatten_<Tl_Typelist>::type rest_type;
typedef append<Hd_Typelist, node<rest_type> > append_type;
public:
typedef typename append_type::type::root type;
};
} // namespace detail
#define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type>
#define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) >
#define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) >
#define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) >
#define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) >
#define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) >
#define _GLIBCXX_TYPELIST_CHAIN7(X0, X1, X2, X3, X4, X5, X6) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN6(X1, X2, X3, X4, X5, X6) >
#define _GLIBCXX_TYPELIST_CHAIN8(X0, X1, X2, X3, X4, X5, X6, X7) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN7(X1, X2, X3, X4, X5, X6, X7) >
#define _GLIBCXX_TYPELIST_CHAIN9(X0, X1, X2, X3, X4, X5, X6, X7, X8) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN8(X1, X2, X3, X4, X5, X6, X7, X8) >
#define _GLIBCXX_TYPELIST_CHAIN10(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN9(X1, X2, X3, X4, X5, X6, X7, X8, X9) >
#define _GLIBCXX_TYPELIST_CHAIN11(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN10(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) >
#define _GLIBCXX_TYPELIST_CHAIN12(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN11(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) >
#define _GLIBCXX_TYPELIST_CHAIN13(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN12(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) >
#define _GLIBCXX_TYPELIST_CHAIN14(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN13(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) >
#define _GLIBCXX_TYPELIST_CHAIN15(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN14(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) >
#define _GLIBCXX_TYPELIST_CHAIN16(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN15(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) >
#define _GLIBCXX_TYPELIST_CHAIN17(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN16(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) >
#define _GLIBCXX_TYPELIST_CHAIN18(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN17(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) >
#define _GLIBCXX_TYPELIST_CHAIN19(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN18(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) >
#define _GLIBCXX_TYPELIST_CHAIN20(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN19(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) >
template<typename Fn, typename Typelist>
void
apply(Fn& fn, Typelist)
{
detail::apply_<Fn, typename Typelist::root> a;
a(fn);
}
template<typename Fn, typename Typelist>
void
apply_generator(Fn& fn, Typelist)
{
detail::apply_generator1_<Fn, typename Typelist::root> a;
a(fn);
}
template<typename Fn, typename TypelistT, typename TypelistV>
void
apply_generator(Fn& fn, TypelistT, TypelistV)
{
typedef typename TypelistT::root rootT;
typedef typename TypelistV::root rootV;
detail::apply_generator2_<Fn, rootT, rootV> a;
a(fn);
}
template<typename Typelist0, typename Typelist1>
struct append
{
private:
typedef typename Typelist0::root root0_type;
typedef typename Typelist1::root root1_type;
typedef detail::append_<root0_type, root1_type> append_type;
public:
typedef node<typename append_type::type> type;
};
template<typename Typelist_Typelist>
struct append_typelist
{
private:
typedef typename Typelist_Typelist::root root_type;
typedef detail::append_typelist_<root_type> append_type;
public:
typedef node<typename append_type::type> type;
};
template<typename Typelist, typename T>
struct contains
{
private:
typedef typename Typelist::root root_type;
public:
enum
{
value = detail::contains_<root_type, T>::value
};
};
template<typename Typelist, template<typename T> class Pred>
struct filter
{
private:
typedef typename Typelist::root root_type;
typedef detail::chain_filter_<root_type, Pred> filter_type;
public:
typedef node<typename filter_type::type> type;
};
template<typename Typelist, int i>
struct at_index
{
private:
typedef typename Typelist::root root_type;
typedef detail::chain_at_index_<root_type, i> index_type;
public:
typedef typename index_type::type type;
};
template<typename Typelist, template<typename T> class Transform>
struct transform
{
private:
typedef typename Typelist::root root_type;
typedef detail::chain_transform_<root_type, Transform> transform_type;
public:
typedef node<typename transform_type::type> type;
};
template<typename Typelist_Typelist>
struct flatten
{
private:
typedef typename Typelist_Typelist::root root_type;
typedef typename detail::chain_flatten_<root_type>::type flatten_type;
public:
typedef node<flatten_type> type;
};
template<typename Typelist>
struct from_first
{
private:
typedef typename at_index<Typelist, 0>::type first_type;
public:
typedef node<chain<first_type, null_type> > type;
};
template<typename T1>
struct create1
{
typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)> type;
};
template<typename T1, typename T2>
struct create2
{
typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)> type;
};
template<typename T1, typename T2, typename T3>
struct create3
{
typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)> type;
};
template<typename T1, typename T2, typename T3, typename T4>
struct create4
{
typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)> type;
};
template<typename T1, typename T2, typename T3,
typename T4, typename T5>
struct create5
{
typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)> type;
};
template<typename T1, typename T2, typename T3,
typename T4, typename T5, typename T6>
struct create6
{
typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type;
};
} // namespace typelist
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif