feat: multi-user system, bug fixes, security & performance fixes, and more
This commit is contained in:
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user