diff --git a/loader/include/Geode/c++stl/gnustl.hpp b/loader/include/Geode/c++stl/gnustl.hpp index 67c38309..5a2f4ae7 100644 --- a/loader/include/Geode/c++stl/gnustl.hpp +++ b/loader/include/Geode/c++stl/gnustl.hpp @@ -15,6 +15,12 @@ namespace geode::base { #if defined(GEODE_IS_ANDROID) #include "gnustl-map.hpp" + #include "gnustl/unordered_map.hpp" + #include "gnustl/unordered_set.hpp" + #include "gnustl/hash_specialization.hpp" + #undef _GLIBCXX_RELEASE + #undef __GLIBCXX__ + #undef _GLIBCXX_USE_DUAL_ABI namespace gd { using namespace geode::stl; @@ -686,11 +692,11 @@ namespace gd { template using set = void*[6]; - template - using unordered_map = void*[7]; + template , class Pred = geode::stl::equal_to, class Alloc = std::allocator>> + using unordered_map = geode::stl::unordered_map; - template - using unordered_set = void*[7]; + template , class Pred = geode::stl::equal_to, class Alloc = std::allocator> + using unordered_set = geode::stl::unordered_set; }; #elif defined(GEODE_IS_IOS) diff --git a/loader/include/Geode/c++stl/gnustl/alloc_traits.h b/loader/include/Geode/c++stl/gnustl/alloc_traits.h new file mode 100644 index 00000000..6681d6b9 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/alloc_traits.h @@ -0,0 +1,531 @@ +// Allocator traits -*- C++ -*- + +// Copyright (C) 2011-2014 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 +// . + +/** @file bits/alloc_traits.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#pragma once + +#if __cplusplus >= 201103L + +#include "memoryfwd.h" +#include "ptr_traits.h" +#include "type_traits.h" +#include "ext/numeric_traits.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + class __alloctr_rebind_helper + { + template + static constexpr std::true_type + _S_chk(typename _Alloc2::template rebind<_Tp2>::other*); + + template + static constexpr std::false_type + _S_chk(...); + + public: + using __type = decltype(_S_chk<_Alloc, _Tp>(nullptr)); + }; + + template::__type::value> + struct __alloctr_rebind; + + template + struct __alloctr_rebind<_Alloc, _Tp, true> + { + typedef typename _Alloc::template rebind<_Tp>::other __type; + }; + + template class _Alloc, typename _Tp, + typename _Up, typename... _Args> + struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false> + { + typedef _Alloc<_Tp, _Args...> __type; + }; + + /** + * @brief Uniform interface to all allocator types. + * @ingroup allocators + */ + template + struct allocator_traits + { + /// The allocator type + typedef _Alloc allocator_type; + /// The allocated type + typedef typename _Alloc::value_type value_type; + +#define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \ + private: \ + template \ + static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \ + static _ALT _S_##_NTYPE##_helper(...); \ + typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \ + public: + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*) + + /** + * @brief The allocator's pointer type. + * + * @c Alloc::pointer if that type exists, otherwise @c value_type* + */ + typedef __pointer pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer, + typename pointer_traits::template rebind) + + /** + * @brief The allocator's const pointer type. + * + * @c Alloc::const_pointer if that type exists, otherwise + * pointer_traits::rebind + */ + typedef __const_pointer const_pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer, + typename pointer_traits::template rebind) + + /** + * @brief The allocator's void pointer type. + * + * @c Alloc::void_pointer if that type exists, otherwise + * pointer_traits::rebind + */ + typedef __void_pointer void_pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer, + typename pointer_traits::template rebind) + + /** + * @brief The allocator's const void pointer type. + * + * @c Alloc::const_void_pointer if that type exists, otherwise + * pointer_traits::rebind + */ + typedef __const_void_pointer const_void_pointer; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type, + typename pointer_traits::difference_type) + + /** + * @brief The allocator's difference type + * + * @c Alloc::difference_type if that type exists, otherwise + * pointer_traits::difference_type + */ + typedef __difference_type difference_type; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type, + typename std::make_unsigned::type) + + /** + * @brief The allocator's size type + * + * @c Alloc::size_type if that type exists, otherwise + * make_unsigned::type + */ + typedef __size_type size_type; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment, + std::false_type) + + /** + * @brief How the allocator is propagated on copy assignment + * + * @c Alloc::propagate_on_container_copy_assignment if that type exists, + * otherwise @c false_type + */ + typedef __propagate_on_container_copy_assignment + propagate_on_container_copy_assignment; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment, + std::false_type) + + /** + * @brief How the allocator is propagated on move assignment + * + * @c Alloc::propagate_on_container_move_assignment if that type exists, + * otherwise @c false_type + */ + typedef __propagate_on_container_move_assignment + propagate_on_container_move_assignment; + +_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, + std::false_type) + + /** + * @brief How the allocator is propagated on swap + * + * @c Alloc::propagate_on_container_swap if that type exists, + * otherwise @c false_type + */ + typedef __propagate_on_container_swap propagate_on_container_swap; + +#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE + + template + using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type; + template + using rebind_traits = allocator_traits>; + + private: + template + struct __allocate_helper + { + template()->allocate( + std::declval(), + std::declval()))> + static std::true_type __test(int); + + template + static std::false_type __test(...); + + using type = decltype(__test<_Alloc>(0)); + }; + + template + using __has_allocate = typename __allocate_helper<_Alloc2>::type; + + template>> + static pointer + _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint) + { return __a.allocate(__n, __hint); } + + template>>> + static pointer + _S_allocate(_Alloc2& __a, size_type __n, _UnusedHint) + { return __a.allocate(__n); } + + template + struct __construct_helper + { + template()->construct( + std::declval<_Tp*>(), std::declval<_Args>()...))> + static std::true_type __test(int); + + template + static std::false_type __test(...); + + using type = decltype(__test<_Alloc>(0)); + }; + + template + using __has_construct + = typename __construct_helper<_Tp, _Args...>::type; + + template + static _Require<__has_construct<_Tp, _Args...>> + _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + { __a.construct(__p, std::forward<_Args>(__args)...); } + + template + static + _Require>, + std::is_constructible<_Tp, _Args...>>> + _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) + { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } + + template + struct __destroy_helper + { + template()->destroy( + std::declval<_Tp*>()))> + static std::true_type __test(int); + + template + static std::false_type __test(...); + + using type = decltype(__test<_Alloc>(0)); + }; + + template + using __has_destroy = typename __destroy_helper<_Tp>::type; + + template + static _Require<__has_destroy<_Tp>> + _S_destroy(_Alloc& __a, _Tp* __p) + { __a.destroy(__p); } + + template + static _Require<__not_<__has_destroy<_Tp>>> + _S_destroy(_Alloc&, _Tp* __p) + { __p->~_Tp(); } + + template + struct __maxsize_helper + { + template()->max_size())> + static std::true_type __test(int); + + template + static std::false_type __test(...); + + using type = decltype(__test<_Alloc2>(0)); + }; + + template + using __has_max_size = typename __maxsize_helper<_Alloc2>::type; + + template>> + static size_type + _S_max_size(_Alloc2& __a, int) + { return __a.max_size(); } + + template>>> + static size_type + _S_max_size(_Alloc2&, ...) + { return __gnu_cxx::__numeric_traits::__max; } + + template + struct __select_helper + { + template() + ->select_on_container_copy_construction())> + static std::true_type __test(int); + + template + static std::false_type __test(...); + + using type = decltype(__test<_Alloc2>(0)); + }; + + template + using __has_soccc = typename __select_helper<_Alloc2>::type; + + template>> + static _Alloc2 + _S_select(_Alloc2& __a, int) + { return __a.select_on_container_copy_construction(); } + + template>>> + static _Alloc2 + _S_select(_Alloc2& __a, ...) + { return __a; } + + public: + + /** + * @brief Allocate memory. + * @param __a An allocator. + * @param __n The number of objects to allocate space for. + * + * Calls @c a.allocate(n) + */ + static pointer + allocate(_Alloc& __a, size_type __n) + { return __a.allocate(__n); } + + /** + * @brief Allocate memory. + * @param __a An allocator. + * @param __n The number of objects to allocate space for. + * @param __hint Aid to locality. + * @return Memory of suitable size and alignment for @a n objects + * of type @c value_type + * + * Returns a.allocate(n, hint) if that expression is + * well-formed, otherwise returns @c a.allocate(n) + */ + static pointer + allocate(_Alloc& __a, size_type __n, const_void_pointer __hint) + { return _S_allocate(__a, __n, __hint); } + + /** + * @brief Deallocate memory. + * @param __a An allocator. + * @param __p Pointer to the memory to deallocate. + * @param __n The number of objects space was allocated for. + * + * Calls a.deallocate(p, n) + */ + static void deallocate(_Alloc& __a, pointer __p, size_type __n) + { __a.deallocate(__p, __n); } + + /** + * @brief Construct an object of type @a _Tp + * @param __a An allocator. + * @param __p Pointer to memory of suitable size and alignment for Tp + * @param __args Constructor arguments. + * + * Calls __a.construct(__p, std::forward(__args)...) + * if that expression is well-formed, otherwise uses placement-new + * to construct an object of type @a _Tp at location @a __p from the + * arguments @a __args... + */ + template + static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) + { _S_construct(__a, __p, std::forward<_Args>(__args)...); } + + /** + * @brief Destroy an object of type @a _Tp + * @param __a An allocator. + * @param __p Pointer to the object to destroy + * + * Calls @c __a.destroy(__p) if that expression is well-formed, + * otherwise calls @c __p->~_Tp() + */ + template + static void destroy(_Alloc& __a, _Tp* __p) + { _S_destroy(__a, __p); } + + /** + * @brief The maximum supported allocation size + * @param __a An allocator. + * @return @c __a.max_size() or @c numeric_limits::max() + * + * Returns @c __a.max_size() if that expression is well-formed, + * otherwise returns @c numeric_limits::max() + */ + static size_type max_size(const _Alloc& __a) noexcept + { return _S_max_size(__a, 0); } + + /** + * @brief Obtain an allocator to use when copying a container. + * @param __rhs An allocator. + * @return @c __rhs.select_on_container_copy_construction() or @a __rhs + * + * Returns @c __rhs.select_on_container_copy_construction() if that + * expression is well-formed, otherwise returns @a __rhs + */ + static _Alloc + select_on_container_copy_construction(const _Alloc& __rhs) + { return _S_select(__rhs, 0); } + }; + + template + inline void + __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, std::true_type) + { __one = __two; } + + template + inline void + __do_alloc_on_copy(_Alloc&, const _Alloc&, std::false_type) + { } + + template + inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two) + { + typedef allocator_traits<_Alloc> __traits; + typedef typename __traits::propagate_on_container_copy_assignment __pocca; + __do_alloc_on_copy(__one, __two, __pocca()); + } + + template + inline _Alloc __alloc_on_copy(const _Alloc& __a) + { + typedef allocator_traits<_Alloc> __traits; + return __traits::select_on_container_copy_construction(__a); + } + + template + inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, std::true_type) + { __one = std::move(__two); } + + template + inline void __do_alloc_on_move(_Alloc&, _Alloc&, std::false_type) + { } + + template + inline void __alloc_on_move(_Alloc& __one, _Alloc& __two) + { + typedef allocator_traits<_Alloc> __traits; + typedef typename __traits::propagate_on_container_move_assignment __pocma; + __do_alloc_on_move(__one, __two, __pocma()); + } + + template + inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, std::true_type) + { + using std::swap; + swap(__one, __two); + } + + template + inline void __do_alloc_on_swap(_Alloc&, _Alloc&, std::false_type) + { } + + template + inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two) + { + typedef allocator_traits<_Alloc> __traits; + typedef typename __traits::propagate_on_container_swap __pocs; + __do_alloc_on_swap(__one, __two, __pocs()); + } + + template + class __is_copy_insertable_impl + { + typedef allocator_traits<_Alloc> _Traits; + + template(), + std::declval<_Up*>(), + std::declval()))> + static std::true_type + _M_select(int); + + template + static std::false_type + _M_select(...); + + public: + typedef decltype(_M_select(0)) type; + }; + + // true if _Alloc::value_type is CopyInsertable into containers using _Alloc + template + struct __is_copy_insertable + : __is_copy_insertable_impl<_Alloc>::type + { }; + + // std::allocator<_Tp> just requires CopyConstructible + template + struct __is_copy_insertable> + : std::is_copy_constructible<_Tp> + { }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/allocator.h b/loader/include/Geode/c++stl/gnustl/allocator.h new file mode 100644 index 00000000..e2bd4635 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/allocator.h @@ -0,0 +1,220 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001-2014 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 +// . + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file bits/allocator.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H 1 + +#include "c++allocator.hpp" // Define the base class to std::allocator. +#include "memoryfwd.h" +#if __cplusplus >= 201103L +#include +#endif + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @addtogroup allocators + * @{ + */ + + /// allocator specialization. + template<> + class allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + +#if __cplusplus >= 201103L + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2103. std::allocator propagate_on_container_move_assignment + typedef std::true_type propagate_on_container_move_assignment; +#endif + }; + + /** + * @brief The @a standard allocator, as per [20.4]. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html + * for further details. + * + * @tparam _Tp Type of allocated object. + */ + template + class allocator: public __allocator_base<_Tp> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef allocator<_Tp1> other; }; + +#if __cplusplus >= 201103L + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2103. std::allocator propagate_on_container_move_assignment + typedef std::true_type propagate_on_container_move_assignment; +#endif + + allocator() throw() { } + + allocator(const allocator& __a) throw() + : __allocator_base<_Tp>(__a) { } + + template + allocator(const allocator<_Tp1>&) throw() { } + + ~allocator() throw() { } + + // Inherit everything else. + }; + + template + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } + + template + inline bool + operator==(const allocator<_Tp>&, const allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } + + template + inline bool + operator!=(const allocator<_Tp>&, const allocator<_Tp>&) + { return false; } + + /// @} group allocator + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class allocator; + extern template class allocator; +#endif + + // Undefine. +#undef __allocator_base + + // To implement Option 3 of DR 431. + template + struct __alloc_swap + { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } }; + + template + struct __alloc_swap<_Alloc, false> + { + static void + _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT + { + // Precondition: swappable allocators. + if (__one != __two) + swap(__one, __two); + } + }; + + // Optimize for stateless allocators. + template + struct __alloc_neq + { + static bool + _S_do_it(const _Alloc&, const _Alloc&) + { return false; } + }; + + template + struct __alloc_neq<_Alloc, false> + { + static bool + _S_do_it(const _Alloc& __one, const _Alloc& __two) + { return __one != __two; } + }; + +#if __cplusplus >= 201103L + template, + std::is_nothrow_move_constructible>::value> + struct __shrink_to_fit_aux + { static bool _S_do_it(_Tp&) noexcept { return false; } }; + + template + struct __shrink_to_fit_aux<_Tp, true> + { + static bool + _S_do_it(_Tp& __c) noexcept + { + try + { + _Tp(__make_move_if_noexcept_iterator(__c.begin()), + __make_move_if_noexcept_iterator(__c.end()), + __c.get_allocator()).swap(__c); + return true; + } + catch(...) + { return false; } + } + }; +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/c++allocator.hpp b/loader/include/Geode/c++stl/gnustl/c++allocator.hpp new file mode 100644 index 00000000..d0594187 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/c++allocator.hpp @@ -0,0 +1,54 @@ +// Base to std::allocator -*- C++ -*- + +// Copyright (C) 2004-2014 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 +// . + +/** @file bits/c++allocator.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#ifndef _GLIBCXX_CXX_ALLOCATOR_H +#define _GLIBCXX_CXX_ALLOCATOR_H 1 + +#include "ext/new_allocator.h" + +#if __cplusplus >= 201103L +namespace geode::stl { + /** + * @brief An alias to the base class for std::allocator. + * @ingroup allocators + * + * Used to set the std::allocator base class to + * __gnu_cxx::new_allocator. + * + * @tparam _Tp Type of allocated object. + */ + template + using __allocator_base = __gnu_cxx::new_allocator<_Tp>; +} +#else +// Define new_allocator as the base class to std::allocator. +# define __allocator_base __gnu_cxx::new_allocator +#endif + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/c++config-arm64.h b/loader/include/Geode/c++stl/gnustl/c++config-arm64.h new file mode 100644 index 00000000..11303f8b --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/c++config-arm64.h @@ -0,0 +1,1680 @@ +// Predefined symbols and macros -*- C++ -*- + +// Copyright (C) 1997-2014 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 +// . + +/** @file bits/c++config.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{iosfwd} + */ + +#ifndef _GLIBCXX_CXX_CONFIG_H +#define _GLIBCXX_CXX_CONFIG_H 1 + +// The current version of the C++ library in compressed ISO date format. +#define __GLIBCXX__ 20150123 + +// Macros for various attributes. +// _GLIBCXX_PURE +// _GLIBCXX_CONST +// _GLIBCXX_NORETURN +// _GLIBCXX_NOTHROW +// _GLIBCXX_VISIBILITY +#ifndef _GLIBCXX_PURE +# define _GLIBCXX_PURE __attribute__ ((__pure__)) +#endif + +#ifndef _GLIBCXX_CONST +# define _GLIBCXX_CONST __attribute__ ((__const__)) +#endif + +#ifndef _GLIBCXX_NORETURN +# define _GLIBCXX_NORETURN __attribute__ ((__noreturn__)) +#endif + +// See below for C++ +#ifndef _GLIBCXX_NOTHROW +# ifndef __cplusplus +# define _GLIBCXX_NOTHROW __attribute__((__nothrow__)) +# endif +#endif + +// Macros for visibility attributes. +// _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +// _GLIBCXX_VISIBILITY +# define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 + +#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +# define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) +#else +// If this is not supplied by the OS-specific or CPU-specific +// headers included below, it will be defined to an empty default. +# define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) +#endif + +// Macros for deprecated attributes. +// _GLIBCXX_USE_DEPRECATED +// _GLIBCXX_DEPRECATED +#ifndef _GLIBCXX_USE_DEPRECATED +# define _GLIBCXX_USE_DEPRECATED 1 +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +# define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) +#else +# define _GLIBCXX_DEPRECATED +#endif + +// Macros for ABI tag attributes. +#ifndef _GLIBCXX_ABI_TAG_CXX11 +# define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) +#endif + + +#if __cplusplus + +// Macro for constexpr, to support in mixed 03/0x mode. +#ifndef _GLIBCXX_CONSTEXPR +# if __cplusplus >= 201103L +# define _GLIBCXX_CONSTEXPR constexpr +# define _GLIBCXX_USE_CONSTEXPR constexpr +# else +# define _GLIBCXX_CONSTEXPR +# define _GLIBCXX_USE_CONSTEXPR const +# endif +#endif + +// Macro for noexcept, to support in mixed 03/0x mode. +#ifndef _GLIBCXX_NOEXCEPT +# if __cplusplus >= 201103L +# define _GLIBCXX_NOEXCEPT noexcept +# define _GLIBCXX_USE_NOEXCEPT noexcept +# define _GLIBCXX_THROW(_EXC) +# else +# define _GLIBCXX_NOEXCEPT +# define _GLIBCXX_USE_NOEXCEPT throw() +# define _GLIBCXX_THROW(_EXC) throw(_EXC) +# endif +#endif + +#ifndef _GLIBCXX_NOTHROW +# define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT +#endif + +#ifndef _GLIBCXX_THROW_OR_ABORT +# if __EXCEPTIONS +# define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC)) +# else +# define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort()) +# endif +#endif + +// Macro for extern template, ie controling template linkage via use +// of extern keyword on template declaration. As documented in the g++ +// manual, it inhibits all implicit instantiations and is used +// throughout the library to avoid multiple weak definitions for +// required types that are already explicitly instantiated in the +// library binary. This substantially reduces the binary size of +// resulting executables. +// Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern +// templates only in basic_string, thus activating its debug-mode +// checks even at -O0. +# define _GLIBCXX_EXTERN_TEMPLATE 1 + +/* + Outline of libstdc++ namespaces. + + namespace std + { + namespace __debug { } + namespace __parallel { } + namespace __profile { } + namespace __cxx1998 { } + + namespace __detail { } + + namespace rel_ops { } + + namespace tr1 + { + namespace placeholders { } + namespace regex_constants { } + namespace __detail { } + } + + namespace tr2 { } + + namespace decimal { } + + namespace chrono { } + namespace placeholders { } + namespace regex_constants { } + namespace this_thread { } + + namespace experimental { } + } + + namespace abi { } + + namespace __gnu_cxx + { + namespace __detail { } + } + + For full details see: + http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html +*/ +namespace std +{ + typedef __SIZE_TYPE__ size_t; + typedef __PTRDIFF_TYPE__ ptrdiff_t; + +#if __cplusplus >= 201103L + typedef decltype(nullptr) nullptr_t; +#endif +} + + +// Defined if inline namespaces are used for versioning. +# define _GLIBCXX_INLINE_VERSION 0 + +// Inline namespace for symbol versioning. +#if _GLIBCXX_INLINE_VERSION + +namespace std +{ + inline namespace __7 { } + + namespace rel_ops { inline namespace __7 { } } + + namespace tr1 + { + inline namespace __7 { } + namespace placeholders { inline namespace __7 { } } + namespace regex_constants { inline namespace __7 { } } + namespace __detail { inline namespace __7 { } } + } + + namespace tr2 + { inline namespace __7 { } } + + namespace decimal { inline namespace __7 { } } + + namespace chrono { inline namespace __7 { } } + namespace placeholders { inline namespace __7 { } } + namespace regex_constants { inline namespace __7 { } } + namespace this_thread { inline namespace __7 { } } + + namespace experimental { inline namespace __7 { } } + + namespace __detail { inline namespace __7 { } } +} + +namespace __gnu_cxx +{ + inline namespace __7 { } + namespace __detail { inline namespace __7 { } } +} +# define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 { +# define _GLIBCXX_END_NAMESPACE_VERSION } +#else +# define _GLIBCXX_BEGIN_NAMESPACE_VERSION +# define _GLIBCXX_END_NAMESPACE_VERSION +#endif + + +// Inline namespaces for special modes: debug, parallel, profile. +#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \ + || defined(_GLIBCXX_PROFILE) +namespace std +{ + // Non-inline namespace for components replaced by alternates in active mode. + namespace __cxx1998 + { +#if _GLIBCXX_INLINE_VERSION + inline namespace __7 { } +#endif + } + + // Inline namespace for debug mode. +# ifdef _GLIBCXX_DEBUG + inline namespace __debug { } +# endif + + // Inline namespaces for parallel mode. +# ifdef _GLIBCXX_PARALLEL + inline namespace __parallel { } +# endif + + // Inline namespaces for profile mode +# ifdef _GLIBCXX_PROFILE + inline namespace __profile { } +# endif +} + +// Check for invalid usage and unsupported mixed-mode use. +# if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL) +# error illegal use of multiple inlined namespaces +# endif +# if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG) +# error illegal use of multiple inlined namespaces +# endif +# if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL) +# error illegal use of multiple inlined namespaces +# endif + +// Check for invalid use due to lack for weak symbols. +# if __NO_INLINE__ && !__GXX_WEAK__ +# warning currently using inlined namespace mode which may fail \ + without inlining due to lack of weak symbols +# endif +#endif + +// Macros for namespace scope. Either namespace std:: or the name +// of some nested namespace within it corresponding to the active mode. +// _GLIBCXX_STD_A +// _GLIBCXX_STD_C +// +// Macros for opening/closing conditional namespaces. +// _GLIBCXX_BEGIN_NAMESPACE_ALGO +// _GLIBCXX_END_NAMESPACE_ALGO +// _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +// _GLIBCXX_END_NAMESPACE_CONTAINER +#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) +# define _GLIBCXX_STD_C __cxx1998 +# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ + namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION +# define _GLIBCXX_END_NAMESPACE_CONTAINER \ + _GLIBCXX_END_NAMESPACE_VERSION } +# undef _GLIBCXX_EXTERN_TEMPLATE +# define _GLIBCXX_EXTERN_TEMPLATE -1 +#endif + +#ifdef _GLIBCXX_PARALLEL +# define _GLIBCXX_STD_A __cxx1998 +# define _GLIBCXX_BEGIN_NAMESPACE_ALGO \ + namespace _GLIBCXX_STD_A { _GLIBCXX_BEGIN_NAMESPACE_VERSION +# define _GLIBCXX_END_NAMESPACE_ALGO \ + _GLIBCXX_END_NAMESPACE_VERSION } +#endif + +#ifndef _GLIBCXX_STD_A +# define _GLIBCXX_STD_A std +#endif + +#ifndef _GLIBCXX_STD_C +# define _GLIBCXX_STD_C std +#endif + +#ifndef _GLIBCXX_BEGIN_NAMESPACE_ALGO +# define _GLIBCXX_BEGIN_NAMESPACE_ALGO +#endif + +#ifndef _GLIBCXX_END_NAMESPACE_ALGO +# define _GLIBCXX_END_NAMESPACE_ALGO +#endif + +#ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +#endif + +#ifndef _GLIBCXX_END_NAMESPACE_CONTAINER +# define _GLIBCXX_END_NAMESPACE_CONTAINER +#endif + +// GLIBCXX_ABI Deprecated +// Define if compatibility should be provided for -mlong-double-64. +#undef _GLIBCXX_LONG_DOUBLE_COMPAT + +// Inline namespace for long double 128 mode. +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +namespace std +{ + inline namespace __gnu_cxx_ldbl128 { } +} +# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 { +# define _GLIBCXX_END_NAMESPACE_LDBL } +#else +# define _GLIBCXX_NAMESPACE_LDBL +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL +# define _GLIBCXX_END_NAMESPACE_LDBL +#endif + +// Assert. +#if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PARALLEL) +# define __glibcxx_assert(_Condition) +#else +namespace std +{ + // Avoid the use of assert, because we're trying to keep the + // include out of the mix. + inline void + __replacement_assert(const char* __file, int __line, + const char* __function, const char* __condition) + { + __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, + __function, __condition); + __builtin_abort(); + } +} +#define __glibcxx_assert(_Condition) \ + do \ + { \ + if (! (_Condition)) \ + std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } while (false) +#endif + +// Macros for race detectors. +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain +// atomic (lock-free) synchronization to race detectors: +// the race detector will infer a happens-before arc from the former to the +// latter when they share the same argument pointer. +// +// The most frequent use case for these macros (and the only case in the +// current implementation of the library) is atomic reference counting: +// void _M_remove_reference() +// { +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); +// if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) +// { +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); +// _M_destroy(__a); +// } +// } +// The annotations in this example tell the race detector that all memory +// accesses occurred when the refcount was positive do not race with +// memory accesses which occurred after the refcount became zero. +#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE +# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) +#endif +#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER +# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) +#endif + +// Macros for C linkage: define extern "C" linkage only when using C++. +# define _GLIBCXX_BEGIN_EXTERN_C extern "C" { +# define _GLIBCXX_END_EXTERN_C } + +#else // !__cplusplus +# define _GLIBCXX_BEGIN_EXTERN_C +# define _GLIBCXX_END_EXTERN_C +#endif + + +// First includes. + +// Pick up any OS-specific definitions. +// #include "os_defines.h" // dank: Empty on this arch + +// Pick up any CPU-specific definitions. +// #include "cpu_defines.h" // dank: Empty on this arch + +// If platform uses neither visibility nor psuedo-visibility, +// specify empty default for namespace annotation macros. +#ifndef _GLIBCXX_PSEUDO_VISIBILITY +# define _GLIBCXX_PSEUDO_VISIBILITY(V) +#endif + +// Certain function definitions that are meant to be overridable from +// user code are decorated with this macro. For some targets, this +// macro causes these definitions to be weak. +#ifndef _GLIBCXX_WEAK_DEFINITION +# define _GLIBCXX_WEAK_DEFINITION +#endif + + +// The remainder of the prewritten config is automatic; all the +// user hooks are listed above. + +// Create a boolean flag to be used to determine if --fast-math is set. +#ifdef __FAST_MATH__ +# define _GLIBCXX_FAST_MATH 1 +#else +# define _GLIBCXX_FAST_MATH 0 +#endif + +// This marks string literals in header files to be extracted for eventual +// translation. It is primarily used for messages in thrown exceptions; see +// src/functexcept.cc. We use __N because the more traditional _N is used +// for something else under certain OSes (see BADNAMES). +#define __N(msgid) (msgid) + +// For example, is known to #define min and max as macros... +#undef min +#undef max + +// End of prewritten config; the settings discovered at configure time follow. +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `acosf' function. */ +#define _GLIBCXX_HAVE_ACOSF 1 + +/* Define to 1 if you have the `acosl' function. */ +#define _GLIBCXX_HAVE_ACOSL 1 + +/* Define to 1 if you have the `asinf' function. */ +#define _GLIBCXX_HAVE_ASINF 1 + +/* Define to 1 if you have the `asinl' function. */ +#define _GLIBCXX_HAVE_ASINL 1 + +/* Define to 1 if the target assembler supports .symver directive. */ +#define _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE 1 + +/* Define to 1 if you have the `atan2f' function. */ +#define _GLIBCXX_HAVE_ATAN2F 1 + +/* Define to 1 if you have the `atan2l' function. */ +#define _GLIBCXX_HAVE_ATAN2L 1 + +/* Define to 1 if you have the `atanf' function. */ +#define _GLIBCXX_HAVE_ATANF 1 + +/* Define to 1 if you have the `atanl' function. */ +#define _GLIBCXX_HAVE_ATANL 1 + +/* Define to 1 if you have the `at_quick_exit' function. */ +/* #undef _GLIBCXX_HAVE_AT_QUICK_EXIT */ + +/* Define to 1 if the target assembler supports thread-local storage. */ +/* #undef _GLIBCXX_HAVE_CC_TLS */ + +/* Define to 1 if you have the `ceilf' function. */ +#define _GLIBCXX_HAVE_CEILF 1 + +/* Define to 1 if you have the `ceill' function. */ +#define _GLIBCXX_HAVE_CEILL 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_COMPLEX_H 1 + +/* Define to 1 if you have the `cosf' function. */ +#define _GLIBCXX_HAVE_COSF 1 + +/* Define to 1 if you have the `coshf' function. */ +#define _GLIBCXX_HAVE_COSHF 1 + +/* Define to 1 if you have the `coshl' function. */ +#define _GLIBCXX_HAVE_COSHL 1 + +/* Define to 1 if you have the `cosl' function. */ +#define _GLIBCXX_HAVE_COSL 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_DLFCN_H 1 + +/* Define if EBADMSG exists. */ +#define _GLIBCXX_HAVE_EBADMSG 1 + +/* Define if ECANCELED exists. */ +#define _GLIBCXX_HAVE_ECANCELED 1 + +/* Define if ECHILD exists. */ +#define _GLIBCXX_HAVE_ECHILD 1 + +/* Define if EIDRM exists. */ +#define _GLIBCXX_HAVE_EIDRM 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_ENDIAN_H 1 + +/* Define if ENODATA exists. */ +#define _GLIBCXX_HAVE_ENODATA 1 + +/* Define if ENOLINK exists. */ +#define _GLIBCXX_HAVE_ENOLINK 1 + +/* Define if ENOSPC exists. */ +#define _GLIBCXX_HAVE_ENOSPC 1 + +/* Define if ENOSR exists. */ +#define _GLIBCXX_HAVE_ENOSR 1 + +/* Define if ENOSTR exists. */ +#define _GLIBCXX_HAVE_ENOSTR 1 + +/* Define if ENOTRECOVERABLE exists. */ +#define _GLIBCXX_HAVE_ENOTRECOVERABLE 1 + +/* Define if ENOTSUP exists. */ +#define _GLIBCXX_HAVE_ENOTSUP 1 + +/* Define if EOVERFLOW exists. */ +#define _GLIBCXX_HAVE_EOVERFLOW 1 + +/* Define if EOWNERDEAD exists. */ +#define _GLIBCXX_HAVE_EOWNERDEAD 1 + +/* Define if EPERM exists. */ +#define _GLIBCXX_HAVE_EPERM 1 + +/* Define if EPROTO exists. */ +#define _GLIBCXX_HAVE_EPROTO 1 + +/* Define if ETIME exists. */ +#define _GLIBCXX_HAVE_ETIME 1 + +/* Define if ETIMEDOUT exists. */ +#define _GLIBCXX_HAVE_ETIMEDOUT 1 + +/* Define if ETXTBSY exists. */ +#define _GLIBCXX_HAVE_ETXTBSY 1 + +/* Define if EWOULDBLOCK exists. */ +#define _GLIBCXX_HAVE_EWOULDBLOCK 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_EXECINFO_H */ + +/* Define to 1 if you have the `expf' function. */ +#define _GLIBCXX_HAVE_EXPF 1 + +/* Define to 1 if you have the `expl' function. */ +#define _GLIBCXX_HAVE_EXPL 1 + +/* Define to 1 if you have the `fabsf' function. */ +#define _GLIBCXX_HAVE_FABSF 1 + +/* Define to 1 if you have the `fabsl' function. */ +#define _GLIBCXX_HAVE_FABSL 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_FENV_H 1 + +/* Define to 1 if you have the `finite' function. */ +#define _GLIBCXX_HAVE_FINITE 1 + +/* Define to 1 if you have the `finitef' function. */ +#define _GLIBCXX_HAVE_FINITEF 1 + +/* Define to 1 if you have the `finitel' function. */ +/* #undef _GLIBCXX_HAVE_FINITEL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_FLOAT_H 1 + +/* Define to 1 if you have the `floorf' function. */ +#define _GLIBCXX_HAVE_FLOORF 1 + +/* Define to 1 if you have the `floorl' function. */ +#define _GLIBCXX_HAVE_FLOORL 1 + +/* Define to 1 if you have the `fmodf' function. */ +#define _GLIBCXX_HAVE_FMODF 1 + +/* Define to 1 if you have the `fmodl' function. */ +#define _GLIBCXX_HAVE_FMODL 1 + +/* Define to 1 if you have the `fpclass' function. */ +/* #undef _GLIBCXX_HAVE_FPCLASS */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_FP_H */ + +/* Define to 1 if you have the `frexpf' function. */ +#define _GLIBCXX_HAVE_FREXPF 1 + +/* Define to 1 if you have the `frexpl' function. */ +#define _GLIBCXX_HAVE_FREXPL 1 + +/* Define if _Unwind_GetIPInfo is available. */ +#define _GLIBCXX_HAVE_GETIPINFO 1 + +/* Define if gets is available in . */ +#define _GLIBCXX_HAVE_GETS 1 + +/* Define to 1 if you have the `hypot' function. */ +#define _GLIBCXX_HAVE_HYPOT 1 + +/* Define to 1 if you have the `hypotf' function. */ +#define _GLIBCXX_HAVE_HYPOTF 1 + +/* Define to 1 if you have the `hypotl' function. */ +#define _GLIBCXX_HAVE_HYPOTL 1 + +/* Define if you have the iconv() function. */ +/* #undef _GLIBCXX_HAVE_ICONV */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_IEEEFP_H */ + +/* Define if int64_t is available in . */ +#define _GLIBCXX_HAVE_INT64_T 1 + +/* Define if int64_t is a long. */ +#define _GLIBCXX_HAVE_INT64_T_LONG 1 + +/* Define if int64_t is a long long. */ +/* #undef _GLIBCXX_HAVE_INT64_T_LONG_LONG */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isinf' function. */ +#define _GLIBCXX_HAVE_ISINF 1 + +/* Define to 1 if you have the `isinff' function. */ +/* #undef _GLIBCXX_HAVE_ISINFF */ + +/* Define to 1 if you have the `isinfl' function. */ +/* #undef _GLIBCXX_HAVE_ISINFL */ + +/* Define to 1 if you have the `isnan' function. */ +#define _GLIBCXX_HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +#define _GLIBCXX_HAVE_ISNANF 1 + +/* Define to 1 if you have the `isnanl' function. */ +/* #undef _GLIBCXX_HAVE_ISNANL */ + +/* Defined if iswblank exists. */ +#define _GLIBCXX_HAVE_ISWBLANK 1 + +/* Define if LC_MESSAGES is available in . */ +#define _GLIBCXX_HAVE_LC_MESSAGES 1 + +/* Define to 1 if you have the `ldexpf' function. */ +#define _GLIBCXX_HAVE_LDEXPF 1 + +/* Define to 1 if you have the `ldexpl' function. */ +#define _GLIBCXX_HAVE_LDEXPL 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_LIBINTL_H */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_AS */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_DATA */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_FSIZE */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_RSS */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_VMEM */ + +/* Define if futex syscall is available. */ +#define _GLIBCXX_HAVE_LINUX_FUTEX 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `log10f' function. */ +#define _GLIBCXX_HAVE_LOG10F 1 + +/* Define to 1 if you have the `log10l' function. */ +#define _GLIBCXX_HAVE_LOG10L 1 + +/* Define to 1 if you have the `logf' function. */ +#define _GLIBCXX_HAVE_LOGF 1 + +/* Define to 1 if you have the `logl' function. */ +#define _GLIBCXX_HAVE_LOGL 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MACHINE_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_MACHINE_PARAM_H */ + +/* Define if mbstate_t exists in wchar.h. */ +#define _GLIBCXX_HAVE_MBSTATE_T 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `modf' function. */ +#define _GLIBCXX_HAVE_MODF 1 + +/* Define to 1 if you have the `modff' function. */ +#define _GLIBCXX_HAVE_MODFF 1 + +/* Define to 1 if you have the `modfl' function. */ +#define _GLIBCXX_HAVE_MODFL 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_NAN_H */ + +/* Define if poll is available in . */ +#define _GLIBCXX_HAVE_POLL 1 + +/* Define to 1 if you have the `powf' function. */ +#define _GLIBCXX_HAVE_POWF 1 + +/* Define to 1 if you have the `powl' function. */ +#define _GLIBCXX_HAVE_POWL 1 + +/* Define to 1 if you have the `qfpclass' function. */ +/* #undef _GLIBCXX_HAVE_QFPCLASS */ + +/* Define to 1 if you have the `quick_exit' function. */ +/* #undef _GLIBCXX_HAVE_QUICK_EXIT */ + +/* Define to 1 if you have the `setenv' function. */ +/* #undef _GLIBCXX_HAVE_SETENV */ + +/* Define to 1 if you have the `sincos' function. */ +#define _GLIBCXX_HAVE_SINCOS 1 + +/* Define to 1 if you have the `sincosf' function. */ +#define _GLIBCXX_HAVE_SINCOSF 1 + +/* Define to 1 if you have the `sincosl' function. */ +#define _GLIBCXX_HAVE_SINCOSL 1 + +/* Define to 1 if you have the `sinf' function. */ +#define _GLIBCXX_HAVE_SINF 1 + +/* Define to 1 if you have the `sinhf' function. */ +#define _GLIBCXX_HAVE_SINHF 1 + +/* Define to 1 if you have the `sinhl' function. */ +#define _GLIBCXX_HAVE_SINHL 1 + +/* Define to 1 if you have the `sinl' function. */ +#define _GLIBCXX_HAVE_SINL 1 + +/* Defined if sleep exists. */ +/* #undef _GLIBCXX_HAVE_SLEEP */ + +/* Define to 1 if you have the `sqrtf' function. */ +#define _GLIBCXX_HAVE_SQRTF 1 + +/* Define to 1 if you have the `sqrtl' function. */ +#define _GLIBCXX_HAVE_SQRTL 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDALIGN_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDLIB_H 1 + +/* Define if strerror_l is available in . */ +/* #undef _GLIBCXX_HAVE_STRERROR_L */ + +/* Define if strerror_r is available in . */ +#define _GLIBCXX_HAVE_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtof' function. */ +#define _GLIBCXX_HAVE_STRTOF 1 + +/* Define to 1 if you have the `strtold' function. */ +#define _GLIBCXX_HAVE_STRTOLD 1 + +/* Define if strxfrm_l is available in . */ +/* #undef _GLIBCXX_HAVE_STRXFRM_L */ + +/* Define to 1 if the target runtime linker supports binding the same symbol + to different versions. */ +/* #undef _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_FILIO_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_IPC_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have a suitable header file */ +/* #undef _GLIBCXX_HAVE_SYS_SDT_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_SEM_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_SYSINFO_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_UIO_H 1 + +/* Define if S_IFREG is available in . */ +/* #undef _GLIBCXX_HAVE_S_IFREG */ + +/* Define if S_IFREG is available in . */ +#define _GLIBCXX_HAVE_S_ISREG 1 + +/* Define to 1 if you have the `tanf' function. */ +#define _GLIBCXX_HAVE_TANF 1 + +/* Define to 1 if you have the `tanhf' function. */ +#define _GLIBCXX_HAVE_TANHF 1 + +/* Define to 1 if you have the `tanhl' function. */ +#define _GLIBCXX_HAVE_TANHL 1 + +/* Define to 1 if you have the `tanl' function. */ +#define _GLIBCXX_HAVE_TANL 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_TGMATH_H */ + +/* Define to 1 if the target supports thread-local storage. */ +/* #undef _GLIBCXX_HAVE_TLS */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_UNISTD_H 1 + +/* Defined if usleep exists. */ +/* #undef _GLIBCXX_HAVE_USLEEP */ + +/* Defined if vfwscanf exists. */ +#define _GLIBCXX_HAVE_VFWSCANF 1 + +/* Defined if vswscanf exists. */ +#define _GLIBCXX_HAVE_VSWSCANF 1 + +/* Defined if vwscanf exists. */ +#define _GLIBCXX_HAVE_VWSCANF 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCHAR_H 1 + +/* Defined if wcstof exists. */ +#define _GLIBCXX_HAVE_WCSTOF 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCTYPE_H 1 + +/* Defined if Sleep exists. */ +/* #undef _GLIBCXX_HAVE_WIN32_SLEEP */ + +/* Define if writev is available in . */ +#define _GLIBCXX_HAVE_WRITEV 1 + +/* Define to 1 if you have the `_acosf' function. */ +/* #undef _GLIBCXX_HAVE__ACOSF */ + +/* Define to 1 if you have the `_acosl' function. */ +/* #undef _GLIBCXX_HAVE__ACOSL */ + +/* Define to 1 if you have the `_asinf' function. */ +/* #undef _GLIBCXX_HAVE__ASINF */ + +/* Define to 1 if you have the `_asinl' function. */ +/* #undef _GLIBCXX_HAVE__ASINL */ + +/* Define to 1 if you have the `_atan2f' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2F */ + +/* Define to 1 if you have the `_atan2l' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2L */ + +/* Define to 1 if you have the `_atanf' function. */ +/* #undef _GLIBCXX_HAVE__ATANF */ + +/* Define to 1 if you have the `_atanl' function. */ +/* #undef _GLIBCXX_HAVE__ATANL */ + +/* Define to 1 if you have the `_ceilf' function. */ +/* #undef _GLIBCXX_HAVE__CEILF */ + +/* Define to 1 if you have the `_ceill' function. */ +/* #undef _GLIBCXX_HAVE__CEILL */ + +/* Define to 1 if you have the `_cosf' function. */ +/* #undef _GLIBCXX_HAVE__COSF */ + +/* Define to 1 if you have the `_coshf' function. */ +/* #undef _GLIBCXX_HAVE__COSHF */ + +/* Define to 1 if you have the `_coshl' function. */ +/* #undef _GLIBCXX_HAVE__COSHL */ + +/* Define to 1 if you have the `_cosl' function. */ +/* #undef _GLIBCXX_HAVE__COSL */ + +/* Define to 1 if you have the `_expf' function. */ +/* #undef _GLIBCXX_HAVE__EXPF */ + +/* Define to 1 if you have the `_expl' function. */ +/* #undef _GLIBCXX_HAVE__EXPL */ + +/* Define to 1 if you have the `_fabsf' function. */ +/* #undef _GLIBCXX_HAVE__FABSF */ + +/* Define to 1 if you have the `_fabsl' function. */ +/* #undef _GLIBCXX_HAVE__FABSL */ + +/* Define to 1 if you have the `_finite' function. */ +/* #undef _GLIBCXX_HAVE__FINITE */ + +/* Define to 1 if you have the `_finitef' function. */ +/* #undef _GLIBCXX_HAVE__FINITEF */ + +/* Define to 1 if you have the `_finitel' function. */ +/* #undef _GLIBCXX_HAVE__FINITEL */ + +/* Define to 1 if you have the `_floorf' function. */ +/* #undef _GLIBCXX_HAVE__FLOORF */ + +/* Define to 1 if you have the `_floorl' function. */ +/* #undef _GLIBCXX_HAVE__FLOORL */ + +/* Define to 1 if you have the `_fmodf' function. */ +/* #undef _GLIBCXX_HAVE__FMODF */ + +/* Define to 1 if you have the `_fmodl' function. */ +/* #undef _GLIBCXX_HAVE__FMODL */ + +/* Define to 1 if you have the `_fpclass' function. */ +/* #undef _GLIBCXX_HAVE__FPCLASS */ + +/* Define to 1 if you have the `_frexpf' function. */ +/* #undef _GLIBCXX_HAVE__FREXPF */ + +/* Define to 1 if you have the `_frexpl' function. */ +/* #undef _GLIBCXX_HAVE__FREXPL */ + +/* Define to 1 if you have the `_hypot' function. */ +/* #undef _GLIBCXX_HAVE__HYPOT */ + +/* Define to 1 if you have the `_hypotf' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTF */ + +/* Define to 1 if you have the `_hypotl' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTL */ + +/* Define to 1 if you have the `_isinf' function. */ +/* #undef _GLIBCXX_HAVE__ISINF */ + +/* Define to 1 if you have the `_isinff' function. */ +/* #undef _GLIBCXX_HAVE__ISINFF */ + +/* Define to 1 if you have the `_isinfl' function. */ +/* #undef _GLIBCXX_HAVE__ISINFL */ + +/* Define to 1 if you have the `_isnan' function. */ +/* #undef _GLIBCXX_HAVE__ISNAN */ + +/* Define to 1 if you have the `_isnanf' function. */ +/* #undef _GLIBCXX_HAVE__ISNANF */ + +/* Define to 1 if you have the `_isnanl' function. */ +/* #undef _GLIBCXX_HAVE__ISNANL */ + +/* Define to 1 if you have the `_ldexpf' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPF */ + +/* Define to 1 if you have the `_ldexpl' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPL */ + +/* Define to 1 if you have the `_log10f' function. */ +/* #undef _GLIBCXX_HAVE__LOG10F */ + +/* Define to 1 if you have the `_log10l' function. */ +/* #undef _GLIBCXX_HAVE__LOG10L */ + +/* Define to 1 if you have the `_logf' function. */ +/* #undef _GLIBCXX_HAVE__LOGF */ + +/* Define to 1 if you have the `_logl' function. */ +/* #undef _GLIBCXX_HAVE__LOGL */ + +/* Define to 1 if you have the `_modf' function. */ +/* #undef _GLIBCXX_HAVE__MODF */ + +/* Define to 1 if you have the `_modff' function. */ +/* #undef _GLIBCXX_HAVE__MODFF */ + +/* Define to 1 if you have the `_modfl' function. */ +/* #undef _GLIBCXX_HAVE__MODFL */ + +/* Define to 1 if you have the `_powf' function. */ +/* #undef _GLIBCXX_HAVE__POWF */ + +/* Define to 1 if you have the `_powl' function. */ +/* #undef _GLIBCXX_HAVE__POWL */ + +/* Define to 1 if you have the `_qfpclass' function. */ +/* #undef _GLIBCXX_HAVE__QFPCLASS */ + +/* Define to 1 if you have the `_sincos' function. */ +/* #undef _GLIBCXX_HAVE__SINCOS */ + +/* Define to 1 if you have the `_sincosf' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSF */ + +/* Define to 1 if you have the `_sincosl' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSL */ + +/* Define to 1 if you have the `_sinf' function. */ +/* #undef _GLIBCXX_HAVE__SINF */ + +/* Define to 1 if you have the `_sinhf' function. */ +/* #undef _GLIBCXX_HAVE__SINHF */ + +/* Define to 1 if you have the `_sinhl' function. */ +/* #undef _GLIBCXX_HAVE__SINHL */ + +/* Define to 1 if you have the `_sinl' function. */ +/* #undef _GLIBCXX_HAVE__SINL */ + +/* Define to 1 if you have the `_sqrtf' function. */ +/* #undef _GLIBCXX_HAVE__SQRTF */ + +/* Define to 1 if you have the `_sqrtl' function. */ +/* #undef _GLIBCXX_HAVE__SQRTL */ + +/* Define to 1 if you have the `_tanf' function. */ +/* #undef _GLIBCXX_HAVE__TANF */ + +/* Define to 1 if you have the `_tanhf' function. */ +/* #undef _GLIBCXX_HAVE__TANHF */ + +/* Define to 1 if you have the `_tanhl' function. */ +/* #undef _GLIBCXX_HAVE__TANHL */ + +/* Define to 1 if you have the `_tanl' function. */ +/* #undef _GLIBCXX_HAVE__TANL */ + +/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */ +/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */ + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef _GLIBCXX_ICONV_CONST */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +/* #undef _GLIBCXX_PACKAGE */ + +/* Define to the address where bug reports for this package should be sent. */ +#define _GLIBCXX_PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define _GLIBCXX_PACKAGE_NAME "package-unused" + +/* Define to the full name and version of this package. */ +#define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" + +/* Define to the one symbol short name of this package. */ +#define _GLIBCXX_PACKAGE_TARNAME "libstdc++" + +/* Define to the home page for this package. */ +#define _GLIBCXX_PACKAGE_URL "" + +/* Define to the version of this package. */ +#define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" + +/* The size of `char', as computed by sizeof. */ +/* #undef SIZEOF_CHAR */ + +/* The size of `int', as computed by sizeof. */ +/* #undef SIZEOF_INT */ + +/* The size of `long', as computed by sizeof. */ +/* #undef SIZEOF_LONG */ + +/* The size of `short', as computed by sizeof. */ +/* #undef SIZEOF_SHORT */ + +/* The size of `void *', as computed by sizeof. */ +/* #undef SIZEOF_VOID_P */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +/* #undef _GLIBCXX_VERSION */ + +/* Define if the compiler supports C++11 atomics. */ +#define _GLIBCXX_ATOMIC_BUILTINS 1 + +/* Define to use concept checking code from the boost libraries. */ +/* #undef _GLIBCXX_CONCEPT_CHECKS */ + +/* Define to 1 if a fully dynamic basic_string is wanted, 0 to disable, + undefined for platform defaults */ +#define _GLIBCXX_FULLY_DYNAMIC_STRING 0 + +/* Define if gthreads library is available. */ +#define _GLIBCXX_HAS_GTHREADS 1 + +/* Define to 1 if a full hosted library is built, or 0 if freestanding. */ +#define _GLIBCXX_HOSTED 1 + +/* Define if compatibility should be provided for -mlong-double-64. */ + +/* Define if ptrdiff_t is int. */ +/* #undef _GLIBCXX_PTRDIFF_T_IS_INT */ + +/* Define if using setrlimit to set resource limits during "make check" */ +/* #undef _GLIBCXX_RES_LIMITS */ + +/* Define if size_t is unsigned int. */ +/* #undef _GLIBCXX_SIZE_T_IS_UINT */ + +/* Define if the compiler is configured for setjmp/longjmp exceptions. */ +/* #undef _GLIBCXX_SJLJ_EXCEPTIONS */ + +/* Define to the value of the EOF integer constant. */ +#define _GLIBCXX_STDIO_EOF -1 + +/* Define to the value of the SEEK_CUR integer constant. */ +#define _GLIBCXX_STDIO_SEEK_CUR 1 + +/* Define to the value of the SEEK_END integer constant. */ +#define _GLIBCXX_STDIO_SEEK_END 2 + +/* Define to use symbol versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER */ + +/* Define to use darwin versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_DARWIN */ + +/* Define to use GNU versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_GNU */ + +/* Define to use GNU namespace versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_GNU_NAMESPACE */ + +/* Define to use Sun versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_SUN */ + +/* Define if C99 functions or macros from , , , + , and can be used or exposed. */ +/* #undef _GLIBCXX_USE_C99 */ + +/* Define if C99 functions in should be used in . Using + compiler builtins for these functions requires corresponding C99 library + functions to be present. */ +/* #undef _GLIBCXX_USE_C99_COMPLEX */ + +/* Define if C99 functions in should be used in . + Using compiler builtins for these functions requires corresponding C99 + library functions to be present. */ +/* #undef _GLIBCXX_USE_C99_COMPLEX_TR1 */ + +/* Define if C99 functions in should be imported in in + namespace std::tr1. */ +#define _GLIBCXX_USE_C99_CTYPE_TR1 1 + +/* Define if C99 functions in should be imported in in + namespace std::tr1. */ +#define _GLIBCXX_USE_C99_FENV_TR1 1 + +/* Define if C99 functions in should be imported in + in namespace std::tr1. */ +#define _GLIBCXX_USE_C99_INTTYPES_TR1 1 + +/* Define if wchar_t C99 functions in should be imported in + in namespace std::tr1. */ +#define _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 1 + +/* Define if C99 functions or macros in should be imported in + in namespace std. */ +#define _GLIBCXX_USE_C99_MATH 1 + +/* Define if C99 functions or macros in should be imported in + in namespace std::tr1. */ +#define _GLIBCXX_USE_C99_MATH_TR1 1 + +/* Define if C99 types in should be imported in in + namespace std::tr1. */ +#define _GLIBCXX_USE_C99_STDINT_TR1 1 + +/* Defined if clock_gettime syscall has monotonic and realtime clock support. + */ +/* #undef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL */ + +/* Defined if clock_gettime has monotonic clock support. */ +#define _GLIBCXX_USE_CLOCK_MONOTONIC 1 + +/* Defined if clock_gettime has realtime clock support. */ +#define _GLIBCXX_USE_CLOCK_REALTIME 1 + +/* Define if ISO/IEC TR 24733 decimal floating point types are supported on + this host. */ +/* #undef _GLIBCXX_USE_DECIMAL_FLOAT */ + +/* Define if __float128 is supported on this host. + Hide all uses of __float128 from Clang. Google ref b/6422845 */ +#ifndef __clang__ +/* #undef _GLIBCXX_USE_FLOAT128 */ +#endif + +/* Defined if gettimeofday is available. */ +#define _GLIBCXX_USE_GETTIMEOFDAY 1 + +/* Define if get_nprocs is available in . */ +/* #undef _GLIBCXX_USE_GET_NPROCS */ + +/* Define if __int128 is supported on this host. */ +#define _GLIBCXX_USE_INT128 1 + +/* Define if LFS support is available. */ +/* #undef _GLIBCXX_USE_LFS */ + +/* Define if code specialized for long long should be used. */ +#define _GLIBCXX_USE_LONG_LONG 1 + +/* Defined if nanosleep is available. */ +#define _GLIBCXX_USE_NANOSLEEP 1 + +/* Define if NLS translations are to be used. */ +/* #undef _GLIBCXX_USE_NLS */ + +/* Define if pthreads_num_processors_np is available in . */ +/* #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP */ + +/* Define if /dev/random and /dev/urandom are available for the random_device + of TR1 (Chapter 5.1). */ +#define _GLIBCXX_USE_RANDOM_TR1 1 + +/* Defined if sched_yield is available. */ +#define _GLIBCXX_USE_SCHED_YIELD 1 + +/* Define if _SC_NPROCESSORS_ONLN is available in . */ +#define _GLIBCXX_USE_SC_NPROCESSORS_ONLN 1 + +/* Define if _SC_NPROC_ONLN is available in . */ +/* #undef _GLIBCXX_USE_SC_NPROC_ONLN */ + +/* Define if sysctl(), CTL_HW and HW_NCPU are available in . */ +/* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ + +/* Define if obsolescent tmpnam is available in . */ +#define _GLIBCXX_USE_TMPNAM 1 + +/* Define if code specialized for wchar_t should be used. */ +#define _GLIBCXX_USE_WCHAR_T 1 + +/* Define to 1 if a verbose library is built, or 0 otherwise. */ +#define _GLIBCXX_VERBOSE 1 + +/* Defined if as can handle rdrand. + Disable when building with Clang. Google ref b/8680429 */ +#ifndef __clang__ +/* #undef _GLIBCXX_X86_RDRAND */ +#endif + +/* Define to 1 if mutex_timedlock is available. */ +#define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 + +#if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) +# define _GLIBCXX_HAVE_ACOSF 1 +# define acosf _acosf +#endif + +#if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) +# define _GLIBCXX_HAVE_ACOSL 1 +# define acosl _acosl +#endif + +#if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) +# define _GLIBCXX_HAVE_ASINF 1 +# define asinf _asinf +#endif + +#if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) +# define _GLIBCXX_HAVE_ASINL 1 +# define asinl _asinl +#endif + +#if defined (_GLIBCXX_HAVE__ATAN2F) && ! defined (_GLIBCXX_HAVE_ATAN2F) +# define _GLIBCXX_HAVE_ATAN2F 1 +# define atan2f _atan2f +#endif + +#if defined (_GLIBCXX_HAVE__ATAN2L) && ! defined (_GLIBCXX_HAVE_ATAN2L) +# define _GLIBCXX_HAVE_ATAN2L 1 +# define atan2l _atan2l +#endif + +#if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) +# define _GLIBCXX_HAVE_ATANF 1 +# define atanf _atanf +#endif + +#if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) +# define _GLIBCXX_HAVE_ATANL 1 +# define atanl _atanl +#endif + +#if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) +# define _GLIBCXX_HAVE_CEILF 1 +# define ceilf _ceilf +#endif + +#if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) +# define _GLIBCXX_HAVE_CEILL 1 +# define ceill _ceill +#endif + +#if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) +# define _GLIBCXX_HAVE_COSF 1 +# define cosf _cosf +#endif + +#if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) +# define _GLIBCXX_HAVE_COSHF 1 +# define coshf _coshf +#endif + +#if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) +# define _GLIBCXX_HAVE_COSHL 1 +# define coshl _coshl +#endif + +#if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) +# define _GLIBCXX_HAVE_COSL 1 +# define cosl _cosl +#endif + +#if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) +# define _GLIBCXX_HAVE_EXPF 1 +# define expf _expf +#endif + +#if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) +# define _GLIBCXX_HAVE_EXPL 1 +# define expl _expl +#endif + +#if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) +# define _GLIBCXX_HAVE_FABSF 1 +# define fabsf _fabsf +#endif + +#if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) +# define _GLIBCXX_HAVE_FABSL 1 +# define fabsl _fabsl +#endif + +#if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) +# define _GLIBCXX_HAVE_FINITE 1 +# define finite _finite +#endif + +#if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) +# define _GLIBCXX_HAVE_FINITEF 1 +# define finitef _finitef +#endif + +#if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) +# define _GLIBCXX_HAVE_FINITEL 1 +# define finitel _finitel +#endif + +#if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) +# define _GLIBCXX_HAVE_FLOORF 1 +# define floorf _floorf +#endif + +#if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) +# define _GLIBCXX_HAVE_FLOORL 1 +# define floorl _floorl +#endif + +#if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) +# define _GLIBCXX_HAVE_FMODF 1 +# define fmodf _fmodf +#endif + +#if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) +# define _GLIBCXX_HAVE_FMODL 1 +# define fmodl _fmodl +#endif + +#if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) +# define _GLIBCXX_HAVE_FPCLASS 1 +# define fpclass _fpclass +#endif + +#if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) +# define _GLIBCXX_HAVE_FREXPF 1 +# define frexpf _frexpf +#endif + +#if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) +# define _GLIBCXX_HAVE_FREXPL 1 +# define frexpl _frexpl +#endif + +#if defined (_GLIBCXX_HAVE__HYPOT) && ! defined (_GLIBCXX_HAVE_HYPOT) +# define _GLIBCXX_HAVE_HYPOT 1 +# define hypot _hypot +#endif + +#if defined (_GLIBCXX_HAVE__HYPOTF) && ! defined (_GLIBCXX_HAVE_HYPOTF) +# define _GLIBCXX_HAVE_HYPOTF 1 +# define hypotf _hypotf +#endif + +#if defined (_GLIBCXX_HAVE__HYPOTL) && ! defined (_GLIBCXX_HAVE_HYPOTL) +# define _GLIBCXX_HAVE_HYPOTL 1 +# define hypotl _hypotl +#endif + +#if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) +# define _GLIBCXX_HAVE_ISINF 1 +# define isinf _isinf +#endif + +#if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) +# define _GLIBCXX_HAVE_ISINFF 1 +# define isinff _isinff +#endif + +#if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) +# define _GLIBCXX_HAVE_ISINFL 1 +# define isinfl _isinfl +#endif + +#if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) +# define _GLIBCXX_HAVE_ISNAN 1 +# define isnan _isnan +#endif + +#if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) +# define _GLIBCXX_HAVE_ISNANF 1 +# define isnanf _isnanf +#endif + +#if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) +# define _GLIBCXX_HAVE_ISNANL 1 +# define isnanl _isnanl +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) +# define _GLIBCXX_HAVE_LDEXPF 1 +# define ldexpf _ldexpf +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) +# define _GLIBCXX_HAVE_LDEXPL 1 +# define ldexpl _ldexpl +#endif + +#if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) +# define _GLIBCXX_HAVE_LOG10F 1 +# define log10f _log10f +#endif + +#if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) +# define _GLIBCXX_HAVE_LOG10L 1 +# define log10l _log10l +#endif + +#if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) +# define _GLIBCXX_HAVE_LOGF 1 +# define logf _logf +#endif + +#if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) +# define _GLIBCXX_HAVE_LOGL 1 +# define logl _logl +#endif + +#if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) +# define _GLIBCXX_HAVE_MODF 1 +# define modf _modf +#endif + +#if defined (_GLIBCXX_HAVE__MODFF) && ! defined (_GLIBCXX_HAVE_MODFF) +# define _GLIBCXX_HAVE_MODFF 1 +# define modff _modff +#endif + +#if defined (_GLIBCXX_HAVE__MODFL) && ! defined (_GLIBCXX_HAVE_MODFL) +# define _GLIBCXX_HAVE_MODFL 1 +# define modfl _modfl +#endif + +#if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) +# define _GLIBCXX_HAVE_POWF 1 +# define powf _powf +#endif + +#if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) +# define _GLIBCXX_HAVE_POWL 1 +# define powl _powl +#endif + +#if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) +# define _GLIBCXX_HAVE_QFPCLASS 1 +# define qfpclass _qfpclass +#endif + +#if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) +# define _GLIBCXX_HAVE_SINCOS 1 +# define sincos _sincos +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) +# define _GLIBCXX_HAVE_SINCOSF 1 +# define sincosf _sincosf +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) +# define _GLIBCXX_HAVE_SINCOSL 1 +# define sincosl _sincosl +#endif + +#if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) +# define _GLIBCXX_HAVE_SINF 1 +# define sinf _sinf +#endif + +#if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) +# define _GLIBCXX_HAVE_SINHF 1 +# define sinhf _sinhf +#endif + +#if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) +# define _GLIBCXX_HAVE_SINHL 1 +# define sinhl _sinhl +#endif + +#if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) +# define _GLIBCXX_HAVE_SINL 1 +# define sinl _sinl +#endif + +#if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) +# define _GLIBCXX_HAVE_SQRTF 1 +# define sqrtf _sqrtf +#endif + +#if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) +# define _GLIBCXX_HAVE_SQRTL 1 +# define sqrtl _sqrtl +#endif + +#if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) +# define _GLIBCXX_HAVE_STRTOF 1 +# define strtof _strtof +#endif + +#if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) +# define _GLIBCXX_HAVE_STRTOLD 1 +# define strtold _strtold +#endif + +#if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) +# define _GLIBCXX_HAVE_TANF 1 +# define tanf _tanf +#endif + +#if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) +# define _GLIBCXX_HAVE_TANHF 1 +# define tanhf _tanhf +#endif + +#if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) +# define _GLIBCXX_HAVE_TANHL 1 +# define tanhl _tanhl +#endif + +#if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) +# define _GLIBCXX_HAVE_TANL 1 +# define tanl _tanl +#endif + +#endif // _GLIBCXX_CXX_CONFIG_H diff --git a/loader/include/Geode/c++stl/gnustl/c++config-armeabi-v7a.h b/loader/include/Geode/c++stl/gnustl/c++config-armeabi-v7a.h new file mode 100644 index 00000000..5c2da1b9 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/c++config-armeabi-v7a.h @@ -0,0 +1,1680 @@ +// Predefined symbols and macros -*- C++ -*- + +// Copyright (C) 1997-2014 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 +// . + +/** @file bits/c++config.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{iosfwd} + */ + +#ifndef _GLIBCXX_CXX_CONFIG_H +#define _GLIBCXX_CXX_CONFIG_H 1 + +// The current version of the C++ library in compressed ISO date format. +#define __GLIBCXX__ 20150123 + +// Macros for various attributes. +// _GLIBCXX_PURE +// _GLIBCXX_CONST +// _GLIBCXX_NORETURN +// _GLIBCXX_NOTHROW +// _GLIBCXX_VISIBILITY +#ifndef _GLIBCXX_PURE +# define _GLIBCXX_PURE __attribute__ ((__pure__)) +#endif + +#ifndef _GLIBCXX_CONST +# define _GLIBCXX_CONST __attribute__ ((__const__)) +#endif + +#ifndef _GLIBCXX_NORETURN +# define _GLIBCXX_NORETURN __attribute__ ((__noreturn__)) +#endif + +// See below for C++ +#ifndef _GLIBCXX_NOTHROW +# ifndef __cplusplus +# define _GLIBCXX_NOTHROW __attribute__((__nothrow__)) +# endif +#endif + +// Macros for visibility attributes. +// _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +// _GLIBCXX_VISIBILITY +# define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 + +#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY +# define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) +#else +// If this is not supplied by the OS-specific or CPU-specific +// headers included below, it will be defined to an empty default. +# define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) +#endif + +// Macros for deprecated attributes. +// _GLIBCXX_USE_DEPRECATED +// _GLIBCXX_DEPRECATED +#ifndef _GLIBCXX_USE_DEPRECATED +# define _GLIBCXX_USE_DEPRECATED 1 +#endif + +#if defined(__DEPRECATED) && (__cplusplus >= 201103L) +# define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) +#else +# define _GLIBCXX_DEPRECATED +#endif + +// Macros for ABI tag attributes. +#ifndef _GLIBCXX_ABI_TAG_CXX11 +# define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) +#endif + + +#if __cplusplus + +// Macro for constexpr, to support in mixed 03/0x mode. +#ifndef _GLIBCXX_CONSTEXPR +# if __cplusplus >= 201103L +# define _GLIBCXX_CONSTEXPR constexpr +# define _GLIBCXX_USE_CONSTEXPR constexpr +# else +# define _GLIBCXX_CONSTEXPR +# define _GLIBCXX_USE_CONSTEXPR const +# endif +#endif + +// Macro for noexcept, to support in mixed 03/0x mode. +#ifndef _GLIBCXX_NOEXCEPT +# if __cplusplus >= 201103L +# define _GLIBCXX_NOEXCEPT noexcept +# define _GLIBCXX_USE_NOEXCEPT noexcept +# define _GLIBCXX_THROW(_EXC) +# else +# define _GLIBCXX_NOEXCEPT +# define _GLIBCXX_USE_NOEXCEPT throw() +# define _GLIBCXX_THROW(_EXC) throw(_EXC) +# endif +#endif + +#ifndef _GLIBCXX_NOTHROW +# define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT +#endif + +#ifndef _GLIBCXX_THROW_OR_ABORT +# if __EXCEPTIONS +# define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC)) +# else +# define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort()) +# endif +#endif + +// Macro for extern template, ie controling template linkage via use +// of extern keyword on template declaration. As documented in the g++ +// manual, it inhibits all implicit instantiations and is used +// throughout the library to avoid multiple weak definitions for +// required types that are already explicitly instantiated in the +// library binary. This substantially reduces the binary size of +// resulting executables. +// Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern +// templates only in basic_string, thus activating its debug-mode +// checks even at -O0. +# define _GLIBCXX_EXTERN_TEMPLATE 1 + +/* + Outline of libstdc++ namespaces. + + namespace std + { + namespace __debug { } + namespace __parallel { } + namespace __profile { } + namespace __cxx1998 { } + + namespace __detail { } + + namespace rel_ops { } + + namespace tr1 + { + namespace placeholders { } + namespace regex_constants { } + namespace __detail { } + } + + namespace tr2 { } + + namespace decimal { } + + namespace chrono { } + namespace placeholders { } + namespace regex_constants { } + namespace this_thread { } + + namespace experimental { } + } + + namespace abi { } + + namespace __gnu_cxx + { + namespace __detail { } + } + + For full details see: + http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html +*/ +namespace std +{ + typedef __SIZE_TYPE__ size_t; + typedef __PTRDIFF_TYPE__ ptrdiff_t; + +#if __cplusplus >= 201103L + typedef decltype(nullptr) nullptr_t; +#endif +} + + +// Defined if inline namespaces are used for versioning. +# define _GLIBCXX_INLINE_VERSION 0 + +// Inline namespace for symbol versioning. +#if _GLIBCXX_INLINE_VERSION + +namespace std +{ + inline namespace __7 { } + + namespace rel_ops { inline namespace __7 { } } + + namespace tr1 + { + inline namespace __7 { } + namespace placeholders { inline namespace __7 { } } + namespace regex_constants { inline namespace __7 { } } + namespace __detail { inline namespace __7 { } } + } + + namespace tr2 + { inline namespace __7 { } } + + namespace decimal { inline namespace __7 { } } + + namespace chrono { inline namespace __7 { } } + namespace placeholders { inline namespace __7 { } } + namespace regex_constants { inline namespace __7 { } } + namespace this_thread { inline namespace __7 { } } + + namespace experimental { inline namespace __7 { } } + + namespace __detail { inline namespace __7 { } } +} + +namespace __gnu_cxx +{ + inline namespace __7 { } + namespace __detail { inline namespace __7 { } } +} +# define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 { +# define _GLIBCXX_END_NAMESPACE_VERSION } +#else +# define _GLIBCXX_BEGIN_NAMESPACE_VERSION +# define _GLIBCXX_END_NAMESPACE_VERSION +#endif + + +// Inline namespaces for special modes: debug, parallel, profile. +#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \ + || defined(_GLIBCXX_PROFILE) +namespace std +{ + // Non-inline namespace for components replaced by alternates in active mode. + namespace __cxx1998 + { +#if _GLIBCXX_INLINE_VERSION + inline namespace __7 { } +#endif + } + + // Inline namespace for debug mode. +# ifdef _GLIBCXX_DEBUG + inline namespace __debug { } +# endif + + // Inline namespaces for parallel mode. +# ifdef _GLIBCXX_PARALLEL + inline namespace __parallel { } +# endif + + // Inline namespaces for profile mode +# ifdef _GLIBCXX_PROFILE + inline namespace __profile { } +# endif +} + +// Check for invalid usage and unsupported mixed-mode use. +# if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL) +# error illegal use of multiple inlined namespaces +# endif +# if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG) +# error illegal use of multiple inlined namespaces +# endif +# if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL) +# error illegal use of multiple inlined namespaces +# endif + +// Check for invalid use due to lack for weak symbols. +# if __NO_INLINE__ && !__GXX_WEAK__ +# warning currently using inlined namespace mode which may fail \ + without inlining due to lack of weak symbols +# endif +#endif + +// Macros for namespace scope. Either namespace std:: or the name +// of some nested namespace within it corresponding to the active mode. +// _GLIBCXX_STD_A +// _GLIBCXX_STD_C +// +// Macros for opening/closing conditional namespaces. +// _GLIBCXX_BEGIN_NAMESPACE_ALGO +// _GLIBCXX_END_NAMESPACE_ALGO +// _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +// _GLIBCXX_END_NAMESPACE_CONTAINER +#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) +# define _GLIBCXX_STD_C __cxx1998 +# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ + namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION +# define _GLIBCXX_END_NAMESPACE_CONTAINER \ + _GLIBCXX_END_NAMESPACE_VERSION } +# undef _GLIBCXX_EXTERN_TEMPLATE +# define _GLIBCXX_EXTERN_TEMPLATE -1 +#endif + +#ifdef _GLIBCXX_PARALLEL +# define _GLIBCXX_STD_A __cxx1998 +# define _GLIBCXX_BEGIN_NAMESPACE_ALGO \ + namespace _GLIBCXX_STD_A { _GLIBCXX_BEGIN_NAMESPACE_VERSION +# define _GLIBCXX_END_NAMESPACE_ALGO \ + _GLIBCXX_END_NAMESPACE_VERSION } +#endif + +#ifndef _GLIBCXX_STD_A +# define _GLIBCXX_STD_A std +#endif + +#ifndef _GLIBCXX_STD_C +# define _GLIBCXX_STD_C std +#endif + +#ifndef _GLIBCXX_BEGIN_NAMESPACE_ALGO +# define _GLIBCXX_BEGIN_NAMESPACE_ALGO +#endif + +#ifndef _GLIBCXX_END_NAMESPACE_ALGO +# define _GLIBCXX_END_NAMESPACE_ALGO +#endif + +#ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER +#endif + +#ifndef _GLIBCXX_END_NAMESPACE_CONTAINER +# define _GLIBCXX_END_NAMESPACE_CONTAINER +#endif + +// GLIBCXX_ABI Deprecated +// Define if compatibility should be provided for -mlong-double-64. +#undef _GLIBCXX_LONG_DOUBLE_COMPAT + +// Inline namespace for long double 128 mode. +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +namespace std +{ + inline namespace __gnu_cxx_ldbl128 { } +} +# define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128:: +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 { +# define _GLIBCXX_END_NAMESPACE_LDBL } +#else +# define _GLIBCXX_NAMESPACE_LDBL +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL +# define _GLIBCXX_END_NAMESPACE_LDBL +#endif + +// Assert. +#if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PARALLEL) +# define __glibcxx_assert(_Condition) +#else +namespace std +{ + // Avoid the use of assert, because we're trying to keep the + // include out of the mix. + inline void + __replacement_assert(const char* __file, int __line, + const char* __function, const char* __condition) + { + __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, + __function, __condition); + __builtin_abort(); + } +} +#define __glibcxx_assert(_Condition) \ + do \ + { \ + if (! (_Condition)) \ + std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } while (false) +#endif + +// Macros for race detectors. +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain +// atomic (lock-free) synchronization to race detectors: +// the race detector will infer a happens-before arc from the former to the +// latter when they share the same argument pointer. +// +// The most frequent use case for these macros (and the only case in the +// current implementation of the library) is atomic reference counting: +// void _M_remove_reference() +// { +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); +// if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) +// { +// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); +// _M_destroy(__a); +// } +// } +// The annotations in this example tell the race detector that all memory +// accesses occurred when the refcount was positive do not race with +// memory accesses which occurred after the refcount became zero. +#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE +# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) +#endif +#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER +# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) +#endif + +// Macros for C linkage: define extern "C" linkage only when using C++. +# define _GLIBCXX_BEGIN_EXTERN_C extern "C" { +# define _GLIBCXX_END_EXTERN_C } + +#else // !__cplusplus +# define _GLIBCXX_BEGIN_EXTERN_C +# define _GLIBCXX_END_EXTERN_C +#endif + + +// First includes. + +// Pick up any OS-specific definitions. +// #include "os_defines.h" // dank: Empty on this arch + +// Pick up any CPU-specific definitions. +// #include "cpu_defines.h" // dank: Empty on this arch + +// If platform uses neither visibility nor psuedo-visibility, +// specify empty default for namespace annotation macros. +#ifndef _GLIBCXX_PSEUDO_VISIBILITY +# define _GLIBCXX_PSEUDO_VISIBILITY(V) +#endif + +// Certain function definitions that are meant to be overridable from +// user code are decorated with this macro. For some targets, this +// macro causes these definitions to be weak. +#ifndef _GLIBCXX_WEAK_DEFINITION +# define _GLIBCXX_WEAK_DEFINITION +#endif + + +// The remainder of the prewritten config is automatic; all the +// user hooks are listed above. + +// Create a boolean flag to be used to determine if --fast-math is set. +#ifdef __FAST_MATH__ +# define _GLIBCXX_FAST_MATH 1 +#else +# define _GLIBCXX_FAST_MATH 0 +#endif + +// This marks string literals in header files to be extracted for eventual +// translation. It is primarily used for messages in thrown exceptions; see +// src/functexcept.cc. We use __N because the more traditional _N is used +// for something else under certain OSes (see BADNAMES). +#define __N(msgid) (msgid) + +// For example, is known to #define min and max as macros... +#undef min +#undef max + +// End of prewritten config; the settings discovered at configure time follow. +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `acosf' function. */ +#define _GLIBCXX_HAVE_ACOSF 1 + +/* Define to 1 if you have the `acosl' function. */ +/* #undef _GLIBCXX_HAVE_ACOSL */ + +/* Define to 1 if you have the `asinf' function. */ +#define _GLIBCXX_HAVE_ASINF 1 + +/* Define to 1 if you have the `asinl' function. */ +/* #undef _GLIBCXX_HAVE_ASINL */ + +/* Define to 1 if the target assembler supports .symver directive. */ +#define _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE 1 + +/* Define to 1 if you have the `atan2f' function. */ +#define _GLIBCXX_HAVE_ATAN2F 1 + +/* Define to 1 if you have the `atan2l' function. */ +/* #undef _GLIBCXX_HAVE_ATAN2L */ + +/* Define to 1 if you have the `atanf' function. */ +#define _GLIBCXX_HAVE_ATANF 1 + +/* Define to 1 if you have the `atanl' function. */ +/* #undef _GLIBCXX_HAVE_ATANL */ + +/* Define to 1 if you have the `at_quick_exit' function. */ +/* #undef _GLIBCXX_HAVE_AT_QUICK_EXIT */ + +/* Define to 1 if the target assembler supports thread-local storage. */ +/* #undef _GLIBCXX_HAVE_CC_TLS */ + +/* Define to 1 if you have the `ceilf' function. */ +#define _GLIBCXX_HAVE_CEILF 1 + +/* Define to 1 if you have the `ceill' function. */ +#define _GLIBCXX_HAVE_CEILL 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_COMPLEX_H */ + +/* Define to 1 if you have the `cosf' function. */ +#define _GLIBCXX_HAVE_COSF 1 + +/* Define to 1 if you have the `coshf' function. */ +#define _GLIBCXX_HAVE_COSHF 1 + +/* Define to 1 if you have the `coshl' function. */ +/* #undef _GLIBCXX_HAVE_COSHL */ + +/* Define to 1 if you have the `cosl' function. */ +/* #undef _GLIBCXX_HAVE_COSL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_DLFCN_H 1 + +/* Define if EBADMSG exists. */ +#define _GLIBCXX_HAVE_EBADMSG 1 + +/* Define if ECANCELED exists. */ +#define _GLIBCXX_HAVE_ECANCELED 1 + +/* Define if ECHILD exists. */ +#define _GLIBCXX_HAVE_ECHILD 1 + +/* Define if EIDRM exists. */ +#define _GLIBCXX_HAVE_EIDRM 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_ENDIAN_H 1 + +/* Define if ENODATA exists. */ +#define _GLIBCXX_HAVE_ENODATA 1 + +/* Define if ENOLINK exists. */ +#define _GLIBCXX_HAVE_ENOLINK 1 + +/* Define if ENOSPC exists. */ +#define _GLIBCXX_HAVE_ENOSPC 1 + +/* Define if ENOSR exists. */ +#define _GLIBCXX_HAVE_ENOSR 1 + +/* Define if ENOSTR exists. */ +#define _GLIBCXX_HAVE_ENOSTR 1 + +/* Define if ENOTRECOVERABLE exists. */ +#define _GLIBCXX_HAVE_ENOTRECOVERABLE 1 + +/* Define if ENOTSUP exists. */ +#define _GLIBCXX_HAVE_ENOTSUP 1 + +/* Define if EOVERFLOW exists. */ +#define _GLIBCXX_HAVE_EOVERFLOW 1 + +/* Define if EOWNERDEAD exists. */ +#define _GLIBCXX_HAVE_EOWNERDEAD 1 + +/* Define if EPERM exists. */ +#define _GLIBCXX_HAVE_EPERM 1 + +/* Define if EPROTO exists. */ +#define _GLIBCXX_HAVE_EPROTO 1 + +/* Define if ETIME exists. */ +#define _GLIBCXX_HAVE_ETIME 1 + +/* Define if ETIMEDOUT exists. */ +#define _GLIBCXX_HAVE_ETIMEDOUT 1 + +/* Define if ETXTBSY exists. */ +#define _GLIBCXX_HAVE_ETXTBSY 1 + +/* Define if EWOULDBLOCK exists. */ +#define _GLIBCXX_HAVE_EWOULDBLOCK 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_EXECINFO_H */ + +/* Define to 1 if you have the `expf' function. */ +#define _GLIBCXX_HAVE_EXPF 1 + +/* Define to 1 if you have the `expl' function. */ +/* #undef _GLIBCXX_HAVE_EXPL */ + +/* Define to 1 if you have the `fabsf' function. */ +#define _GLIBCXX_HAVE_FABSF 1 + +/* Define to 1 if you have the `fabsl' function. */ +#define _GLIBCXX_HAVE_FABSL 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_FENV_H 1 + +/* Define to 1 if you have the `finite' function. */ +#define _GLIBCXX_HAVE_FINITE 1 + +/* Define to 1 if you have the `finitef' function. */ +#define _GLIBCXX_HAVE_FINITEF 1 + +/* Define to 1 if you have the `finitel' function. */ +/* #undef _GLIBCXX_HAVE_FINITEL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_FLOAT_H 1 + +/* Define to 1 if you have the `floorf' function. */ +#define _GLIBCXX_HAVE_FLOORF 1 + +/* Define to 1 if you have the `floorl' function. */ +#define _GLIBCXX_HAVE_FLOORL 1 + +/* Define to 1 if you have the `fmodf' function. */ +#define _GLIBCXX_HAVE_FMODF 1 + +/* Define to 1 if you have the `fmodl' function. */ +/* #undef _GLIBCXX_HAVE_FMODL */ + +/* Define to 1 if you have the `fpclass' function. */ +/* #undef _GLIBCXX_HAVE_FPCLASS */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_FP_H */ + +/* Define to 1 if you have the `frexpf' function. */ +#define _GLIBCXX_HAVE_FREXPF 1 + +/* Define to 1 if you have the `frexpl' function. */ +/* #undef _GLIBCXX_HAVE_FREXPL */ + +/* Define if _Unwind_GetIPInfo is available. */ +#define _GLIBCXX_HAVE_GETIPINFO 1 + +/* Define if gets is available in . */ +#define _GLIBCXX_HAVE_GETS 1 + +/* Define to 1 if you have the `hypot' function. */ +#define _GLIBCXX_HAVE_HYPOT 1 + +/* Define to 1 if you have the `hypotf' function. */ +#define _GLIBCXX_HAVE_HYPOTF 1 + +/* Define to 1 if you have the `hypotl' function. */ +/* #undef _GLIBCXX_HAVE_HYPOTL */ + +/* Define if you have the iconv() function. */ +/* #undef _GLIBCXX_HAVE_ICONV */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_IEEEFP_H */ + +/* Define if int64_t is available in . */ +#define _GLIBCXX_HAVE_INT64_T 1 + +/* Define if int64_t is a long. */ +/* #undef _GLIBCXX_HAVE_INT64_T_LONG */ + +/* Define if int64_t is a long long. */ +#define _GLIBCXX_HAVE_INT64_T_LONG_LONG 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isinf' function. */ +/* #undef _GLIBCXX_HAVE_ISINF */ + +/* Define to 1 if you have the `isinff' function. */ +/* #undef _GLIBCXX_HAVE_ISINFF */ + +/* Define to 1 if you have the `isinfl' function. */ +/* #undef _GLIBCXX_HAVE_ISINFL */ + +/* Define to 1 if you have the `isnan' function. */ +#define _GLIBCXX_HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +#define _GLIBCXX_HAVE_ISNANF 1 + +/* Define to 1 if you have the `isnanl' function. */ +/* #undef _GLIBCXX_HAVE_ISNANL */ + +/* Defined if iswblank exists. */ +/* #undef _GLIBCXX_HAVE_ISWBLANK */ + +/* Define if LC_MESSAGES is available in . */ +#define _GLIBCXX_HAVE_LC_MESSAGES 1 + +/* Define to 1 if you have the `ldexpf' function. */ +#define _GLIBCXX_HAVE_LDEXPF 1 + +/* Define to 1 if you have the `ldexpl' function. */ +#define _GLIBCXX_HAVE_LDEXPL 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_LIBINTL_H */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_AS */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_DATA */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_FSIZE */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_RSS */ + +/* Only used in build directory testsuite_hooks.h. */ +/* #undef _GLIBCXX_HAVE_LIMIT_VMEM */ + +/* Define if futex syscall is available. */ +#define _GLIBCXX_HAVE_LINUX_FUTEX 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `log10f' function. */ +#define _GLIBCXX_HAVE_LOG10F 1 + +/* Define to 1 if you have the `log10l' function. */ +/* #undef _GLIBCXX_HAVE_LOG10L */ + +/* Define to 1 if you have the `logf' function. */ +#define _GLIBCXX_HAVE_LOGF 1 + +/* Define to 1 if you have the `logl' function. */ +/* #undef _GLIBCXX_HAVE_LOGL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MACHINE_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_MACHINE_PARAM_H */ + +/* Define if mbstate_t exists in wchar.h. */ +#define _GLIBCXX_HAVE_MBSTATE_T 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `modf' function. */ +#define _GLIBCXX_HAVE_MODF 1 + +/* Define to 1 if you have the `modff' function. */ +#define _GLIBCXX_HAVE_MODFF 1 + +/* Define to 1 if you have the `modfl' function. */ +/* #undef _GLIBCXX_HAVE_MODFL */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_NAN_H */ + +/* Define if poll is available in . */ +#define _GLIBCXX_HAVE_POLL 1 + +/* Define to 1 if you have the `powf' function. */ +#define _GLIBCXX_HAVE_POWF 1 + +/* Define to 1 if you have the `powl' function. */ +/* #undef _GLIBCXX_HAVE_POWL */ + +/* Define to 1 if you have the `qfpclass' function. */ +/* #undef _GLIBCXX_HAVE_QFPCLASS */ + +/* Define to 1 if you have the `quick_exit' function. */ +/* #undef _GLIBCXX_HAVE_QUICK_EXIT */ + +/* Define to 1 if you have the `setenv' function. */ +/* #undef _GLIBCXX_HAVE_SETENV */ + +/* Define to 1 if you have the `sincos' function. */ +#define _GLIBCXX_HAVE_SINCOS 1 + +/* Define to 1 if you have the `sincosf' function. */ +#define _GLIBCXX_HAVE_SINCOSF 1 + +/* Define to 1 if you have the `sincosl' function. */ +#define _GLIBCXX_HAVE_SINCOSL 1 + +/* Define to 1 if you have the `sinf' function. */ +#define _GLIBCXX_HAVE_SINF 1 + +/* Define to 1 if you have the `sinhf' function. */ +#define _GLIBCXX_HAVE_SINHF 1 + +/* Define to 1 if you have the `sinhl' function. */ +/* #undef _GLIBCXX_HAVE_SINHL */ + +/* Define to 1 if you have the `sinl' function. */ +/* #undef _GLIBCXX_HAVE_SINL */ + +/* Defined if sleep exists. */ +/* #undef _GLIBCXX_HAVE_SLEEP */ + +/* Define to 1 if you have the `sqrtf' function. */ +#define _GLIBCXX_HAVE_SQRTF 1 + +/* Define to 1 if you have the `sqrtl' function. */ +/* #undef _GLIBCXX_HAVE_SQRTL */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDALIGN_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STDLIB_H 1 + +/* Define if strerror_l is available in . */ +/* #undef _GLIBCXX_HAVE_STRERROR_L */ + +/* Define if strerror_r is available in . */ +#define _GLIBCXX_HAVE_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtof' function. */ +/* #undef _GLIBCXX_HAVE_STRTOF */ + +/* Define to 1 if you have the `strtold' function. */ +/* #undef _GLIBCXX_HAVE_STRTOLD */ + +/* Define if strxfrm_l is available in . */ +/* #undef _GLIBCXX_HAVE_STRXFRM_L */ + +/* Define to 1 if the target runtime linker supports binding the same symbol + to different versions. */ +/* #undef _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_FILIO_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_IPC_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have a suitable header file */ +/* #undef _GLIBCXX_HAVE_SYS_SDT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_SYS_SEM_H */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_SYSINFO_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_SYS_UIO_H 1 + +/* Define if S_IFREG is available in . */ +/* #undef _GLIBCXX_HAVE_S_IFREG */ + +/* Define if S_IFREG is available in . */ +#define _GLIBCXX_HAVE_S_ISREG 1 + +/* Define to 1 if you have the `tanf' function. */ +#define _GLIBCXX_HAVE_TANF 1 + +/* Define to 1 if you have the `tanhf' function. */ +#define _GLIBCXX_HAVE_TANHF 1 + +/* Define to 1 if you have the `tanhl' function. */ +/* #undef _GLIBCXX_HAVE_TANHL */ + +/* Define to 1 if you have the `tanl' function. */ +/* #undef _GLIBCXX_HAVE_TANL */ + +/* Define to 1 if you have the header file. */ +/* #undef _GLIBCXX_HAVE_TGMATH_H */ + +/* Define to 1 if the target supports thread-local storage. */ +/* #undef _GLIBCXX_HAVE_TLS */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_UNISTD_H 1 + +/* Defined if usleep exists. */ +/* #undef _GLIBCXX_HAVE_USLEEP */ + +/* Defined if vfwscanf exists. */ +/* #undef _GLIBCXX_HAVE_VFWSCANF */ + +/* Defined if vswscanf exists. */ +/* #undef _GLIBCXX_HAVE_VSWSCANF */ + +/* Defined if vwscanf exists. */ +/* #undef _GLIBCXX_HAVE_VWSCANF */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCHAR_H 1 + +/* Defined if wcstof exists. */ +/* #undef _GLIBCXX_HAVE_WCSTOF */ + +/* Define to 1 if you have the header file. */ +#define _GLIBCXX_HAVE_WCTYPE_H 1 + +/* Defined if Sleep exists. */ +/* #undef _GLIBCXX_HAVE_WIN32_SLEEP */ + +/* Define if writev is available in . */ +#define _GLIBCXX_HAVE_WRITEV 1 + +/* Define to 1 if you have the `_acosf' function. */ +/* #undef _GLIBCXX_HAVE__ACOSF */ + +/* Define to 1 if you have the `_acosl' function. */ +/* #undef _GLIBCXX_HAVE__ACOSL */ + +/* Define to 1 if you have the `_asinf' function. */ +/* #undef _GLIBCXX_HAVE__ASINF */ + +/* Define to 1 if you have the `_asinl' function. */ +/* #undef _GLIBCXX_HAVE__ASINL */ + +/* Define to 1 if you have the `_atan2f' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2F */ + +/* Define to 1 if you have the `_atan2l' function. */ +/* #undef _GLIBCXX_HAVE__ATAN2L */ + +/* Define to 1 if you have the `_atanf' function. */ +/* #undef _GLIBCXX_HAVE__ATANF */ + +/* Define to 1 if you have the `_atanl' function. */ +/* #undef _GLIBCXX_HAVE__ATANL */ + +/* Define to 1 if you have the `_ceilf' function. */ +/* #undef _GLIBCXX_HAVE__CEILF */ + +/* Define to 1 if you have the `_ceill' function. */ +/* #undef _GLIBCXX_HAVE__CEILL */ + +/* Define to 1 if you have the `_cosf' function. */ +/* #undef _GLIBCXX_HAVE__COSF */ + +/* Define to 1 if you have the `_coshf' function. */ +/* #undef _GLIBCXX_HAVE__COSHF */ + +/* Define to 1 if you have the `_coshl' function. */ +/* #undef _GLIBCXX_HAVE__COSHL */ + +/* Define to 1 if you have the `_cosl' function. */ +/* #undef _GLIBCXX_HAVE__COSL */ + +/* Define to 1 if you have the `_expf' function. */ +/* #undef _GLIBCXX_HAVE__EXPF */ + +/* Define to 1 if you have the `_expl' function. */ +/* #undef _GLIBCXX_HAVE__EXPL */ + +/* Define to 1 if you have the `_fabsf' function. */ +/* #undef _GLIBCXX_HAVE__FABSF */ + +/* Define to 1 if you have the `_fabsl' function. */ +/* #undef _GLIBCXX_HAVE__FABSL */ + +/* Define to 1 if you have the `_finite' function. */ +/* #undef _GLIBCXX_HAVE__FINITE */ + +/* Define to 1 if you have the `_finitef' function. */ +/* #undef _GLIBCXX_HAVE__FINITEF */ + +/* Define to 1 if you have the `_finitel' function. */ +/* #undef _GLIBCXX_HAVE__FINITEL */ + +/* Define to 1 if you have the `_floorf' function. */ +/* #undef _GLIBCXX_HAVE__FLOORF */ + +/* Define to 1 if you have the `_floorl' function. */ +/* #undef _GLIBCXX_HAVE__FLOORL */ + +/* Define to 1 if you have the `_fmodf' function. */ +/* #undef _GLIBCXX_HAVE__FMODF */ + +/* Define to 1 if you have the `_fmodl' function. */ +/* #undef _GLIBCXX_HAVE__FMODL */ + +/* Define to 1 if you have the `_fpclass' function. */ +/* #undef _GLIBCXX_HAVE__FPCLASS */ + +/* Define to 1 if you have the `_frexpf' function. */ +/* #undef _GLIBCXX_HAVE__FREXPF */ + +/* Define to 1 if you have the `_frexpl' function. */ +/* #undef _GLIBCXX_HAVE__FREXPL */ + +/* Define to 1 if you have the `_hypot' function. */ +/* #undef _GLIBCXX_HAVE__HYPOT */ + +/* Define to 1 if you have the `_hypotf' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTF */ + +/* Define to 1 if you have the `_hypotl' function. */ +/* #undef _GLIBCXX_HAVE__HYPOTL */ + +/* Define to 1 if you have the `_isinf' function. */ +/* #undef _GLIBCXX_HAVE__ISINF */ + +/* Define to 1 if you have the `_isinff' function. */ +/* #undef _GLIBCXX_HAVE__ISINFF */ + +/* Define to 1 if you have the `_isinfl' function. */ +/* #undef _GLIBCXX_HAVE__ISINFL */ + +/* Define to 1 if you have the `_isnan' function. */ +/* #undef _GLIBCXX_HAVE__ISNAN */ + +/* Define to 1 if you have the `_isnanf' function. */ +/* #undef _GLIBCXX_HAVE__ISNANF */ + +/* Define to 1 if you have the `_isnanl' function. */ +/* #undef _GLIBCXX_HAVE__ISNANL */ + +/* Define to 1 if you have the `_ldexpf' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPF */ + +/* Define to 1 if you have the `_ldexpl' function. */ +/* #undef _GLIBCXX_HAVE__LDEXPL */ + +/* Define to 1 if you have the `_log10f' function. */ +/* #undef _GLIBCXX_HAVE__LOG10F */ + +/* Define to 1 if you have the `_log10l' function. */ +/* #undef _GLIBCXX_HAVE__LOG10L */ + +/* Define to 1 if you have the `_logf' function. */ +/* #undef _GLIBCXX_HAVE__LOGF */ + +/* Define to 1 if you have the `_logl' function. */ +/* #undef _GLIBCXX_HAVE__LOGL */ + +/* Define to 1 if you have the `_modf' function. */ +/* #undef _GLIBCXX_HAVE__MODF */ + +/* Define to 1 if you have the `_modff' function. */ +/* #undef _GLIBCXX_HAVE__MODFF */ + +/* Define to 1 if you have the `_modfl' function. */ +/* #undef _GLIBCXX_HAVE__MODFL */ + +/* Define to 1 if you have the `_powf' function. */ +/* #undef _GLIBCXX_HAVE__POWF */ + +/* Define to 1 if you have the `_powl' function. */ +/* #undef _GLIBCXX_HAVE__POWL */ + +/* Define to 1 if you have the `_qfpclass' function. */ +/* #undef _GLIBCXX_HAVE__QFPCLASS */ + +/* Define to 1 if you have the `_sincos' function. */ +/* #undef _GLIBCXX_HAVE__SINCOS */ + +/* Define to 1 if you have the `_sincosf' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSF */ + +/* Define to 1 if you have the `_sincosl' function. */ +/* #undef _GLIBCXX_HAVE__SINCOSL */ + +/* Define to 1 if you have the `_sinf' function. */ +/* #undef _GLIBCXX_HAVE__SINF */ + +/* Define to 1 if you have the `_sinhf' function. */ +/* #undef _GLIBCXX_HAVE__SINHF */ + +/* Define to 1 if you have the `_sinhl' function. */ +/* #undef _GLIBCXX_HAVE__SINHL */ + +/* Define to 1 if you have the `_sinl' function. */ +/* #undef _GLIBCXX_HAVE__SINL */ + +/* Define to 1 if you have the `_sqrtf' function. */ +/* #undef _GLIBCXX_HAVE__SQRTF */ + +/* Define to 1 if you have the `_sqrtl' function. */ +/* #undef _GLIBCXX_HAVE__SQRTL */ + +/* Define to 1 if you have the `_tanf' function. */ +/* #undef _GLIBCXX_HAVE__TANF */ + +/* Define to 1 if you have the `_tanhf' function. */ +/* #undef _GLIBCXX_HAVE__TANHF */ + +/* Define to 1 if you have the `_tanhl' function. */ +/* #undef _GLIBCXX_HAVE__TANHL */ + +/* Define to 1 if you have the `_tanl' function. */ +/* #undef _GLIBCXX_HAVE__TANL */ + +/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */ +/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */ + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef _GLIBCXX_ICONV_CONST */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +/* #undef _GLIBCXX_PACKAGE */ + +/* Define to the address where bug reports for this package should be sent. */ +#define _GLIBCXX_PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define _GLIBCXX_PACKAGE_NAME "package-unused" + +/* Define to the full name and version of this package. */ +#define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" + +/* Define to the one symbol short name of this package. */ +#define _GLIBCXX_PACKAGE_TARNAME "libstdc++" + +/* Define to the home page for this package. */ +#define _GLIBCXX_PACKAGE_URL "" + +/* Define to the version of this package. */ +#define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" + +/* The size of `char', as computed by sizeof. */ +/* #undef SIZEOF_CHAR */ + +/* The size of `int', as computed by sizeof. */ +/* #undef SIZEOF_INT */ + +/* The size of `long', as computed by sizeof. */ +/* #undef SIZEOF_LONG */ + +/* The size of `short', as computed by sizeof. */ +/* #undef SIZEOF_SHORT */ + +/* The size of `void *', as computed by sizeof. */ +/* #undef SIZEOF_VOID_P */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +/* #undef _GLIBCXX_VERSION */ + +/* Define if the compiler supports C++11 atomics. */ +#define _GLIBCXX_ATOMIC_BUILTINS 1 + +/* Define to use concept checking code from the boost libraries. */ +/* #undef _GLIBCXX_CONCEPT_CHECKS */ + +/* Define to 1 if a fully dynamic basic_string is wanted, 0 to disable, + undefined for platform defaults */ +#define _GLIBCXX_FULLY_DYNAMIC_STRING 0 + +/* Define if gthreads library is available. */ +#define _GLIBCXX_HAS_GTHREADS 1 + +/* Define to 1 if a full hosted library is built, or 0 if freestanding. */ +#define _GLIBCXX_HOSTED 1 + +/* Define if compatibility should be provided for -mlong-double-64. */ + +/* Define if ptrdiff_t is int. */ +#define _GLIBCXX_PTRDIFF_T_IS_INT 1 + +/* Define if using setrlimit to set resource limits during "make check" */ +/* #undef _GLIBCXX_RES_LIMITS */ + +/* Define if size_t is unsigned int. */ +#define _GLIBCXX_SIZE_T_IS_UINT 1 + +/* Define if the compiler is configured for setjmp/longjmp exceptions. */ +/* #undef _GLIBCXX_SJLJ_EXCEPTIONS */ + +/* Define to the value of the EOF integer constant. */ +#define _GLIBCXX_STDIO_EOF -1 + +/* Define to the value of the SEEK_CUR integer constant. */ +#define _GLIBCXX_STDIO_SEEK_CUR 1 + +/* Define to the value of the SEEK_END integer constant. */ +#define _GLIBCXX_STDIO_SEEK_END 2 + +/* Define to use symbol versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER */ + +/* Define to use darwin versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_DARWIN */ + +/* Define to use GNU versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_GNU */ + +/* Define to use GNU namespace versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_GNU_NAMESPACE */ + +/* Define to use Sun versioning in the shared library. */ +/* #undef _GLIBCXX_SYMVER_SUN */ + +/* Define if C99 functions or macros from , , , + , and can be used or exposed. */ +/* #undef _GLIBCXX_USE_C99 */ + +/* Define if C99 functions in should be used in . Using + compiler builtins for these functions requires corresponding C99 library + functions to be present. */ +/* #undef _GLIBCXX_USE_C99_COMPLEX */ + +/* Define if C99 functions in should be used in . + Using compiler builtins for these functions requires corresponding C99 + library functions to be present. */ +/* #undef _GLIBCXX_USE_C99_COMPLEX_TR1 */ + +/* Define if C99 functions in should be imported in in + namespace std::tr1. */ +#define _GLIBCXX_USE_C99_CTYPE_TR1 1 + +/* Define if C99 functions in should be imported in in + namespace std::tr1. */ +#define _GLIBCXX_USE_C99_FENV_TR1 1 + +/* Define if C99 functions in should be imported in + in namespace std::tr1. */ +/* #undef _GLIBCXX_USE_C99_INTTYPES_TR1 */ + +/* Define if wchar_t C99 functions in should be imported in + in namespace std::tr1. */ +/* #undef _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 */ + +/* Define if C99 functions or macros in should be imported in + in namespace std. */ +#define _GLIBCXX_USE_C99_MATH 1 + +/* Define if C99 functions or macros in should be imported in + in namespace std::tr1. */ +/* #undef _GLIBCXX_USE_C99_MATH_TR1 */ + +/* Define if C99 types in should be imported in in + namespace std::tr1. */ +#define _GLIBCXX_USE_C99_STDINT_TR1 1 + +/* Defined if clock_gettime syscall has monotonic and realtime clock support. + */ +/* #undef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL */ + +/* Defined if clock_gettime has monotonic clock support. */ +#define _GLIBCXX_USE_CLOCK_MONOTONIC 1 + +/* Defined if clock_gettime has realtime clock support. */ +#define _GLIBCXX_USE_CLOCK_REALTIME 1 + +/* Define if ISO/IEC TR 24733 decimal floating point types are supported on + this host. */ +/* #undef _GLIBCXX_USE_DECIMAL_FLOAT */ + +/* Define if __float128 is supported on this host. + Hide all uses of __float128 from Clang. Google ref b/6422845 */ +#ifndef __clang__ +/* #undef _GLIBCXX_USE_FLOAT128 */ +#endif + +/* Defined if gettimeofday is available. */ +#define _GLIBCXX_USE_GETTIMEOFDAY 1 + +/* Define if get_nprocs is available in . */ +/* #undef _GLIBCXX_USE_GET_NPROCS */ + +/* Define if __int128 is supported on this host. */ +/* #undef _GLIBCXX_USE_INT128 */ + +/* Define if LFS support is available. */ +/* #undef _GLIBCXX_USE_LFS */ + +/* Define if code specialized for long long should be used. */ +#define _GLIBCXX_USE_LONG_LONG 1 + +/* Defined if nanosleep is available. */ +#define _GLIBCXX_USE_NANOSLEEP 1 + +/* Define if NLS translations are to be used. */ +/* #undef _GLIBCXX_USE_NLS */ + +/* Define if pthreads_num_processors_np is available in . */ +/* #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP */ + +/* Define if /dev/random and /dev/urandom are available for the random_device + of TR1 (Chapter 5.1). */ +#define _GLIBCXX_USE_RANDOM_TR1 1 + +/* Defined if sched_yield is available. */ +#define _GLIBCXX_USE_SCHED_YIELD 1 + +/* Define if _SC_NPROCESSORS_ONLN is available in . */ +#define _GLIBCXX_USE_SC_NPROCESSORS_ONLN 1 + +/* Define if _SC_NPROC_ONLN is available in . */ +/* #undef _GLIBCXX_USE_SC_NPROC_ONLN */ + +/* Define if sysctl(), CTL_HW and HW_NCPU are available in . */ +/* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ + +/* Define if obsolescent tmpnam is available in . */ +#define _GLIBCXX_USE_TMPNAM 1 + +/* Define if code specialized for wchar_t should be used. */ +#define _GLIBCXX_USE_WCHAR_T 1 + +/* Define to 1 if a verbose library is built, or 0 otherwise. */ +#define _GLIBCXX_VERBOSE 1 + +/* Defined if as can handle rdrand. + Disable when building with Clang. Google ref b/8680429 */ +#ifndef __clang__ +/* #undef _GLIBCXX_X86_RDRAND */ +#endif + +/* Define to 1 if mutex_timedlock is available. */ +#define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 + +#if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) +# define _GLIBCXX_HAVE_ACOSF 1 +# define acosf _acosf +#endif + +#if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) +# define _GLIBCXX_HAVE_ACOSL 1 +# define acosl _acosl +#endif + +#if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) +# define _GLIBCXX_HAVE_ASINF 1 +# define asinf _asinf +#endif + +#if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) +# define _GLIBCXX_HAVE_ASINL 1 +# define asinl _asinl +#endif + +#if defined (_GLIBCXX_HAVE__ATAN2F) && ! defined (_GLIBCXX_HAVE_ATAN2F) +# define _GLIBCXX_HAVE_ATAN2F 1 +# define atan2f _atan2f +#endif + +#if defined (_GLIBCXX_HAVE__ATAN2L) && ! defined (_GLIBCXX_HAVE_ATAN2L) +# define _GLIBCXX_HAVE_ATAN2L 1 +# define atan2l _atan2l +#endif + +#if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) +# define _GLIBCXX_HAVE_ATANF 1 +# define atanf _atanf +#endif + +#if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) +# define _GLIBCXX_HAVE_ATANL 1 +# define atanl _atanl +#endif + +#if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) +# define _GLIBCXX_HAVE_CEILF 1 +# define ceilf _ceilf +#endif + +#if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) +# define _GLIBCXX_HAVE_CEILL 1 +# define ceill _ceill +#endif + +#if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) +# define _GLIBCXX_HAVE_COSF 1 +# define cosf _cosf +#endif + +#if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) +# define _GLIBCXX_HAVE_COSHF 1 +# define coshf _coshf +#endif + +#if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) +# define _GLIBCXX_HAVE_COSHL 1 +# define coshl _coshl +#endif + +#if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) +# define _GLIBCXX_HAVE_COSL 1 +# define cosl _cosl +#endif + +#if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) +# define _GLIBCXX_HAVE_EXPF 1 +# define expf _expf +#endif + +#if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) +# define _GLIBCXX_HAVE_EXPL 1 +# define expl _expl +#endif + +#if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) +# define _GLIBCXX_HAVE_FABSF 1 +# define fabsf _fabsf +#endif + +#if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) +# define _GLIBCXX_HAVE_FABSL 1 +# define fabsl _fabsl +#endif + +#if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) +# define _GLIBCXX_HAVE_FINITE 1 +# define finite _finite +#endif + +#if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) +# define _GLIBCXX_HAVE_FINITEF 1 +# define finitef _finitef +#endif + +#if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) +# define _GLIBCXX_HAVE_FINITEL 1 +# define finitel _finitel +#endif + +#if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) +# define _GLIBCXX_HAVE_FLOORF 1 +# define floorf _floorf +#endif + +#if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) +# define _GLIBCXX_HAVE_FLOORL 1 +# define floorl _floorl +#endif + +#if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) +# define _GLIBCXX_HAVE_FMODF 1 +# define fmodf _fmodf +#endif + +#if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) +# define _GLIBCXX_HAVE_FMODL 1 +# define fmodl _fmodl +#endif + +#if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) +# define _GLIBCXX_HAVE_FPCLASS 1 +# define fpclass _fpclass +#endif + +#if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) +# define _GLIBCXX_HAVE_FREXPF 1 +# define frexpf _frexpf +#endif + +#if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) +# define _GLIBCXX_HAVE_FREXPL 1 +# define frexpl _frexpl +#endif + +#if defined (_GLIBCXX_HAVE__HYPOT) && ! defined (_GLIBCXX_HAVE_HYPOT) +# define _GLIBCXX_HAVE_HYPOT 1 +# define hypot _hypot +#endif + +#if defined (_GLIBCXX_HAVE__HYPOTF) && ! defined (_GLIBCXX_HAVE_HYPOTF) +# define _GLIBCXX_HAVE_HYPOTF 1 +# define hypotf _hypotf +#endif + +#if defined (_GLIBCXX_HAVE__HYPOTL) && ! defined (_GLIBCXX_HAVE_HYPOTL) +# define _GLIBCXX_HAVE_HYPOTL 1 +# define hypotl _hypotl +#endif + +#if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) +# define _GLIBCXX_HAVE_ISINF 1 +# define isinf _isinf +#endif + +#if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) +# define _GLIBCXX_HAVE_ISINFF 1 +# define isinff _isinff +#endif + +#if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) +# define _GLIBCXX_HAVE_ISINFL 1 +# define isinfl _isinfl +#endif + +#if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) +# define _GLIBCXX_HAVE_ISNAN 1 +# define isnan _isnan +#endif + +#if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) +# define _GLIBCXX_HAVE_ISNANF 1 +# define isnanf _isnanf +#endif + +#if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) +# define _GLIBCXX_HAVE_ISNANL 1 +# define isnanl _isnanl +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) +# define _GLIBCXX_HAVE_LDEXPF 1 +# define ldexpf _ldexpf +#endif + +#if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) +# define _GLIBCXX_HAVE_LDEXPL 1 +# define ldexpl _ldexpl +#endif + +#if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) +# define _GLIBCXX_HAVE_LOG10F 1 +# define log10f _log10f +#endif + +#if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) +# define _GLIBCXX_HAVE_LOG10L 1 +# define log10l _log10l +#endif + +#if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) +# define _GLIBCXX_HAVE_LOGF 1 +# define logf _logf +#endif + +#if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) +# define _GLIBCXX_HAVE_LOGL 1 +# define logl _logl +#endif + +#if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) +# define _GLIBCXX_HAVE_MODF 1 +# define modf _modf +#endif + +#if defined (_GLIBCXX_HAVE__MODFF) && ! defined (_GLIBCXX_HAVE_MODFF) +# define _GLIBCXX_HAVE_MODFF 1 +# define modff _modff +#endif + +#if defined (_GLIBCXX_HAVE__MODFL) && ! defined (_GLIBCXX_HAVE_MODFL) +# define _GLIBCXX_HAVE_MODFL 1 +# define modfl _modfl +#endif + +#if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) +# define _GLIBCXX_HAVE_POWF 1 +# define powf _powf +#endif + +#if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) +# define _GLIBCXX_HAVE_POWL 1 +# define powl _powl +#endif + +#if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) +# define _GLIBCXX_HAVE_QFPCLASS 1 +# define qfpclass _qfpclass +#endif + +#if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) +# define _GLIBCXX_HAVE_SINCOS 1 +# define sincos _sincos +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) +# define _GLIBCXX_HAVE_SINCOSF 1 +# define sincosf _sincosf +#endif + +#if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) +# define _GLIBCXX_HAVE_SINCOSL 1 +# define sincosl _sincosl +#endif + +#if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) +# define _GLIBCXX_HAVE_SINF 1 +# define sinf _sinf +#endif + +#if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) +# define _GLIBCXX_HAVE_SINHF 1 +# define sinhf _sinhf +#endif + +#if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) +# define _GLIBCXX_HAVE_SINHL 1 +# define sinhl _sinhl +#endif + +#if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) +# define _GLIBCXX_HAVE_SINL 1 +# define sinl _sinl +#endif + +#if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) +# define _GLIBCXX_HAVE_SQRTF 1 +# define sqrtf _sqrtf +#endif + +#if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) +# define _GLIBCXX_HAVE_SQRTL 1 +# define sqrtl _sqrtl +#endif + +#if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) +# define _GLIBCXX_HAVE_STRTOF 1 +# define strtof _strtof +#endif + +#if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) +# define _GLIBCXX_HAVE_STRTOLD 1 +# define strtold _strtold +#endif + +#if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) +# define _GLIBCXX_HAVE_TANF 1 +# define tanf _tanf +#endif + +#if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) +# define _GLIBCXX_HAVE_TANHF 1 +# define tanhf _tanhf +#endif + +#if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) +# define _GLIBCXX_HAVE_TANHL 1 +# define tanhl _tanhl +#endif + +#if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) +# define _GLIBCXX_HAVE_TANL 1 +# define tanl _tanl +#endif + +#endif // _GLIBCXX_CXX_CONFIG_H diff --git a/loader/include/Geode/c++stl/gnustl/c++config.h b/loader/include/Geode/c++stl/gnustl/c++config.h new file mode 100644 index 00000000..ec8b83dd --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/c++config.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +#if UINTPTR_MAX > 0xffffffff +# include "c++config-arm64.h" +#else +# include "c++config-armeabi-v7a.h" +#endif + +// i put this here cuz it's used all over the place +namespace geode::stl { + template using __not_ = std::integral_constant; +} diff --git a/loader/include/Geode/c++stl/gnustl/exception_defines.h b/loader/include/Geode/c++stl/gnustl/exception_defines.h new file mode 100644 index 00000000..89ea52af --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/exception_defines.h @@ -0,0 +1,45 @@ +// -fno-exceptions Support -*- C++ -*- + +// Copyright (C) 2001-2014 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 +// . + +/** @file bits/exception_defines.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{exception} + */ + +#ifndef _EXCEPTION_DEFINES_H +#define _EXCEPTION_DEFINES_H 1 + +#ifndef __EXCEPTIONS +// Iff -fno-exceptions, transform error handling code to work without it. +# define __try if (true) +# define __catch(X) if (false) +# define __throw_exception_again +#else +// Else proceed normally. +# define __try try +# define __catch(X) catch(X) +# define __throw_exception_again throw +#endif + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/ext/aligned_buffer.h b/loader/include/Geode/c++stl/gnustl/ext/aligned_buffer.h new file mode 100644 index 00000000..5b5e993c --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/ext/aligned_buffer.h @@ -0,0 +1,111 @@ +// Aligned memory buffer -*- C++ -*- + +// Copyright (C) 2013-2014 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 +// . + +/** @file ext/aligned_buffer.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#pragma once + +#pragma GCC system_header + +#if __cplusplus >= 201103L +# include +#else +# include +#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 + 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. + 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(&_M_storage); } + + const void* + _M_addr() const noexcept + { return static_cast(&_M_storage); } + + _Tp* + _M_ptr() noexcept + { return static_cast<_Tp*>(_M_addr()); } + + const _Tp* + _M_ptr() const noexcept + { return static_cast(_M_addr()); } + }; + + // Similar to __aligned_membuf but aligned for complete objects, not members. + // This type is used in , , + // and , 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 + struct __aligned_buffer + : std::aligned_storage::value> + { + typename + std::aligned_storage::value>::type + _M_storage; + + void* + _M_addr() noexcept + { + return static_cast(&_M_storage); + } + + const void* + _M_addr() const noexcept + { + return static_cast(&_M_storage); + } + + _Tp* + _M_ptr() noexcept + { return static_cast<_Tp*>(_M_addr()); } + + const _Tp* + _M_ptr() const noexcept + { return static_cast(_M_addr()); } + }; + +} // namespace + diff --git a/loader/include/Geode/c++stl/gnustl/ext/alloc_traits.h b/loader/include/Geode/c++stl/gnustl/ext/alloc_traits.h new file mode 100644 index 00000000..7f59b9e6 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/ext/alloc_traits.h @@ -0,0 +1,211 @@ +// Allocator traits -*- C++ -*- + +// Copyright (C) 2011-2014 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 +// . + +/** @file ext/alloc_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#pragma once + +#pragma GCC system_header + +#if __cplusplus >= 201103L +# include "../alloc_traits.h" +#else +# include // for __alloc_swap +#endif +#include "../c++config.h" + +namespace __gnu_cxx { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +#if __cplusplus >= 201103L + template + struct __allocator_always_compares_equal : std::false_type { }; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; + + template struct array_allocator; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; + + template struct bitmap_allocator; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; + + template struct malloc_allocator; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; + + template struct mt_allocator; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; + + template struct new_allocator; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; + + template struct pool_allocator; + + template + struct __allocator_always_compares_equal> + : std::true_type { }; +#endif + +/** + * @brief Uniform interface to C++98 and C++0x allocators. + * @ingroup allocators +*/ +template + 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 + using __is_custom_pointer + = std::conjunction, + geode::stl::__not_>>; + + public: + // overload construct for non-standard pointer types + template + static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type + construct(_Alloc& __a, _Ptr __p, _Args&&... __args) + { + _Base_type::construct(__a, std::addressof(*__p), + std::forward<_Args>(__args)...); + } + + // overload destroy for non-standard pointer types + template + static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type + destroy(_Alloc& __a, _Ptr __p) + { _Base_type::destroy(__a, std::addressof(*__p)); } + + static _Alloc _S_select_on_copy(const _Alloc& __a) + { return _Base_type::select_on_container_copy_construction(__a); } + + static void _S_on_swap(_Alloc& __a, _Alloc& __b) + { __alloc_on_swap(__a, __b); } + + static constexpr bool _S_propagate_on_copy_assign() + { return _Base_type::propagate_on_container_copy_assignment::value; } + + static constexpr bool _S_propagate_on_move_assign() + { return _Base_type::propagate_on_container_move_assignment::value; } + + static constexpr bool _S_propagate_on_swap() + { return _Base_type::propagate_on_container_swap::value; } + + static constexpr bool _S_always_equal() + { return __allocator_always_compares_equal<_Alloc>::value; } + + static constexpr bool _S_nothrow_move() + { return _S_propagate_on_move_assign() || _S_always_equal(); } + + static constexpr bool _S_nothrow_swap() + { + using std::swap; + return !_S_propagate_on_swap() + || noexcept(swap(std::declval<_Alloc&>(), std::declval<_Alloc&>())); + } + + template + struct rebind + { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; +#else + + 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; + + static pointer + allocate(_Alloc& __a, size_type __n) + { return __a.allocate(__n); } + + static void deallocate(_Alloc& __a, pointer __p, size_type __n) + { __a.deallocate(__p, __n); } + + template + static void construct(_Alloc& __a, pointer __p, const _Tp& __arg) + { __a.construct(__p, __arg); } + + static void destroy(_Alloc& __a, pointer __p) + { __a.destroy(__p); } + + static size_type max_size(const _Alloc& __a) + { return __a.max_size(); } + + static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; } + + 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 + struct rebind + { typedef typename _Alloc::template rebind<_Tp>::other other; }; +#endif + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std diff --git a/loader/include/Geode/c++stl/gnustl/ext/new_allocator.h b/loader/include/Geode/c++stl/gnustl/ext/new_allocator.h new file mode 100644 index 00000000..cf0d1ea6 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/ext/new_allocator.h @@ -0,0 +1,155 @@ +// Allocator that wraps operator new -*- C++ -*- + +// Copyright (C) 2001-2014 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 +// . + +/** @file ext/new_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _NEW_ALLOCATOR_H +#define _NEW_ALLOCATOR_H 1 + +#include "../c++config.h" +#include +#if __cplusplus >= 201103L +#include +#endif + +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + using std::size_t; + using std::ptrdiff_t; + + /** + * @brief An allocator that uses global new, as per [20.4]. + * @ingroup allocators + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * @tparam _Tp Type of allocated object. + */ + template + class new_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef new_allocator<_Tp1> other; }; + +#if __cplusplus >= 201103L + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2103. propagate_on_container_move_assignment + typedef std::true_type propagate_on_container_move_assignment; +#endif + + new_allocator() _GLIBCXX_USE_NOEXCEPT { } + + new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { } + + template + new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } + + ~new_allocator() _GLIBCXX_USE_NOEXCEPT { } + + pointer + address(reference __x) const _GLIBCXX_NOEXCEPT + { return std::addressof(__x); } + + const_pointer + address(const_reference __x) const _GLIBCXX_NOEXCEPT + { return std::addressof(__x); } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { + if (__n > this->max_size()) + std::__throw_bad_alloc(); + + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } + +#ifdef __GXX_DELETE_WITH_SIZE__ + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type __t) + { ::operator delete(__p, __t * sizeof(_Tp)); } +#else + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } +#endif + + size_type + max_size() const _GLIBCXX_USE_NOEXCEPT + { return size_t(-1) / sizeof(_Tp); } + +#if __cplusplus >= 201103L + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new((void *)__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } +#endif + }; + + template + inline bool + operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return false; } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/ext/numeric_traits.h b/loader/include/Geode/c++stl/gnustl/ext/numeric_traits.h new file mode 100644 index 00000000..dcb55e26 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/ext/numeric_traits.h @@ -0,0 +1,135 @@ +// -*- C++ -*- + +// Copyright (C) 2007-2014 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 +// . + +/** @file ext/numeric_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#pragma once + +#pragma GCC system_header + +#include +#include "../c++config.h" + +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Compile time constants for builtin types. + // Sadly std::numeric_limits member functions cannot be used for this. +#define __glibcxx_signed(_Tp) ((_Tp)(-1) < 0) +#define __glibcxx_digits(_Tp) \ + (sizeof(_Tp) * __CHAR_BIT__ - __glibcxx_signed(_Tp)) + +#define __glibcxx_min(_Tp) \ + (__glibcxx_signed(_Tp) ? (_Tp)1 << __glibcxx_digits(_Tp) : (_Tp)0) + +#define __glibcxx_max(_Tp) \ + (__glibcxx_signed(_Tp) ? \ + (((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0) + + template + struct __numeric_traits_integer + { + // Only integers for initialization of member constant. + static const _Value __min = __glibcxx_min(_Value); + static const _Value __max = __glibcxx_max(_Value); + + // NB: these two also available in std::numeric_limits as compile + // time constants, but is big and we avoid including it. + static const bool __is_signed = __glibcxx_signed(_Value); + static const int __digits = __glibcxx_digits(_Value); + }; + + template + const _Value __numeric_traits_integer<_Value>::__min; + + template + const _Value __numeric_traits_integer<_Value>::__max; + + template + const bool __numeric_traits_integer<_Value>::__is_signed; + + template + const int __numeric_traits_integer<_Value>::__digits; + +#undef __glibcxx_signed +#undef __glibcxx_digits +#undef __glibcxx_min +#undef __glibcxx_max + +#define __glibcxx_floating(_Tp, _Fval, _Dval, _LDval) \ + (std::is_same<_Tp, float>::__value ? _Fval \ + : std::is_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__) + + template + 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 + const int __numeric_traits_floating<_Value>::__max_digits10; + + template + const bool __numeric_traits_floating<_Value>::__is_signed; + + template + const int __numeric_traits_floating<_Value>::__digits10; + + template + const int __numeric_traits_floating<_Value>::__max_exponent10; + + template + struct __numeric_traits + : public std::conditional::__value, + __numeric_traits_integer<_Value>, + __numeric_traits_floating<_Value> >::__type + { }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#undef __glibcxx_floating +#undef __glibcxx_max_digits10 +#undef __glibcxx_digits10 +#undef __glibcxx_max_exponent10 diff --git a/loader/include/Geode/c++stl/gnustl/functional_hash.h b/loader/include/Geode/c++stl/gnustl/functional_hash.h new file mode 100644 index 00000000..05211b4d --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/functional_hash.h @@ -0,0 +1,211 @@ +// functional_hash.h header -*- C++ -*- + +// Copyright (C) 2007-2014 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 +// . + +/** @file bits/functional_hash.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{functional} + */ + +#ifndef _FUNCTIONAL_HASH_H +#define _FUNCTIONAL_HASH_H 1 + +#pragma GCC system_header + +#include "hash_bytes.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** @defgroup hashes Hashes + * @ingroup functors + * + * Hashing functors taking a variable type and returning a @c std::size_t. + * + * @{ + */ + + template + struct __hash_base + { + typedef _Result result_type; + typedef _Arg argument_type; + }; + + /// Primary class template hash. + template + struct hash; + + /// Partial specializations for pointer types. + template + struct hash<_Tp*> : public __hash_base + { + size_t + operator()(_Tp* __p) const noexcept + { return reinterpret_cast(__p); } + }; + + // Explicit specializations for integer types. +#define _Cxx_hashtable_define_trivial_hash(_Tp) \ + template<> \ + struct hash<_Tp> : public __hash_base \ + { \ + size_t \ + operator()(_Tp __val) const noexcept \ + { return static_cast(__val); } \ + }; + + /// Explicit specialization for bool. + _Cxx_hashtable_define_trivial_hash(bool) + + /// Explicit specialization for char. + _Cxx_hashtable_define_trivial_hash(char) + + /// Explicit specialization for signed char. + _Cxx_hashtable_define_trivial_hash(signed char) + + /// Explicit specialization for unsigned char. + _Cxx_hashtable_define_trivial_hash(unsigned char) + + /// Explicit specialization for wchar_t. + _Cxx_hashtable_define_trivial_hash(wchar_t) + + /// Explicit specialization for char16_t. + _Cxx_hashtable_define_trivial_hash(char16_t) + + /// Explicit specialization for char32_t. + _Cxx_hashtable_define_trivial_hash(char32_t) + + /// Explicit specialization for short. + _Cxx_hashtable_define_trivial_hash(short) + + /// Explicit specialization for int. + _Cxx_hashtable_define_trivial_hash(int) + + /// Explicit specialization for long. + _Cxx_hashtable_define_trivial_hash(long) + + /// Explicit specialization for long long. + _Cxx_hashtable_define_trivial_hash(long long) + + /// Explicit specialization for unsigned short. + _Cxx_hashtable_define_trivial_hash(unsigned short) + + /// Explicit specialization for unsigned int. + _Cxx_hashtable_define_trivial_hash(unsigned int) + + /// Explicit specialization for unsigned long. + _Cxx_hashtable_define_trivial_hash(unsigned long) + + /// Explicit specialization for unsigned long long. + _Cxx_hashtable_define_trivial_hash(unsigned long long) + +#undef _Cxx_hashtable_define_trivial_hash + + struct _Hash_impl + { + static size_t + hash(const void* __ptr, size_t __clength, + size_t __seed = static_cast(0xc70f6907UL)) + { return _Hash_bytes(__ptr, __clength, __seed); } + + template + static size_t + hash(const _Tp& __val) + { return hash(&__val, sizeof(__val)); } + + template + static size_t + __hash_combine(const _Tp& __val, size_t __hash) + { return hash(&__val, sizeof(__val), __hash); } + }; + + struct _Fnv_hash_impl + { + static size_t + hash(const void* __ptr, size_t __clength, + size_t __seed = static_cast(2166136261UL)) + { return _Fnv_hash_bytes(__ptr, __clength, __seed); } + + template + static size_t + hash(const _Tp& __val) + { return hash(&__val, sizeof(__val)); } + + template + static size_t + __hash_combine(const _Tp& __val, size_t __hash) + { return hash(&__val, sizeof(__val), __hash); } + }; + + /// Specialization for float. + template<> + struct hash : public __hash_base + { + size_t + operator()(float __val) const noexcept + { + // 0 and -0 both hash to zero. + return __val != 0.0f ? _Hash_impl::hash(__val) : 0; + } + }; + + /// Specialization for double. + template<> + struct hash : public __hash_base + { + size_t + operator()(double __val) const noexcept + { + // 0 and -0 both hash to zero. + return __val != 0.0 ? _Hash_impl::hash(__val) : 0; + } + }; + + /// Specialization for long double. + template<> + struct hash + : public __hash_base + { + _GLIBCXX_PURE size_t + operator()(long double __val) const noexcept; + }; + + // @} group hashes + + // Hint about performance of hash functor. If not fast the hash based + // containers will cache the hash code. + // Default behavior is to consider that hasher are fast unless specified + // otherwise. + template + struct __is_fast_hash : public std::true_type + { }; + + template<> + struct __is_fast_hash> : public std::false_type + { }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif // _FUNCTIONAL_HASH_H diff --git a/loader/include/Geode/c++stl/gnustl/hash_bytes.h b/loader/include/Geode/c++stl/gnustl/hash_bytes.h new file mode 100644 index 00000000..18b40618 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/hash_bytes.h @@ -0,0 +1,58 @@ +// Declarations for hash functions. -*- C++ -*- + +// Copyright (C) 2010-2014 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 +// . + +/** @file bits/hash_bytes.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{functional} + */ + +#ifndef _HASH_BYTES_H +#define _HASH_BYTES_H 1 + +#pragma GCC system_header + +#include "c++config.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Hash function implementation for the nontrivial specialization. + // All of them are based on a primitive that hashes a pointer to a + // byte array. The actual hash algorithm is not guaranteed to stay + // the same from release to release -- it may be updated or tuned to + // improve hash quality or speed. + size_t + _Hash_bytes(const void* __ptr, size_t __len, size_t __seed); + + // A similar hash primitive, using the FNV hash algorithm. This + // algorithm is guaranteed to stay the same from release to release. + // (although it might not produce the same values on different + // machines.) + size_t + _Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/hash_specialization.hpp b/loader/include/Geode/c++stl/gnustl/hash_specialization.hpp new file mode 100644 index 00000000..1e65dcd9 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/hash_specialization.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "functional_hash.h" + +namespace geode::stl { + template <> + struct hash : public __hash_base { + size_t operator()(const gd::string& s) const noexcept { + return _Hash_impl::hash(s.data(), s.size()); + } + }; +} diff --git a/loader/include/Geode/c++stl/gnustl/hashtable.h b/loader/include/Geode/c++stl/gnustl/hashtable.h new file mode 100644 index 00000000..6e76b24e --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/hashtable.h @@ -0,0 +1,2124 @@ +// hashtable.h header -*- C++ -*- + +// Copyright (C) 2007-2014 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 +// . + +/** @file bits/hashtable.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{unordered_map, unordered_set} + */ + +#ifndef _HASHTABLE_H +#define _HASHTABLE_H 1 + +#pragma GCC system_header + +#include "hashtable_policy.h" +#include "functional_hash.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + using __cache_default + = __not_, + // Mandatory to have erase not throwing. + __detail::__is_noexcept_hash<_Tp, _Hash>>>; + + /** + * Primary class template _Hashtable. + * + * @ingroup hashtable-detail + * + * @tparam _Value CopyConstructible type. + * + * @tparam _Key CopyConstructible type. + * + * @tparam _Alloc An allocator type + * ([lib.allocator.requirements]) whose _Alloc::value_type is + * _Value. As a conforming extension, we allow for + * _Alloc::value_type != _Value. + * + * @tparam _ExtractKey Function object that takes an object of type + * _Value and returns a value of type _Key. + * + * @tparam _Equal Function object that takes two objects of type k + * and returns a bool-like value that is true if the two objects + * are considered equal. + * + * @tparam _H1 The hash function. A unary function object with + * argument type _Key and result type size_t. Return values should + * be distributed over the entire range [0, numeric_limits:::max()]. + * + * @tparam _H2 The range-hashing function (in the terminology of + * Tavori and Dreizin). A binary function object whose argument + * types and result type are all size_t. Given arguments r and N, + * the return value is in the range [0, N). + * + * @tparam _Hash The ranged hash function (Tavori and Dreizin). A + * binary function whose argument types are _Key and size_t and + * whose result type is size_t. Given arguments k and N, the + * return value is in the range [0, N). Default: hash(k, N) = + * h2(h1(k), N). If _Hash is anything other than the default, _H1 + * and _H2 are ignored. + * + * @tparam _RehashPolicy Policy class with three members, all of + * which govern the bucket count. _M_next_bkt(n) returns a bucket + * count no smaller than n. _M_bkt_for_elements(n) returns a + * bucket count appropriate for an element count of n. + * _M_need_rehash(n_bkt, n_elt, n_ins) determines whether, if the + * current bucket count is n_bkt and the current element count is + * n_elt, we need to increase the bucket count. If so, returns + * make_pair(true, n), where n is the new bucket count. If not, + * returns make_pair(false, ) + * + * @tparam _Traits Compile-time class with three boolean + * std::integral_constant members: __cache_hash_code, __constant_iterators, + * __unique_keys. + * + * Each _Hashtable data structure has: + * + * - _Bucket[] _M_buckets + * - _Hash_node_base _M_before_begin + * - size_type _M_bucket_count + * - size_type _M_element_count + * + * with _Bucket being _Hash_node* and _Hash_node containing: + * + * - _Hash_node* _M_next + * - Tp _M_value + * - size_t _M_hash_code if cache_hash_code is true + * + * In terms of Standard containers the hashtable is like the aggregation of: + * + * - std::forward_list<_Node> containing the elements + * - std::vector::iterator> representing the buckets + * + * The non-empty buckets contain the node before the first node in the + * bucket. This design makes it possible to implement something like a + * std::forward_list::insert_after on container insertion and + * std::forward_list::erase_after on container erase + * calls. _M_before_begin is equivalent to + * std::forward_list::before_begin. Empty buckets contain + * nullptr. Note that one of the non-empty buckets contains + * &_M_before_begin which is not a dereferenceable node so the + * node pointer in a bucket shall never be dereferenced, only its + * next node can be. + * + * Walking through a bucket's nodes requires a check on the hash code to + * see if each node is still in the bucket. Such a design assumes a + * quite efficient hash functor and is one of the reasons it is + * highly advisable to set __cache_hash_code to true. + * + * The container iterators are simply built from nodes. This way + * incrementing the iterator is perfectly efficient independent of + * how many empty buckets there are in the container. + * + * On insert we compute the element's hash code and use it to find the + * bucket index. If the element must be inserted in an empty bucket + * we add it at the beginning of the singly linked list and make the + * bucket point to _M_before_begin. The bucket that used to point to + * _M_before_begin, if any, is updated to point to its new before + * begin node. + * + * On erase, the simple iterator design requires using the hash + * functor to get the index of the bucket to update. For this + * reason, when __cache_hash_code is set to false the hash functor must + * not throw and this is enforced by a static assertion. + * + * Functionality is implemented by decomposition into base classes, + * where the derived _Hashtable class is used in _Map_base, + * _Insert, _Rehash_base, and _Equality base classes to access the + * "this" pointer. _Hashtable_base is used in the base classes as a + * non-recursive, fully-completed-type so that detailed nested type + * information, such as iterator type and node type, can be + * used. This is similar to the "Curiously Recurring Template + * Pattern" (CRTP) technique, but uses a reconstructed, not + * explicitly passed, template pattern. + * + * Base class templates are: + * - __detail::_Hashtable_base + * - __detail::_Map_base + * - __detail::_Insert + * - __detail::_Rehash_base + * - __detail::_Equality + */ + template + class _Hashtable + : public __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, + _H1, _H2, _Hash, _Traits>, + public __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>, + public __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>, + public __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>, + public __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>, + private __detail::_Hashtable_alloc< + typename __alloctr_rebind<_Alloc, + __detail::_Hash_node<_Value, + _Traits::__hash_cached::value> >::__type> + { + using __traits_type = _Traits; + using __hash_cached = typename __traits_type::__hash_cached; + using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>; + using __node_alloc_type = + typename __alloctr_rebind<_Alloc, __node_type>::__type; + + using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>; + + using __value_alloc_traits = + typename __hashtable_alloc::__value_alloc_traits; + using __node_alloc_traits = + typename __hashtable_alloc::__node_alloc_traits; + using __node_base = typename __hashtable_alloc::__node_base; + using __bucket_type = typename __hashtable_alloc::__bucket_type; + + public: + typedef _Key key_type; + typedef _Value value_type; + typedef _Alloc allocator_type; + typedef _Equal key_equal; + + // mapped_type, if present, comes from _Map_base. + // hasher, if present, comes from _Hash_code_base/_Hashtable_base. + typedef typename __value_alloc_traits::pointer pointer; + typedef typename __value_alloc_traits::const_pointer const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + private: + using __rehash_type = _RehashPolicy; + using __rehash_state = typename __rehash_type::_State; + + using __constant_iterators = typename __traits_type::__constant_iterators; + using __unique_keys = typename __traits_type::__unique_keys; + + using __key_extract = typename std::conditional< + __constant_iterators::value, + __detail::_Identity, + __detail::_Select1st>::type; + + using __hashtable_base = __detail:: + _Hashtable_base<_Key, _Value, _ExtractKey, + _Equal, _H1, _H2, _Hash, _Traits>; + + using __hash_code_base = typename __hashtable_base::__hash_code_base; + using __hash_code = typename __hashtable_base::__hash_code; + using __ireturn_type = typename __hashtable_base::__ireturn_type; + + using __map_base = __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + + using __rehash_base = __detail::_Rehash_base<_Key, _Value, _Alloc, + _ExtractKey, _Equal, + _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + + using __eq_base = __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + + using __reuse_or_alloc_node_type = + __detail::_ReuseOrAllocNode<__node_alloc_type>; + + // Metaprogramming for picking apart hash caching. + template + using __if_hash_cached = std::disjunction<__not_<__hash_cached>, _Cond>; + + template + using __if_hash_not_cached = std::disjunction<__hash_cached, _Cond>; + + // Compile-time diagnostics. + + // _Hash_code_base has everything protected, so use this derived type to + // access it. + struct __hash_code_base_access : __hash_code_base + { using __hash_code_base::_M_bucket_index; }; + + // Getting a bucket index from a node shall not throw because it is used + // in methods (erase, swap...) that shall not throw. + static_assert(noexcept(std::declval() + ._M_bucket_index((const __node_type*)nullptr, + (std::size_t)0)), + "Cache the hash code or qualify your functors involved" + " in hash code and bucket index computation with noexcept"); + + // Following two static assertions are necessary to guarantee + // that local_iterator will be default constructible. + + // When hash codes are cached local iterator inherits from H2 functor + // which must then be default constructible. + static_assert(__if_hash_cached>::value, + "Functor used to map hash code to bucket index" + " must be default constructible"); + + template + friend struct __detail::_Map_base; + + template + friend struct __detail::_Insert_base; + + template + friend struct __detail::_Insert; + + public: + using size_type = typename __hashtable_base::size_type; + using difference_type = typename __hashtable_base::difference_type; + + using iterator = typename __hashtable_base::iterator; + using const_iterator = typename __hashtable_base::const_iterator; + + using local_iterator = typename __hashtable_base::local_iterator; + using const_local_iterator = typename __hashtable_base:: + const_local_iterator; + + private: + __bucket_type* _M_buckets; + size_type _M_bucket_count; + __node_base _M_before_begin; + size_type _M_element_count; + _RehashPolicy _M_rehash_policy; + + // A single bucket used when only need for 1 bucket. Especially + // interesting in move semantic to leave hashtable with only 1 buckets + // which is not allocated so that we can have those operations noexcept + // qualified. + // Note that we can't leave hashtable with 0 bucket without adding + // numerous checks in the code to avoid 0 modulus. + __bucket_type _M_single_bucket; + + bool + _M_uses_single_bucket(__bucket_type* __bkts) const + { return __builtin_expect(__bkts == &_M_single_bucket, false); } + + bool + _M_uses_single_bucket() const + { return _M_uses_single_bucket(_M_buckets); } + + __hashtable_alloc& + _M_base_alloc() { return *this; } + + __bucket_type* + _M_allocate_buckets(size_type __n) + { + if (__builtin_expect(__n == 1, false)) + { + _M_single_bucket = nullptr; + return &_M_single_bucket; + } + + return __hashtable_alloc::_M_allocate_buckets(__n); + } + + void + _M_deallocate_buckets(__bucket_type* __bkts, size_type __n) + { + if (_M_uses_single_bucket(__bkts)) + return; + + __hashtable_alloc::_M_deallocate_buckets(__bkts, __n); + } + + void + _M_deallocate_buckets() + { _M_deallocate_buckets(_M_buckets, _M_bucket_count); } + + // Gets bucket begin, deals with the fact that non-empty buckets contain + // their before begin node. + __node_type* + _M_bucket_begin(size_type __bkt) const; + + __node_type* + _M_begin() const + { return static_cast<__node_type*>(_M_before_begin._M_nxt); } + + template + void + _M_assign(const _Hashtable&, const _NodeGenerator&); + + void + _M_move_assign(_Hashtable&&, std::true_type); + + void + _M_move_assign(_Hashtable&&, std::false_type); + + void + _M_reset() noexcept; + + public: + // Constructor, destructor, assignment, swap + _Hashtable(size_type __bucket_hint, + const _H1&, const _H2&, const _Hash&, + const _Equal&, const _ExtractKey&, + const allocator_type&); + + template + _Hashtable(_InputIterator __first, _InputIterator __last, + size_type __bucket_hint, + const _H1&, const _H2&, const _Hash&, + const _Equal&, const _ExtractKey&, + const allocator_type&); + + _Hashtable(const _Hashtable&); + + _Hashtable(_Hashtable&&) noexcept; + + _Hashtable(const _Hashtable&, const allocator_type&); + + _Hashtable(_Hashtable&&, const allocator_type&); + + // Use delegating constructors. + explicit + _Hashtable(const allocator_type& __a) + : _Hashtable(10, _H1(), _H2(), _Hash(), key_equal(), + __key_extract(), __a) + { } + + explicit + _Hashtable(size_type __n = 10, + const _H1& __hf = _H1(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Hashtable(__n, __hf, _H2(), _Hash(), __eql, + __key_extract(), __a) + { } + + template + _Hashtable(_InputIterator __f, _InputIterator __l, + size_type __n = 0, + const _H1& __hf = _H1(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Hashtable(__f, __l, __n, __hf, _H2(), _Hash(), __eql, + __key_extract(), __a) + { } + + _Hashtable(std::initializer_list __l, + size_type __n = 0, + const _H1& __hf = _H1(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _Hashtable(__l.begin(), __l.end(), __n, __hf, _H2(), _Hash(), __eql, + __key_extract(), __a) + { } + + _Hashtable& + operator=(const _Hashtable& __ht); + + _Hashtable& + operator=(_Hashtable&& __ht) + noexcept(__node_alloc_traits::_S_nothrow_move()) + { + constexpr bool __move_storage = + __node_alloc_traits::_S_propagate_on_move_assign() + || __node_alloc_traits::_S_always_equal(); + _M_move_assign(std::move(__ht), + integral_constant()); + return *this; + } + + _Hashtable& + operator=(std::initializer_list __l) + { + __reuse_or_alloc_node_type __roan(_M_begin(), *this); + _M_before_begin._M_nxt = nullptr; + clear(); + this->_M_insert_range(__l.begin(), __l.end(), __roan); + return *this; + } + + ~_Hashtable() noexcept; + + void + swap(_Hashtable&) + noexcept(__node_alloc_traits::_S_nothrow_swap()); + + // Basic container operations + iterator + begin() noexcept + { return iterator(_M_begin()); } + + const_iterator + begin() const noexcept + { return const_iterator(_M_begin()); } + + iterator + end() noexcept + { return iterator(nullptr); } + + const_iterator + end() const noexcept + { return const_iterator(nullptr); } + + const_iterator + cbegin() const noexcept + { return const_iterator(_M_begin()); } + + const_iterator + cend() const noexcept + { return const_iterator(nullptr); } + + size_type + size() const noexcept + { return _M_element_count; } + + bool + empty() const noexcept + { return size() == 0; } + + allocator_type + get_allocator() const noexcept + { return allocator_type(this->_M_node_allocator()); } + + size_type + max_size() const noexcept + { return __node_alloc_traits::max_size(this->_M_node_allocator()); } + + // Observers + key_equal + key_eq() const + { return this->_M_eq(); } + + // hash_function, if present, comes from _Hash_code_base. + + // Bucket operations + size_type + bucket_count() const noexcept + { return _M_bucket_count; } + + size_type + max_bucket_count() const noexcept + { return max_size(); } + + size_type + bucket_size(size_type __n) const + { return std::distance(begin(__n), end(__n)); } + + size_type + bucket(const key_type& __k) const + { return _M_bucket_index(__k, this->_M_hash_code(__k)); } + + local_iterator + begin(size_type __n) + { + return local_iterator(*this, _M_bucket_begin(__n), + __n, _M_bucket_count); + } + + local_iterator + end(size_type __n) + { return local_iterator(*this, nullptr, __n, _M_bucket_count); } + + const_local_iterator + begin(size_type __n) const + { + return const_local_iterator(*this, _M_bucket_begin(__n), + __n, _M_bucket_count); + } + + const_local_iterator + end(size_type __n) const + { return const_local_iterator(*this, nullptr, __n, _M_bucket_count); } + + // DR 691. + const_local_iterator + cbegin(size_type __n) const + { + return const_local_iterator(*this, _M_bucket_begin(__n), + __n, _M_bucket_count); + } + + const_local_iterator + cend(size_type __n) const + { return const_local_iterator(*this, nullptr, __n, _M_bucket_count); } + + float + load_factor() const noexcept + { + return static_cast(size()) / static_cast(bucket_count()); + } + + // max_load_factor, if present, comes from _Rehash_base. + + // Generalization of max_load_factor. Extension, not found in + // TR1. Only useful if _RehashPolicy is something other than + // the default. + const _RehashPolicy& + __rehash_policy() const + { return _M_rehash_policy; } + + void + __rehash_policy(const _RehashPolicy&); + + // Lookup. + iterator + find(const key_type& __k); + + const_iterator + find(const key_type& __k) const; + + size_type + count(const key_type& __k) const; + + std::pair + equal_range(const key_type& __k); + + std::pair + equal_range(const key_type& __k) const; + + protected: + // Bucket index computation helpers. + size_type + _M_bucket_index(__node_type* __n) const noexcept + { return __hash_code_base::_M_bucket_index(__n, _M_bucket_count); } + + size_type + _M_bucket_index(const key_type& __k, __hash_code __c) const + { return __hash_code_base::_M_bucket_index(__k, __c, _M_bucket_count); } + + // Find and insert helper functions and types + // Find the node before the one matching the criteria. + __node_base* + _M_find_before_node(size_type, const key_type&, __hash_code) const; + + __node_type* + _M_find_node(size_type __bkt, const key_type& __key, + __hash_code __c) const + { + __node_base* __before_n = _M_find_before_node(__bkt, __key, __c); + if (__before_n) + return static_cast<__node_type*>(__before_n->_M_nxt); + return nullptr; + } + + // Insert a node at the beginning of a bucket. + void + _M_insert_bucket_begin(size_type, __node_type*); + + // Remove the bucket first node + void + _M_remove_bucket_begin(size_type __bkt, __node_type* __next_n, + size_type __next_bkt); + + // Get the node before __n in the bucket __bkt + __node_base* + _M_get_previous_node(size_type __bkt, __node_base* __n); + + // Insert node with hash code __code, in bucket bkt if no rehash (assumes + // no element with its key already present). Take ownership of the node, + // deallocate it on exception. + iterator + _M_insert_unique_node(size_type __bkt, __hash_code __code, + __node_type* __n); + + // Insert node with hash code __code. Take ownership of the node, + // deallocate it on exception. + iterator + _M_insert_multi_node(__node_type* __hint, + __hash_code __code, __node_type* __n); + + template + std::pair + _M_emplace(std::true_type, _Args&&... __args); + + template + iterator + _M_emplace(std::false_type __uk, _Args&&... __args) + { return _M_emplace(cend(), __uk, std::forward<_Args>(__args)...); } + + // Emplace with hint, useless when keys are unique. + template + iterator + _M_emplace(const_iterator, std::true_type __uk, _Args&&... __args) + { return _M_emplace(__uk, std::forward<_Args>(__args)...).first; } + + template + iterator + _M_emplace(const_iterator, std::false_type, _Args&&... __args); + + template + std::pair + _M_insert(_Arg&&, const _NodeGenerator&, std::true_type); + + template + iterator + _M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen, + std::false_type __uk) + { + return _M_insert(cend(), std::forward<_Arg>(__arg), __node_gen, + __uk); + } + + // Insert with hint, not used when keys are unique. + template + iterator + _M_insert(const_iterator, _Arg&& __arg, const _NodeGenerator& __node_gen, + std::true_type __uk) + { + return + _M_insert(std::forward<_Arg>(__arg), __node_gen, __uk).first; + } + + // Insert with hint when keys are not unique. + template + iterator + _M_insert(const_iterator, _Arg&&, const _NodeGenerator&, std::false_type); + + size_type + _M_erase(std::true_type, const key_type&); + + size_type + _M_erase(std::false_type, const key_type&); + + iterator + _M_erase(size_type __bkt, __node_base* __prev_n, __node_type* __n); + + public: + // Emplace + template + __ireturn_type + emplace(_Args&&... __args) + { return _M_emplace(__unique_keys(), std::forward<_Args>(__args)...); } + + template + iterator + emplace_hint(const_iterator __hint, _Args&&... __args) + { + return _M_emplace(__hint, __unique_keys(), + std::forward<_Args>(__args)...); + } + + // Insert member functions via inheritance. + + // Erase + iterator + erase(const_iterator); + + // LWG 2059. + iterator + erase(iterator __it) + { return erase(const_iterator(__it)); } + + size_type + erase(const key_type& __k) + { return _M_erase(__unique_keys(), __k); } + + iterator + erase(const_iterator, const_iterator); + + void + clear() noexcept; + + // Set number of buckets to be appropriate for container of n element. + void rehash(size_type __n); + + // DR 1189. + // reserve, if present, comes from _Rehash_base. + + private: + // Helper rehash method used when keys are unique. + void _M_rehash_aux(size_type __n, std::true_type); + + // Helper rehash method used when keys can be non-unique. + void _M_rehash_aux(size_type __n, std::false_type); + + // Unconditionally change size of bucket array to n, restore + // hash policy state to __state on exception. + void _M_rehash(size_type __n, const __rehash_state& __state); + }; + + + // Definitions of class template _Hashtable's out-of-line member functions. + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + _Traits>::__node_type* + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_bucket_begin(size_type __bkt) const + { + __node_base* __n = _M_buckets[__bkt]; + return __n ? static_cast<__node_type*>(__n->_M_nxt) : nullptr; + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _Hashtable(size_type __bucket_hint, + const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __hashtable_base(__exk, __h1, __h2, __h, __eq), + __map_base(), + __rehash_base(), + __hashtable_alloc(__node_alloc_type(__a)), + _M_element_count(0), + _M_rehash_policy() + { + _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint); + _M_buckets = _M_allocate_buckets(_M_bucket_count); + } + + template + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _Hashtable(_InputIterator __f, _InputIterator __l, + size_type __bucket_hint, + const _H1& __h1, const _H2& __h2, const _Hash& __h, + const _Equal& __eq, const _ExtractKey& __exk, + const allocator_type& __a) + : __hashtable_base(__exk, __h1, __h2, __h, __eq), + __map_base(), + __rehash_base(), + __hashtable_alloc(__node_alloc_type(__a)), + _M_element_count(0), + _M_rehash_policy() + { + auto __nb_elems = __detail::__distance_fw(__f, __l); + _M_bucket_count = + _M_rehash_policy._M_next_bkt( + std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems), + __bucket_hint)); + + _M_buckets = _M_allocate_buckets(_M_bucket_count); + __try + { + for (; __f != __l; ++__f) + this->insert(*__f); + } + __catch(...) + { + clear(); + _M_deallocate_buckets(); + __throw_exception_again; + } + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>& + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>::operator=( + const _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>& __ht) + { + if (&__ht == this) + return *this; + + if (__node_alloc_traits::_S_propagate_on_copy_assign()) + { + auto& __this_alloc = this->_M_node_allocator(); + auto& __that_alloc = __ht._M_node_allocator(); + if (!__node_alloc_traits::_S_always_equal() + && __this_alloc != __that_alloc) + { + // Replacement allocator cannot free existing storage. + this->_M_deallocate_nodes(_M_begin()); + _M_before_begin._M_nxt = nullptr; + _M_deallocate_buckets(); + _M_buckets = nullptr; + __alloc_on_copy(__this_alloc, __that_alloc); + __hashtable_base::operator=(__ht); + _M_bucket_count = __ht._M_bucket_count; + _M_element_count = __ht._M_element_count; + _M_rehash_policy = __ht._M_rehash_policy; + __try + { + _M_assign(__ht, + [this](const __node_type* __n) + { return this->_M_allocate_node(__n->_M_v()); }); + } + __catch(...) + { + // _M_assign took care of deallocating all memory. Now we + // must make sure this instance remains in a usable state. + _M_reset(); + __throw_exception_again; + } + return *this; + } + __alloc_on_copy(__this_alloc, __that_alloc); + } + + // Reuse allocated buckets and nodes. + __bucket_type* __former_buckets = nullptr; + std::size_t __former_bucket_count = _M_bucket_count; + const __rehash_state& __former_state = _M_rehash_policy._M_state(); + + if (_M_bucket_count != __ht._M_bucket_count) + { + __former_buckets = _M_buckets; + _M_buckets = _M_allocate_buckets(__ht._M_bucket_count); + _M_bucket_count = __ht._M_bucket_count; + } + else + __builtin_memset(_M_buckets, 0, + _M_bucket_count * sizeof(__bucket_type)); + + __try + { + __hashtable_base::operator=(__ht); + _M_element_count = __ht._M_element_count; + _M_rehash_policy = __ht._M_rehash_policy; + __reuse_or_alloc_node_type __roan(_M_begin(), *this); + _M_before_begin._M_nxt = nullptr; + _M_assign(__ht, + [&__roan](const __node_type* __n) + { return __roan(__n->_M_v()); }); + if (__former_buckets) + _M_deallocate_buckets(__former_buckets, __former_bucket_count); + } + __catch(...) + { + if (__former_buckets) + { + // Restore previous buckets. + _M_deallocate_buckets(); + _M_rehash_policy._M_reset(__former_state); + _M_buckets = __former_buckets; + _M_bucket_count = __former_bucket_count; + } + __builtin_memset(_M_buckets, 0, + _M_bucket_count * sizeof(__bucket_type)); + __throw_exception_again; + } + return *this; + } + + template + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_assign(const _Hashtable& __ht, const _NodeGenerator& __node_gen) + { + __bucket_type* __buckets = nullptr; + if (!_M_buckets) + _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count); + + __try + { + if (!__ht._M_before_begin._M_nxt) + return; + + // First deal with the special first node pointed to by + // _M_before_begin. + __node_type* __ht_n = __ht._M_begin(); + __node_type* __this_n = __node_gen(__ht_n); + this->_M_copy_code(__this_n, __ht_n); + _M_before_begin._M_nxt = __this_n; + _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin; + + // Then deal with other nodes. + __node_base* __prev_n = __this_n; + for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next()) + { + __this_n = __node_gen(__ht_n); + __prev_n->_M_nxt = __this_n; + this->_M_copy_code(__this_n, __ht_n); + size_type __bkt = _M_bucket_index(__this_n); + if (!_M_buckets[__bkt]) + _M_buckets[__bkt] = __prev_n; + __prev_n = __this_n; + } + } + __catch(...) + { + clear(); + if (__buckets) + _M_deallocate_buckets(); + __throw_exception_again; + } + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_reset() noexcept + { + _M_rehash_policy._M_reset(); + _M_bucket_count = 1; + _M_single_bucket = nullptr; + _M_buckets = &_M_single_bucket; + _M_before_begin._M_nxt = nullptr; + _M_element_count = 0; + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_move_assign(_Hashtable&& __ht, std::true_type) + { + this->_M_deallocate_nodes(_M_begin()); + _M_deallocate_buckets(); + __hashtable_base::operator=(std::move(__ht)); + _M_rehash_policy = __ht._M_rehash_policy; + if (!__ht._M_uses_single_bucket()) + _M_buckets = __ht._M_buckets; + else + { + _M_buckets = &_M_single_bucket; + _M_single_bucket = __ht._M_single_bucket; + } + _M_bucket_count = __ht._M_bucket_count; + _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt; + _M_element_count = __ht._M_element_count; + __alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator()); + + // Fix buckets containing the _M_before_begin pointers that can't be + // moved. + if (_M_begin()) + _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; + __ht._M_reset(); + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_move_assign(_Hashtable&& __ht, std::false_type) + { + if (__ht._M_node_allocator() == this->_M_node_allocator()) + _M_move_assign(std::move(__ht), std::true_type()); + else + { + // Can't move memory, move elements then. + __bucket_type* __former_buckets = nullptr; + size_type __former_bucket_count = _M_bucket_count; + const __rehash_state& __former_state = _M_rehash_policy._M_state(); + + if (_M_bucket_count != __ht._M_bucket_count) + { + __former_buckets = _M_buckets; + _M_buckets = _M_allocate_buckets(__ht._M_bucket_count); + _M_bucket_count = __ht._M_bucket_count; + } + else + __builtin_memset(_M_buckets, 0, + _M_bucket_count * sizeof(__bucket_type)); + + __try + { + __hashtable_base::operator=(std::move(__ht)); + _M_element_count = __ht._M_element_count; + _M_rehash_policy = __ht._M_rehash_policy; + __reuse_or_alloc_node_type __roan(_M_begin(), *this); + _M_before_begin._M_nxt = nullptr; + _M_assign(__ht, + [&__roan](__node_type* __n) + { return __roan(std::move_if_noexcept(__n->_M_v())); }); + __ht.clear(); + } + __catch(...) + { + if (__former_buckets) + { + _M_deallocate_buckets(); + _M_rehash_policy._M_reset(__former_state); + _M_buckets = __former_buckets; + _M_bucket_count = __former_bucket_count; + } + __builtin_memset(_M_buckets, 0, + _M_bucket_count * sizeof(__bucket_type)); + __throw_exception_again; + } + } + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _Hashtable(const _Hashtable& __ht) + : __hashtable_base(__ht), + __map_base(__ht), + __rehash_base(__ht), + __hashtable_alloc( + __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())), + _M_buckets(), + _M_bucket_count(__ht._M_bucket_count), + _M_element_count(__ht._M_element_count), + _M_rehash_policy(__ht._M_rehash_policy) + { + _M_assign(__ht, + [this](const __node_type* __n) + { return this->_M_allocate_node(__n->_M_v()); }); + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _Hashtable(_Hashtable&& __ht) noexcept + : __hashtable_base(__ht), + __map_base(__ht), + __rehash_base(__ht), + __hashtable_alloc(std::move(__ht._M_base_alloc())), + _M_buckets(__ht._M_buckets), + _M_bucket_count(__ht._M_bucket_count), + _M_before_begin(__ht._M_before_begin._M_nxt), + _M_element_count(__ht._M_element_count), + _M_rehash_policy(__ht._M_rehash_policy) + { + // Update, if necessary, buckets if __ht is using its single bucket. + if (__ht._M_uses_single_bucket()) + { + _M_buckets = &_M_single_bucket; + _M_single_bucket = __ht._M_single_bucket; + } + + // Update, if necessary, bucket pointing to before begin that hasn't + // moved. + if (_M_begin()) + _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; + + __ht._M_reset(); + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _Hashtable(const _Hashtable& __ht, const allocator_type& __a) + : __hashtable_base(__ht), + __map_base(__ht), + __rehash_base(__ht), + __hashtable_alloc(__node_alloc_type(__a)), + _M_buckets(), + _M_bucket_count(__ht._M_bucket_count), + _M_element_count(__ht._M_element_count), + _M_rehash_policy(__ht._M_rehash_policy) + { + _M_assign(__ht, + [this](const __node_type* __n) + { return this->_M_allocate_node(__n->_M_v()); }); + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _Hashtable(_Hashtable&& __ht, const allocator_type& __a) + : __hashtable_base(__ht), + __map_base(__ht), + __rehash_base(__ht), + __hashtable_alloc(__node_alloc_type(__a)), + _M_buckets(), + _M_bucket_count(__ht._M_bucket_count), + _M_element_count(__ht._M_element_count), + _M_rehash_policy(__ht._M_rehash_policy) + { + if (__ht._M_node_allocator() == this->_M_node_allocator()) + { + if (__ht._M_uses_single_bucket()) + { + _M_buckets = &_M_single_bucket; + _M_single_bucket = __ht._M_single_bucket; + } + else + _M_buckets = __ht._M_buckets; + + _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt; + // Update, if necessary, bucket pointing to before begin that hasn't + // moved. + if (_M_begin()) + _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; + __ht._M_reset(); + } + else + { + _M_assign(__ht, + [this](__node_type* __n) + { + return this->_M_allocate_node( + std::move_if_noexcept(__n->_M_v())); + }); + __ht.clear(); + } + } + + template + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + ~_Hashtable() noexcept + { + clear(); + if (_M_buckets) + _M_deallocate_buckets(); + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + swap(_Hashtable& __x) + noexcept(__node_alloc_traits::_S_nothrow_swap()) + { + // The only base class with member variables is hash_code_base. + // We define _Hash_code_base::_M_swap because different + // specializations have different members. + this->_M_swap(__x); + + __alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator()); + std::swap(_M_rehash_policy, __x._M_rehash_policy); + + // Deal properly with potentially moved instances. + if (this->_M_uses_single_bucket()) + { + if (!__x._M_uses_single_bucket()) + { + _M_buckets = __x._M_buckets; + __x._M_buckets = &__x._M_single_bucket; + } + } + else if (__x._M_uses_single_bucket()) + { + __x._M_buckets = _M_buckets; + _M_buckets = &_M_single_bucket; + } + else + std::swap(_M_buckets, __x._M_buckets); + + std::swap(_M_bucket_count, __x._M_bucket_count); + std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt); + std::swap(_M_element_count, __x._M_element_count); + std::swap(_M_single_bucket, __x._M_single_bucket); + + // Fix buckets containing the _M_before_begin pointers that can't be + // swapped. + if (_M_begin()) + _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; + + if (__x._M_begin()) + __x._M_buckets[__x._M_bucket_index(__x._M_begin())] + = &__x._M_before_begin; + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + __rehash_policy(const _RehashPolicy& __pol) + { + auto __do_rehash = + __pol._M_need_rehash(_M_bucket_count, _M_element_count, 0); + if (__do_rehash.first) + _M_rehash(__do_rehash.second, _M_rehash_policy._M_state()); + _M_rehash_policy = __pol; + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + find(const key_type& __k) + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __n = _M_bucket_index(__k, __code); + __node_type* __p = _M_find_node(__n, __k, __code); + return __p ? iterator(__p) : end(); + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::const_iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + find(const key_type& __k) const + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __n = _M_bucket_index(__k, __code); + __node_type* __p = _M_find_node(__n, __k, __code); + return __p ? const_iterator(__p) : end(); + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::size_type + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + count(const key_type& __k) const + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __n = _M_bucket_index(__k, __code); + __node_type* __p = _M_bucket_begin(__n); + if (!__p) + return 0; + + std::size_t __result = 0; + for (;; __p = __p->_M_next()) + { + if (this->_M_equals(__k, __code, __p)) + ++__result; + else if (__result) + // All equivalent values are next to each other, if we + // found a non-equivalent value after an equivalent one it + // means that we won't find any new equivalent value. + break; + if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n) + break; + } + return __result; + } + + template + std::pair::iterator, + typename _Hashtable<_Key, _Value, _Alloc, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + _Traits>::iterator> + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + equal_range(const key_type& __k) + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __n = _M_bucket_index(__k, __code); + __node_type* __p = _M_find_node(__n, __k, __code); + + if (__p) + { + __node_type* __p1 = __p->_M_next(); + while (__p1 && _M_bucket_index(__p1) == __n + && this->_M_equals(__k, __code, __p1)) + __p1 = __p1->_M_next(); + + return std::make_pair(iterator(__p), iterator(__p1)); + } + else + return std::make_pair(end(), end()); + } + + template + std::pair::const_iterator, + typename _Hashtable<_Key, _Value, _Alloc, + _ExtractKey, _Equal, _H1, + _H2, _Hash, _RehashPolicy, + _Traits>::const_iterator> + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + equal_range(const key_type& __k) const + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __n = _M_bucket_index(__k, __code); + __node_type* __p = _M_find_node(__n, __k, __code); + + if (__p) + { + __node_type* __p1 = __p->_M_next(); + while (__p1 && _M_bucket_index(__p1) == __n + && this->_M_equals(__k, __code, __p1)) + __p1 = __p1->_M_next(); + + return std::make_pair(const_iterator(__p), const_iterator(__p1)); + } + else + return std::make_pair(end(), end()); + } + + // Find the node whose key compares equal to k in the bucket n. + // Return nullptr if no node is found. + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + _Traits>::__node_base* + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_find_before_node(size_type __n, const key_type& __k, + __hash_code __code) const + { + __node_base* __prev_p = _M_buckets[__n]; + if (!__prev_p) + return nullptr; + + for (__node_type* __p = static_cast<__node_type*>(__prev_p->_M_nxt);; + __p = __p->_M_next()) + { + if (this->_M_equals(__k, __code, __p)) + return __prev_p; + + if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n) + break; + __prev_p = __p; + } + return nullptr; + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_insert_bucket_begin(size_type __bkt, __node_type* __node) + { + if (_M_buckets[__bkt]) + { + // Bucket is not empty, we just need to insert the new node + // after the bucket before begin. + __node->_M_nxt = _M_buckets[__bkt]->_M_nxt; + _M_buckets[__bkt]->_M_nxt = __node; + } + else + { + // The bucket is empty, the new node is inserted at the + // beginning of the singly-linked list and the bucket will + // contain _M_before_begin pointer. + __node->_M_nxt = _M_before_begin._M_nxt; + _M_before_begin._M_nxt = __node; + if (__node->_M_nxt) + // We must update former begin bucket that is pointing to + // _M_before_begin. + _M_buckets[_M_bucket_index(__node->_M_next())] = __node; + _M_buckets[__bkt] = &_M_before_begin; + } + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_remove_bucket_begin(size_type __bkt, __node_type* __next, + size_type __next_bkt) + { + if (!__next || __next_bkt != __bkt) + { + // Bucket is now empty + // First update next bucket if any + if (__next) + _M_buckets[__next_bkt] = _M_buckets[__bkt]; + + // Second update before begin node if necessary + if (&_M_before_begin == _M_buckets[__bkt]) + _M_before_begin._M_nxt = __next; + _M_buckets[__bkt] = nullptr; + } + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + _Traits>::__node_base* + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_get_previous_node(size_type __bkt, __node_base* __n) + { + __node_base* __prev_n = _M_buckets[__bkt]; + while (__prev_n->_M_nxt != __n) + __prev_n = __prev_n->_M_nxt; + return __prev_n; + } + + template + template + std::pair::iterator, bool> + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_emplace(std::true_type, _Args&&... __args) + { + // First build the node to get access to the hash code + __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...); + const key_type& __k = this->_M_extract()(__node->_M_v()); + __hash_code __code; + __try + { + __code = this->_M_hash_code(__k); + } + __catch(...) + { + this->_M_deallocate_node(__node); + __throw_exception_again; + } + + size_type __bkt = _M_bucket_index(__k, __code); + if (__node_type* __p = _M_find_node(__bkt, __k, __code)) + { + // There is already an equivalent node, no insertion + this->_M_deallocate_node(__node); + return std::make_pair(iterator(__p), false); + } + + // Insert the node + return std::make_pair(_M_insert_unique_node(__bkt, __code, __node), + true); + } + + template + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_emplace(const_iterator __hint, std::false_type, _Args&&... __args) + { + // First build the node to get its hash code. + __node_type* __node = + this->_M_allocate_node(std::forward<_Args>(__args)...); + + __hash_code __code; + __try + { + __code = this->_M_hash_code(this->_M_extract()(__node->_M_v())); + } + __catch(...) + { + this->_M_deallocate_node(__node); + __throw_exception_again; + } + + return _M_insert_multi_node(__hint._M_cur, __code, __node); + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_insert_unique_node(size_type __bkt, __hash_code __code, + __node_type* __node) + { + const __rehash_state& __saved_state = _M_rehash_policy._M_state(); + std::pair __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1); + + __try + { + if (__do_rehash.first) + { + _M_rehash(__do_rehash.second, __saved_state); + __bkt = _M_bucket_index(this->_M_extract()(__node->_M_v()), __code); + } + + this->_M_store_code(__node, __code); + + // Always insert at the beginning of the bucket. + _M_insert_bucket_begin(__bkt, __node); + ++_M_element_count; + return iterator(__node); + } + __catch(...) + { + this->_M_deallocate_node(__node); + __throw_exception_again; + } + } + + // Insert node, in bucket bkt if no rehash (assumes no element with its key + // already present). Take ownership of the node, deallocate it on exception. + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_insert_multi_node(__node_type* __hint, __hash_code __code, + __node_type* __node) + { + const __rehash_state& __saved_state = _M_rehash_policy._M_state(); + std::pair __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1); + + __try + { + if (__do_rehash.first) + _M_rehash(__do_rehash.second, __saved_state); + + this->_M_store_code(__node, __code); + const key_type& __k = this->_M_extract()(__node->_M_v()); + size_type __bkt = _M_bucket_index(__k, __code); + + // Find the node before an equivalent one or use hint if it exists and + // if it is equivalent. + __node_base* __prev + = __builtin_expect(__hint != nullptr, false) + && this->_M_equals(__k, __code, __hint) + ? __hint + : _M_find_before_node(__bkt, __k, __code); + if (__prev) + { + // Insert after the node before the equivalent one. + __node->_M_nxt = __prev->_M_nxt; + __prev->_M_nxt = __node; + if (__builtin_expect(__prev == __hint, false)) + // hint might be the last bucket node, in this case we need to + // update next bucket. + if (__node->_M_nxt + && !this->_M_equals(__k, __code, __node->_M_next())) + { + size_type __next_bkt = _M_bucket_index(__node->_M_next()); + if (__next_bkt != __bkt) + _M_buckets[__next_bkt] = __node; + } + } + else + // The inserted node has no equivalent in the + // hashtable. We must insert the new node at the + // beginning of the bucket to preserve equivalent + // elements' relative positions. + _M_insert_bucket_begin(__bkt, __node); + ++_M_element_count; + return iterator(__node); + } + __catch(...) + { + this->_M_deallocate_node(__node); + __throw_exception_again; + } + } + + // Insert v if no element with its key is already present. + template + template + std::pair::iterator, bool> + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_insert(_Arg&& __v, const _NodeGenerator& __node_gen, std::true_type) + { + const key_type& __k = this->_M_extract()(__v); + __hash_code __code = this->_M_hash_code(__k); + size_type __bkt = _M_bucket_index(__k, __code); + + __node_type* __n = _M_find_node(__bkt, __k, __code); + if (__n) + return std::make_pair(iterator(__n), false); + + __n = __node_gen(std::forward<_Arg>(__v)); + return std::make_pair(_M_insert_unique_node(__bkt, __code, __n), true); + } + + // Insert v unconditionally. + template + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_insert(const_iterator __hint, _Arg&& __v, + const _NodeGenerator& __node_gen, + std::false_type) + { + // First compute the hash code so that we don't do anything if it + // throws. + __hash_code __code = this->_M_hash_code(this->_M_extract()(__v)); + + // Second allocate new node so that we don't rehash if it throws. + __node_type* __node = __node_gen(std::forward<_Arg>(__v)); + + return _M_insert_multi_node(__hint._M_cur, __code, __node); + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + erase(const_iterator __it) + { + __node_type* __n = __it._M_cur; + std::size_t __bkt = _M_bucket_index(__n); + + // Look for previous node to unlink it from the erased one, this + // is why we need buckets to contain the before begin to make + // this search fast. + __node_base* __prev_n = _M_get_previous_node(__bkt, __n); + return _M_erase(__bkt, __prev_n, __n); + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_erase(size_type __bkt, __node_base* __prev_n, __node_type* __n) + { + if (__prev_n == _M_buckets[__bkt]) + _M_remove_bucket_begin(__bkt, __n->_M_next(), + __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0); + else if (__n->_M_nxt) + { + size_type __next_bkt = _M_bucket_index(__n->_M_next()); + if (__next_bkt != __bkt) + _M_buckets[__next_bkt] = __prev_n; + } + + __prev_n->_M_nxt = __n->_M_nxt; + iterator __result(__n->_M_next()); + this->_M_deallocate_node(__n); + --_M_element_count; + + return __result; + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::size_type + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_erase(std::true_type, const key_type& __k) + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __bkt = _M_bucket_index(__k, __code); + + // Look for the node before the first matching node. + __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code); + if (!__prev_n) + return 0; + + // We found a matching node, erase it. + __node_type* __n = static_cast<__node_type*>(__prev_n->_M_nxt); + _M_erase(__bkt, __prev_n, __n); + return 1; + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::size_type + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_erase(std::false_type, const key_type& __k) + { + __hash_code __code = this->_M_hash_code(__k); + std::size_t __bkt = _M_bucket_index(__k, __code); + + // Look for the node before the first matching node. + __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code); + if (!__prev_n) + return 0; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 526. Is it undefined if a function in the standard changes + // in parameters? + // We use one loop to find all matching nodes and another to deallocate + // them so that the key stays valid during the first loop. It might be + // invalidated indirectly when destroying nodes. + __node_type* __n = static_cast<__node_type*>(__prev_n->_M_nxt); + __node_type* __n_last = __n; + std::size_t __n_last_bkt = __bkt; + do + { + __n_last = __n_last->_M_next(); + if (!__n_last) + break; + __n_last_bkt = _M_bucket_index(__n_last); + } + while (__n_last_bkt == __bkt && this->_M_equals(__k, __code, __n_last)); + + // Deallocate nodes. + size_type __result = 0; + do + { + __node_type* __p = __n->_M_next(); + this->_M_deallocate_node(__n); + __n = __p; + ++__result; + --_M_element_count; + } + while (__n != __n_last); + + if (__prev_n == _M_buckets[__bkt]) + _M_remove_bucket_begin(__bkt, __n_last, __n_last_bkt); + else if (__n_last && __n_last_bkt != __bkt) + _M_buckets[__n_last_bkt] = __prev_n; + __prev_n->_M_nxt = __n_last; + return __result; + } + + template + typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, + _Traits>::iterator + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + erase(const_iterator __first, const_iterator __last) + { + __node_type* __n = __first._M_cur; + __node_type* __last_n = __last._M_cur; + if (__n == __last_n) + return iterator(__n); + + std::size_t __bkt = _M_bucket_index(__n); + + __node_base* __prev_n = _M_get_previous_node(__bkt, __n); + bool __is_bucket_begin = __n == _M_bucket_begin(__bkt); + std::size_t __n_bkt = __bkt; + for (;;) + { + do + { + __node_type* __tmp = __n; + __n = __n->_M_next(); + this->_M_deallocate_node(__tmp); + --_M_element_count; + if (!__n) + break; + __n_bkt = _M_bucket_index(__n); + } + while (__n != __last_n && __n_bkt == __bkt); + if (__is_bucket_begin) + _M_remove_bucket_begin(__bkt, __n, __n_bkt); + if (__n == __last_n) + break; + __is_bucket_begin = true; + __bkt = __n_bkt; + } + + if (__n && (__n_bkt != __bkt || __is_bucket_begin)) + _M_buckets[__n_bkt] = __prev_n; + __prev_n->_M_nxt = __n; + return iterator(__n); + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + clear() noexcept + { + this->_M_deallocate_nodes(_M_begin()); + __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type)); + _M_element_count = 0; + _M_before_begin._M_nxt = nullptr; + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + rehash(size_type __n) + { + const __rehash_state& __saved_state = _M_rehash_policy._M_state(); + std::size_t __buckets + = std::max(_M_rehash_policy._M_bkt_for_elements(_M_element_count + 1), + __n); + __buckets = _M_rehash_policy._M_next_bkt(__buckets); + + if (__buckets != _M_bucket_count) + _M_rehash(__buckets, __saved_state); + else + // No rehash, restore previous state to keep a consistent state. + _M_rehash_policy._M_reset(__saved_state); + } + + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_rehash(size_type __n, const __rehash_state& __state) + { + __try + { + _M_rehash_aux(__n, __unique_keys()); + } + __catch(...) + { + // A failure here means that buckets allocation failed. We only + // have to restore hash policy previous state. + _M_rehash_policy._M_reset(__state); + __throw_exception_again; + } + } + + // Rehash when there is no equivalent elements. + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_rehash_aux(size_type __n, std::true_type) + { + __bucket_type* __new_buckets = _M_allocate_buckets(__n); + __node_type* __p = _M_begin(); + _M_before_begin._M_nxt = nullptr; + std::size_t __bbegin_bkt = 0; + while (__p) + { + __node_type* __next = __p->_M_next(); + std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n); + if (!__new_buckets[__bkt]) + { + __p->_M_nxt = _M_before_begin._M_nxt; + _M_before_begin._M_nxt = __p; + __new_buckets[__bkt] = &_M_before_begin; + if (__p->_M_nxt) + __new_buckets[__bbegin_bkt] = __p; + __bbegin_bkt = __bkt; + } + else + { + __p->_M_nxt = __new_buckets[__bkt]->_M_nxt; + __new_buckets[__bkt]->_M_nxt = __p; + } + __p = __next; + } + + _M_deallocate_buckets(); + _M_bucket_count = __n; + _M_buckets = __new_buckets; + } + + // Rehash when there can be equivalent elements, preserve their relative + // order. + template + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>:: + _M_rehash_aux(size_type __n, std::false_type) + { + __bucket_type* __new_buckets = _M_allocate_buckets(__n); + + __node_type* __p = _M_begin(); + _M_before_begin._M_nxt = nullptr; + std::size_t __bbegin_bkt = 0; + std::size_t __prev_bkt = 0; + __node_type* __prev_p = nullptr; + bool __check_bucket = false; + + while (__p) + { + __node_type* __next = __p->_M_next(); + std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n); + + if (__prev_p && __prev_bkt == __bkt) + { + // Previous insert was already in this bucket, we insert after + // the previously inserted one to preserve equivalent elements + // relative order. + __p->_M_nxt = __prev_p->_M_nxt; + __prev_p->_M_nxt = __p; + + // Inserting after a node in a bucket require to check that we + // haven't change the bucket last node, in this case next + // bucket containing its before begin node must be updated. We + // schedule a check as soon as we move out of the sequence of + // equivalent nodes to limit the number of checks. + __check_bucket = true; + } + else + { + if (__check_bucket) + { + // Check if we shall update the next bucket because of + // insertions into __prev_bkt bucket. + if (__prev_p->_M_nxt) + { + std::size_t __next_bkt + = __hash_code_base::_M_bucket_index(__prev_p->_M_next(), + __n); + if (__next_bkt != __prev_bkt) + __new_buckets[__next_bkt] = __prev_p; + } + __check_bucket = false; + } + + if (!__new_buckets[__bkt]) + { + __p->_M_nxt = _M_before_begin._M_nxt; + _M_before_begin._M_nxt = __p; + __new_buckets[__bkt] = &_M_before_begin; + if (__p->_M_nxt) + __new_buckets[__bbegin_bkt] = __p; + __bbegin_bkt = __bkt; + } + else + { + __p->_M_nxt = __new_buckets[__bkt]->_M_nxt; + __new_buckets[__bkt]->_M_nxt = __p; + } + } + __prev_p = __p; + __prev_bkt = __bkt; + __p = __next; + } + + if (__check_bucket && __prev_p->_M_nxt) + { + std::size_t __next_bkt + = __hash_code_base::_M_bucket_index(__prev_p->_M_next(), __n); + if (__next_bkt != __prev_bkt) + __new_buckets[__next_bkt] = __prev_p; + } + + _M_deallocate_buckets(); + _M_bucket_count = __n; + _M_buckets = __new_buckets; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // _HASHTABLE_H diff --git a/loader/include/Geode/c++stl/gnustl/hashtable_policy.h b/loader/include/Geode/c++stl/gnustl/hashtable_policy.h new file mode 100644 index 00000000..a90edd36 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/hashtable_policy.h @@ -0,0 +1,2163 @@ +// Internal policy header for unordered_set and unordered_map -*- C++ -*- + +// Copyright (C) 2010-2014 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 +// . + +/** @file bits/hashtable_policy.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. + * @headername{unordered_map,unordered_set} + */ + +#pragma once + +#include "c++config.h" +#include "exception_defines.h" +#include "ext/aligned_buffer.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + class _Hashtable; + +_GLIBCXX_END_NAMESPACE_VERSION + +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup hashtable-detail Base and Implementation Classes + * @ingroup unordered_associative_containers + * @{ + */ + template + struct _Hashtable_base; + + // Helper function: return distance(first, last) for forward + // iterators, or 0 for input iterators. + template + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last, + std::input_iterator_tag) + { return 0; } + + template + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last, + std::forward_iterator_tag) + { return std::distance(__first, __last); } + + template + inline typename std::iterator_traits<_Iterator>::difference_type + __distance_fw(_Iterator __first, _Iterator __last) + { + typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag; + return __distance_fw(__first, __last, _Tag()); + } + + // Helper type used to detect whether the hash functor is noexcept. + template + struct __is_noexcept_hash : std::integral_constant()(std::declval()))> + { }; + + struct _Identity + { + template + _Tp&& + operator()(_Tp&& __x) const + { return std::forward<_Tp>(__x); } + }; + + struct _Select1st + { + template + auto + operator()(_Tp&& __x) const + -> decltype(std::get<0>(std::forward<_Tp>(__x))) + { return std::get<0>(std::forward<_Tp>(__x)); } + }; + + template + struct _Hashtable_alloc; + + // Functor recycling a pool of nodes and using allocation once the pool is + // empty. + template + struct _ReuseOrAllocNode + { + private: + using __node_alloc_type = _NodeAlloc; + using __hashtable_alloc = _Hashtable_alloc<__node_alloc_type>; + using __value_alloc_type = typename __hashtable_alloc::__value_alloc_type; + using __value_alloc_traits = + typename __hashtable_alloc::__value_alloc_traits; + using __node_alloc_traits = + typename __hashtable_alloc::__node_alloc_traits; + using __node_type = typename __hashtable_alloc::__node_type; + + public: + _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h) + : _M_nodes(__nodes), _M_h(__h) { } + _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete; + + ~_ReuseOrAllocNode() + { _M_h._M_deallocate_nodes(_M_nodes); } + + template + __node_type* + operator()(_Arg&& __arg) const + { + if (_M_nodes) + { + __node_type* __node = _M_nodes; + _M_nodes = _M_nodes->_M_next(); + __node->_M_nxt = nullptr; + __value_alloc_type __a(_M_h._M_node_allocator()); + __value_alloc_traits::destroy(__a, __node->_M_valptr()); + __try + { + __value_alloc_traits::construct(__a, __node->_M_valptr(), + std::forward<_Arg>(__arg)); + } + __catch(...) + { + __node->~__node_type(); + __node_alloc_traits::deallocate(_M_h._M_node_allocator(), + __node, 1); + __throw_exception_again; + } + return __node; + } + return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); + } + + private: + mutable __node_type* _M_nodes; + __hashtable_alloc& _M_h; + }; + + // Functor similar to the previous one but without any pool of nodes to + // recycle. + template + struct _AllocNode + { + private: + using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>; + using __node_type = typename __hashtable_alloc::__node_type; + + public: + _AllocNode(__hashtable_alloc& __h) + : _M_h(__h) { } + + template + __node_type* + operator()(_Arg&& __arg) const + { return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); } + + private: + __hashtable_alloc& _M_h; + }; + + // Auxiliary types used for all instantiations of _Hashtable nodes + // and iterators. + + /** + * struct _Hashtable_traits + * + * Important traits for hash tables. + * + * @tparam _Cache_hash_code Boolean value. True if the value of + * the hash function is stored along with the value. This is a + * time-space tradeoff. Storing it may improve lookup speed by + * reducing the number of times we need to call the _Equal + * function. + * + * @tparam _Constant_iterators Boolean value. True if iterator and + * const_iterator are both constant iterator types. This is true + * for unordered_set and unordered_multiset, false for + * unordered_map and unordered_multimap. + * + * @tparam _Unique_keys Boolean value. True if the return value + * of _Hashtable::count(k) is always at most one, false if it may + * be an arbitrary number. This is true for unordered_set and + * unordered_map, false for unordered_multiset and + * unordered_multimap. + */ + template + struct _Hashtable_traits + { + template + using __bool_constant = std::integral_constant; + + using __hash_cached = __bool_constant<_Cache_hash_code>; + using __constant_iterators = __bool_constant<_Constant_iterators>; + using __unique_keys = __bool_constant<_Unique_keys>; + }; + + /** + * struct _Hash_node_base + * + * Nodes, used to wrap elements stored in the hash table. A policy + * template parameter of class template _Hashtable controls whether + * nodes also store a hash code. In some cases (e.g. strings) this + * may be a performance win. + */ + struct _Hash_node_base + { + _Hash_node_base* _M_nxt; + + _Hash_node_base() noexcept : _M_nxt() { } + + _Hash_node_base(_Hash_node_base* __next) noexcept : _M_nxt(__next) { } + }; + + /** + * struct _Hash_node_value_base + * + * Node type with the value to store. + */ + template + struct _Hash_node_value_base : _Hash_node_base + { + typedef _Value value_type; + + __gnu_cxx::__aligned_buffer<_Value> _M_storage; + + _Value* + _M_valptr() noexcept + { return _M_storage._M_ptr(); } + + const _Value* + _M_valptr() const noexcept + { return _M_storage._M_ptr(); } + + _Value& + _M_v() noexcept + { return *_M_valptr(); } + + const _Value& + _M_v() const noexcept + { return *_M_valptr(); } + }; + + /** + * Primary template struct _Hash_node. + */ + template + struct _Hash_node; + + /** + * Specialization for nodes with caches, struct _Hash_node. + * + * Base class is __detail::_Hash_node_value_base. + */ + template + struct _Hash_node<_Value, true> : _Hash_node_value_base<_Value> + { + std::size_t _M_hash_code; + + _Hash_node* + _M_next() const noexcept + { return static_cast<_Hash_node*>(this->_M_nxt); } + }; + + /** + * Specialization for nodes without caches, struct _Hash_node. + * + * Base class is __detail::_Hash_node_value_base. + */ + template + struct _Hash_node<_Value, false> : _Hash_node_value_base<_Value> + { + _Hash_node* + _M_next() const noexcept + { return static_cast<_Hash_node*>(this->_M_nxt); } + }; + + /// Base class for node iterators. + template + struct _Node_iterator_base + { + using __node_type = _Hash_node<_Value, _Cache_hash_code>; + + __node_type* _M_cur; + + _Node_iterator_base(__node_type* __p) noexcept + : _M_cur(__p) { } + + void + _M_incr() noexcept + { _M_cur = _M_cur->_M_next(); } + }; + + template + inline bool + operator==(const _Node_iterator_base<_Value, _Cache_hash_code>& __x, + const _Node_iterator_base<_Value, _Cache_hash_code >& __y) + noexcept + { return __x._M_cur == __y._M_cur; } + + template + inline bool + operator!=(const _Node_iterator_base<_Value, _Cache_hash_code>& __x, + const _Node_iterator_base<_Value, _Cache_hash_code>& __y) + noexcept + { return __x._M_cur != __y._M_cur; } + + /// Node iterators, used to iterate through all the hashtable. + template + struct _Node_iterator + : public _Node_iterator_base<_Value, __cache> + { + private: + using __base_type = _Node_iterator_base<_Value, __cache>; + using __node_type = typename __base_type::__node_type; + + public: + typedef _Value value_type; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + using pointer = typename std::conditional<__constant_iterators, + const _Value*, _Value*>::type; + + using reference = typename std::conditional<__constant_iterators, + const _Value&, _Value&>::type; + + _Node_iterator() noexcept + : __base_type(0) { } + + explicit + _Node_iterator(__node_type* __p) noexcept + : __base_type(__p) { } + + reference + operator*() const noexcept + { return this->_M_cur->_M_v(); } + + pointer + operator->() const noexcept + { return this->_M_cur->_M_valptr(); } + + _Node_iterator& + operator++() noexcept + { + this->_M_incr(); + return *this; + } + + _Node_iterator + operator++(int) noexcept + { + _Node_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + /// Node const_iterators, used to iterate through all the hashtable. + template + struct _Node_const_iterator + : public _Node_iterator_base<_Value, __cache> + { + private: + using __base_type = _Node_iterator_base<_Value, __cache>; + using __node_type = typename __base_type::__node_type; + + public: + typedef _Value value_type; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + typedef const _Value* pointer; + typedef const _Value& reference; + + _Node_const_iterator() noexcept + : __base_type(0) { } + + explicit + _Node_const_iterator(__node_type* __p) noexcept + : __base_type(__p) { } + + _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators, + __cache>& __x) noexcept + : __base_type(__x._M_cur) { } + + reference + operator*() const noexcept + { return this->_M_cur->_M_v(); } + + pointer + operator->() const noexcept + { return this->_M_cur->_M_valptr(); } + + _Node_const_iterator& + operator++() noexcept + { + this->_M_incr(); + return *this; + } + + _Node_const_iterator + operator++(int) noexcept + { + _Node_const_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + // Many of class template _Hashtable's template parameters are policy + // classes. These are defaults for the policies. + + /// Default range hashing function: use division to fold a large number + /// into the range [0, N). + struct _Mod_range_hashing + { + typedef std::size_t first_argument_type; + typedef std::size_t second_argument_type; + typedef std::size_t result_type; + + result_type + operator()(first_argument_type __num, + second_argument_type __den) const noexcept + { return __num % __den; } + }; + + /// Default ranged hash function H. In principle it should be a + /// function object composed from objects of type H1 and H2 such that + /// h(k, N) = h2(h1(k), N), but that would mean making extra copies of + /// h1 and h2. So instead we'll just use a tag to tell class template + /// hashtable to do that composition. + struct _Default_ranged_hash { }; + + /// Default value for rehash policy. Bucket size is (usually) the + /// smallest prime that keeps the load factor small enough. + struct _Prime_rehash_policy + { + _Prime_rehash_policy(float __z = 1.0) + : _M_max_load_factor(__z), _M_next_resize(0) { } + + float + max_load_factor() const noexcept + { return _M_max_load_factor; } + + // Return a bucket size no smaller than n. + std::size_t + _M_next_bkt(std::size_t __n) const; + + // Return a bucket count appropriate for n elements + std::size_t + _M_bkt_for_elements(std::size_t __n) const + { return __builtin_ceil(__n / (long double)_M_max_load_factor); } + + // __n_bkt is current bucket count, __n_elt is current element count, + // and __n_ins is number of elements to be inserted. Do we need to + // increase bucket count? If so, return make_pair(true, n), where n + // is the new bucket count. If not, return make_pair(false, 0). + std::pair + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) const; + + typedef std::size_t _State; + + _State + _M_state() const + { return _M_next_resize; } + + void + _M_reset() noexcept + { _M_next_resize = 0; } + + void + _M_reset(_State __state) + { _M_next_resize = __state; } + + enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 }; + + static const std::size_t _S_growth_factor = 2; + + float _M_max_load_factor; + mutable std::size_t _M_next_resize; + }; + + // Base classes for std::_Hashtable. We define these base classes + // because in some cases we want to do different things depending on + // the value of a policy class. In some cases the policy class + // affects which member functions and nested typedefs are defined; + // we handle that by specializing base class templates. Several of + // the base class templates need to access other members of class + // template _Hashtable, so we use a variant of the "Curiously + // Recurring Template Pattern" (CRTP) technique. + + /** + * Primary class template _Map_base. + * + * If the hashtable has a value type of the form pair and a + * key extraction policy (_ExtractKey) that returns the first part + * of the pair, the hashtable gets a mapped_type typedef. If it + * satisfies those criteria and also has unique keys, then it also + * gets an operator[]. + */ + template + struct _Map_base { }; + + /// Partial specialization, __unique_keys set to false. + template + struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, false> + { + using mapped_type = typename std::tuple_element<1, _Pair>::type; + }; + + /// Partial specialization, __unique_keys set to true. + template + struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true> + { + private: + using __hashtable_base = __detail::_Hashtable_base<_Key, _Pair, + _Select1st, + _Equal, _H1, _H2, _Hash, + _Traits>; + + using __hashtable = _Hashtable<_Key, _Pair, _Alloc, + _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>; + + using __hash_code = typename __hashtable_base::__hash_code; + using __node_type = typename __hashtable_base::__node_type; + + public: + using key_type = typename __hashtable_base::key_type; + using iterator = typename __hashtable_base::iterator; + using mapped_type = typename std::tuple_element<1, _Pair>::type; + + mapped_type& + operator[](const key_type& __k); + + mapped_type& + operator[](key_type&& __k); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 761. unordered_map needs an at() member function. + mapped_type& + at(const key_type& __k); + + const mapped_type& + at(const key_type& __k) const; + }; + + template + typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true> + ::mapped_type& + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: + operator[](const key_type& __k) + { + __hashtable* __h = static_cast<__hashtable*>(this); + __hash_code __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code); + __node_type* __p = __h->_M_find_node(__n, __k, __code); + + if (!__p) + { + __p = __h->_M_allocate_node(std::piecewise_construct, + std::tuple(__k), + std::tuple<>()); + return __h->_M_insert_unique_node(__n, __code, __p)->second; + } + + return __p->_M_v().second; + } + + template + typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true> + ::mapped_type& + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: + operator[](key_type&& __k) + { + __hashtable* __h = static_cast<__hashtable*>(this); + __hash_code __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code); + __node_type* __p = __h->_M_find_node(__n, __k, __code); + + if (!__p) + { + __p = __h->_M_allocate_node(std::piecewise_construct, + std::forward_as_tuple(std::move(__k)), + std::tuple<>()); + return __h->_M_insert_unique_node(__n, __code, __p)->second; + } + + return __p->_M_v().second; + } + + template + typename _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true> + ::mapped_type& + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: + at(const key_type& __k) + { + __hashtable* __h = static_cast<__hashtable*>(this); + __hash_code __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code); + __node_type* __p = __h->_M_find_node(__n, __k, __code); + + if (!__p) + std::__throw_out_of_range(__N("_Map_base::at")); + return __p->_M_v().second; + } + + template + const typename _Map_base<_Key, _Pair, _Alloc, _Select1st, + _Equal, _H1, _H2, _Hash, _RehashPolicy, + _Traits, true>::mapped_type& + _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: + at(const key_type& __k) const + { + const __hashtable* __h = static_cast(this); + __hash_code __code = __h->_M_hash_code(__k); + std::size_t __n = __h->_M_bucket_index(__k, __code); + __node_type* __p = __h->_M_find_node(__n, __k, __code); + + if (!__p) + std::__throw_out_of_range(__N("_Map_base::at")); + return __p->_M_v().second; + } + + /** + * Primary class template _Insert_base. + * + * insert member functions appropriate to all _Hashtables. + */ + template + struct _Insert_base + { + protected: + using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + + using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _Traits>; + + using value_type = typename __hashtable_base::value_type; + using iterator = typename __hashtable_base::iterator; + using const_iterator = typename __hashtable_base::const_iterator; + using size_type = typename __hashtable_base::size_type; + + using __unique_keys = typename __hashtable_base::__unique_keys; + using __ireturn_type = typename __hashtable_base::__ireturn_type; + using __node_type = _Hash_node<_Value, _Traits::__hash_cached::value>; + using __node_alloc_type = + typename __alloctr_rebind<_Alloc, __node_type>::__type; + using __node_gen_type = _AllocNode<__node_alloc_type>; + + __hashtable& + _M_conjure_hashtable() + { return *(static_cast<__hashtable*>(this)); } + + template + void + _M_insert_range(_InputIterator __first, _InputIterator __last, + const _NodeGetter&); + + public: + __ireturn_type + insert(const value_type& __v) + { + __hashtable& __h = _M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return __h._M_insert(__v, __node_gen, __unique_keys()); + } + + iterator + insert(const_iterator __hint, const value_type& __v) + { + __hashtable& __h = _M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return __h._M_insert(__hint, __v, __node_gen, __unique_keys()); + } + + void + insert(std::initializer_list __l) + { this->insert(__l.begin(), __l.end()); } + + template + void + insert(_InputIterator __first, _InputIterator __last) + { + __hashtable& __h = _M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return _M_insert_range(__first, __last, __node_gen); + } + }; + + template + template + void + _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>:: + _M_insert_range(_InputIterator __first, _InputIterator __last, + const _NodeGetter& __node_gen) + { + using __rehash_type = typename __hashtable::__rehash_type; + using __rehash_state = typename __hashtable::__rehash_state; + using pair_type = std::pair; + + size_type __n_elt = __detail::__distance_fw(__first, __last); + + __hashtable& __h = _M_conjure_hashtable(); + __rehash_type& __rehash = __h._M_rehash_policy; + const __rehash_state& __saved_state = __rehash._M_state(); + pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count, + __h._M_element_count, + __n_elt); + + if (__do_rehash.first) + __h._M_rehash(__do_rehash.second, __saved_state); + + for (; __first != __last; ++__first) + __h._M_insert(*__first, __node_gen, __unique_keys()); + } + + /** + * Primary class template _Insert. + * + * Select insert member functions appropriate to _Hashtable policy choices. + */ + template + struct _Insert; + + /// Specialization. + template + struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits, true, true> + : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits> + { + using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + using value_type = typename __base_type::value_type; + using iterator = typename __base_type::iterator; + using const_iterator = typename __base_type::const_iterator; + + using __unique_keys = typename __base_type::__unique_keys; + using __hashtable = typename __base_type::__hashtable; + using __node_gen_type = typename __base_type::__node_gen_type; + + using __base_type::insert; + + std::pair + insert(value_type&& __v) + { + __hashtable& __h = this->_M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return __h._M_insert(std::move(__v), __node_gen, __unique_keys()); + } + + iterator + insert(const_iterator __hint, value_type&& __v) + { + __hashtable& __h = this->_M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return __h._M_insert(__hint, std::move(__v), __node_gen, + __unique_keys()); + } + }; + + /// Specialization. + template + struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits, true, false> + : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits> + { + using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + using value_type = typename __base_type::value_type; + using iterator = typename __base_type::iterator; + using const_iterator = typename __base_type::const_iterator; + + using __unique_keys = typename __base_type::__unique_keys; + using __hashtable = typename __base_type::__hashtable; + using __node_gen_type = typename __base_type::__node_gen_type; + + using __base_type::insert; + + iterator + insert(value_type&& __v) + { + __hashtable& __h = this->_M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return __h._M_insert(std::move(__v), __node_gen, __unique_keys()); + } + + iterator + insert(const_iterator __hint, value_type&& __v) + { + __hashtable& __h = this->_M_conjure_hashtable(); + __node_gen_type __node_gen(__h); + return __h._M_insert(__hint, std::move(__v), __node_gen, + __unique_keys()); + } + }; + + /// Specialization. + template + struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits, false, _Unique_keys> + : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits> + { + using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _RehashPolicy, _Traits>; + using value_type = typename __base_type::value_type; + using iterator = typename __base_type::iterator; + using const_iterator = typename __base_type::const_iterator; + + using __unique_keys = typename __base_type::__unique_keys; + using __hashtable = typename __base_type::__hashtable; + using __ireturn_type = typename __base_type::__ireturn_type; + + using __base_type::insert; + + template + using __is_cons = std::is_constructible; + + template + using _IFcons = std::enable_if<__is_cons<_Pair>::value>; + + template + using _IFconsp = typename _IFcons<_Pair>::type; + + template> + __ireturn_type + insert(_Pair&& __v) + { + __hashtable& __h = this->_M_conjure_hashtable(); + return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v)); + } + + template> + iterator + insert(const_iterator __hint, _Pair&& __v) + { + __hashtable& __h = this->_M_conjure_hashtable(); + return __h._M_emplace(__hint, __unique_keys(), + std::forward<_Pair>(__v)); + } + }; + + /** + * Primary class template _Rehash_base. + * + * Give hashtable the max_load_factor functions and reserve iff the + * rehash policy is _Prime_rehash_policy. + */ + template + struct _Rehash_base; + + /// Specialization. + template + struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _Prime_rehash_policy, _Traits> + { + using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, + _Equal, _H1, _H2, _Hash, + _Prime_rehash_policy, _Traits>; + + float + max_load_factor() const noexcept + { + const __hashtable* __this = static_cast(this); + return __this->__rehash_policy().max_load_factor(); + } + + void + max_load_factor(float __z) + { + __hashtable* __this = static_cast<__hashtable*>(this); + __this->__rehash_policy(_Prime_rehash_policy(__z)); + } + + void + reserve(std::size_t __n) + { + __hashtable* __this = static_cast<__hashtable*>(this); + __this->rehash(__builtin_ceil(__n / max_load_factor())); + } + }; + + /** + * Primary class template _Hashtable_ebo_helper. + * + * Helper class using EBO when it is not forbidden (the type is not + * final) and when it is worth it (the type is empty.) + */ + template + struct _Hashtable_ebo_helper; + + /// Specialization using EBO. + template + struct _Hashtable_ebo_helper<_Nm, _Tp, true> + : private _Tp + { + _Hashtable_ebo_helper() = default; + + template + _Hashtable_ebo_helper(_OtherTp&& __tp) + : _Tp(std::forward<_OtherTp>(__tp)) + { } + + static const _Tp& + _S_cget(const _Hashtable_ebo_helper& __eboh) + { return static_cast(__eboh); } + + static _Tp& + _S_get(_Hashtable_ebo_helper& __eboh) + { return static_cast<_Tp&>(__eboh); } + }; + + /// Specialization not using EBO. + template + struct _Hashtable_ebo_helper<_Nm, _Tp, false> + { + _Hashtable_ebo_helper() = default; + + template + _Hashtable_ebo_helper(_OtherTp&& __tp) + : _M_tp(std::forward<_OtherTp>(__tp)) + { } + + static const _Tp& + _S_cget(const _Hashtable_ebo_helper& __eboh) + { return __eboh._M_tp; } + + static _Tp& + _S_get(_Hashtable_ebo_helper& __eboh) + { return __eboh._M_tp; } + + private: + _Tp _M_tp; + }; + + /** + * Primary class template _Local_iterator_base. + * + * Base class for local iterators, used to iterate within a bucket + * but not between buckets. + */ + template + struct _Local_iterator_base; + + /** + * Primary class template _Hash_code_base. + * + * Encapsulates two policy issues that aren't quite orthogonal. + * (1) the difference between using a ranged hash function and using + * the combination of a hash function and a range-hashing function. + * In the former case we don't have such things as hash codes, so + * we have a dummy type as placeholder. + * (2) Whether or not we cache hash codes. Caching hash codes is + * meaningless if we have a ranged hash function. + * + * We also put the key extraction objects here, for convenience. + * Each specialization derives from one or more of the template + * parameters to benefit from Ebo. This is important as this type + * is inherited in some cases by the _Local_iterator_base type used + * to implement local_iterator and const_local_iterator. As with + * any iterator type we prefer to make it as small as possible. + * + * Primary template is unused except as a hook for specializations. + */ + template + struct _Hash_code_base; + + /// Specialization: ranged hash function, no caching hash codes. H1 + /// and H2 are provided but ignored. We define a dummy hash code type. + template + struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false> + : private _Hashtable_ebo_helper<0, _ExtractKey>, + private _Hashtable_ebo_helper<1, _Hash> + { + private: + using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>; + using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>; + + protected: + typedef void* __hash_code; + typedef _Hash_node<_Value, false> __node_type; + + // We need the default constructor for the local iterators. + _Hash_code_base() = default; + + _Hash_code_base(const _ExtractKey& __ex, const _H1&, const _H2&, + const _Hash& __h) + : __ebo_extract_key(__ex), __ebo_hash(__h) { } + + __hash_code + _M_hash_code(const _Key& __key) const + { return 0; } + + std::size_t + _M_bucket_index(const _Key& __k, __hash_code, std::size_t __n) const + { return _M_ranged_hash()(__k, __n); } + + std::size_t + _M_bucket_index(const __node_type* __p, std::size_t __n) const + noexcept( noexcept(std::declval()(std::declval(), + (std::size_t)0)) ) + { return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); } + + void + _M_store_code(__node_type*, __hash_code) const + { } + + void + _M_copy_code(__node_type*, const __node_type*) const + { } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract(), __x._M_extract()); + std::swap(_M_ranged_hash(), __x._M_ranged_hash()); + } + + const _ExtractKey& + _M_extract() const { return __ebo_extract_key::_S_cget(*this); } + + _ExtractKey& + _M_extract() { return __ebo_extract_key::_S_get(*this); } + + const _Hash& + _M_ranged_hash() const { return __ebo_hash::_S_cget(*this); } + + _Hash& + _M_ranged_hash() { return __ebo_hash::_S_get(*this); } + }; + + // No specialization for ranged hash function while caching hash codes. + // That combination is meaningless, and trying to do it is an error. + + /// Specialization: ranged hash function, cache hash codes. This + /// combination is meaningless, so we provide only a declaration + /// and no definition. + template + struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>; + + /// Specialization: hash function and range-hashing function, no + /// caching of hash codes. + /// Provides typedef and accessor required by C++ 11. + template + struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, + _Default_ranged_hash, false> + : private _Hashtable_ebo_helper<0, _ExtractKey>, + private _Hashtable_ebo_helper<1, _H1>, + private _Hashtable_ebo_helper<2, _H2> + { + private: + using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>; + using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>; + using __ebo_h2 = _Hashtable_ebo_helper<2, _H2>; + + // Gives the local iterator implementation access to _M_bucket_index(). + friend struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, + _Default_ranged_hash, false>; + + public: + typedef _H1 hasher; + + hasher + hash_function() const + { return _M_h1(); } + + protected: + typedef std::size_t __hash_code; + typedef _Hash_node<_Value, false> __node_type; + + // We need the default constructor for the local iterators. + _Hash_code_base() = default; + + _Hash_code_base(const _ExtractKey& __ex, + const _H1& __h1, const _H2& __h2, + const _Default_ranged_hash&) + : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { } + + __hash_code + _M_hash_code(const _Key& __k) const + { return _M_h1()(__k); } + + std::size_t + _M_bucket_index(const _Key&, __hash_code __c, std::size_t __n) const + { return _M_h2()(__c, __n); } + + std::size_t + _M_bucket_index(const __node_type* __p, std::size_t __n) const + noexcept( noexcept(std::declval()(std::declval())) + && noexcept(std::declval()((__hash_code)0, + (std::size_t)0)) ) + { return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); } + + void + _M_store_code(__node_type*, __hash_code) const + { } + + void + _M_copy_code(__node_type*, const __node_type*) const + { } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract(), __x._M_extract()); + std::swap(_M_h1(), __x._M_h1()); + std::swap(_M_h2(), __x._M_h2()); + } + + const _ExtractKey& + _M_extract() const { return __ebo_extract_key::_S_cget(*this); } + + _ExtractKey& + _M_extract() { return __ebo_extract_key::_S_get(*this); } + + const _H1& + _M_h1() const { return __ebo_h1::_S_cget(*this); } + + _H1& + _M_h1() { return __ebo_h1::_S_get(*this); } + + const _H2& + _M_h2() const { return __ebo_h2::_S_cget(*this); } + + _H2& + _M_h2() { return __ebo_h2::_S_get(*this); } + }; + + /// Specialization: hash function and range-hashing function, + /// caching hash codes. H is provided but ignored. Provides + /// typedef and accessor required by C++ 11. + template + struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, + _Default_ranged_hash, true> + : private _Hashtable_ebo_helper<0, _ExtractKey>, + private _Hashtable_ebo_helper<1, _H1>, + private _Hashtable_ebo_helper<2, _H2> + { + private: + // Gives the local iterator implementation access to _M_h2(). + friend struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, + _Default_ranged_hash, true>; + + using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>; + using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>; + using __ebo_h2 = _Hashtable_ebo_helper<2, _H2>; + + public: + typedef _H1 hasher; + + hasher + hash_function() const + { return _M_h1(); } + + protected: + typedef std::size_t __hash_code; + typedef _Hash_node<_Value, true> __node_type; + + _Hash_code_base(const _ExtractKey& __ex, + const _H1& __h1, const _H2& __h2, + const _Default_ranged_hash&) + : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { } + + __hash_code + _M_hash_code(const _Key& __k) const + { return _M_h1()(__k); } + + std::size_t + _M_bucket_index(const _Key&, __hash_code __c, + std::size_t __n) const + { return _M_h2()(__c, __n); } + + std::size_t + _M_bucket_index(const __node_type* __p, std::size_t __n) const + noexcept( noexcept(std::declval()((__hash_code)0, + (std::size_t)0)) ) + { return _M_h2()(__p->_M_hash_code, __n); } + + void + _M_store_code(__node_type* __n, __hash_code __c) const + { __n->_M_hash_code = __c; } + + void + _M_copy_code(__node_type* __to, const __node_type* __from) const + { __to->_M_hash_code = __from->_M_hash_code; } + + void + _M_swap(_Hash_code_base& __x) + { + std::swap(_M_extract(), __x._M_extract()); + std::swap(_M_h1(), __x._M_h1()); + std::swap(_M_h2(), __x._M_h2()); + } + + const _ExtractKey& + _M_extract() const { return __ebo_extract_key::_S_cget(*this); } + + _ExtractKey& + _M_extract() { return __ebo_extract_key::_S_get(*this); } + + const _H1& + _M_h1() const { return __ebo_h1::_S_cget(*this); } + + _H1& + _M_h1() { return __ebo_h1::_S_get(*this); } + + const _H2& + _M_h2() const { return __ebo_h2::_S_cget(*this); } + + _H2& + _M_h2() { return __ebo_h2::_S_get(*this); } + }; + + /** + * Primary class template _Equal_helper. + * + */ + template + struct _Equal_helper; + + /// Specialization. + template + struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType, true> + { + static bool + _S_equals(const _Equal& __eq, const _ExtractKey& __extract, + const _Key& __k, _HashCodeType __c, _Hash_node<_Value, true>* __n) + { return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); } + }; + + /// Specialization. + template + struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType, false> + { + static bool + _S_equals(const _Equal& __eq, const _ExtractKey& __extract, + const _Key& __k, _HashCodeType, _Hash_node<_Value, false>* __n) + { return __eq(__k, __extract(__n->_M_v())); } + }; + + + /// Partial specialization used when nodes contain a cached hash code. + template + struct _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, true> + : private _Hashtable_ebo_helper<0, _H2> + { + protected: + using __base_type = _Hashtable_ebo_helper<0, _H2>; + using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, true>; + + _Local_iterator_base() = default; + _Local_iterator_base(const __hash_code_base& __base, + _Hash_node<_Value, true>* __p, + std::size_t __bkt, std::size_t __bkt_count) + : __base_type(__base._M_h2()), + _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { } + + void + _M_incr() + { + _M_cur = _M_cur->_M_next(); + if (_M_cur) + { + std::size_t __bkt + = __base_type::_S_get(*this)(_M_cur->_M_hash_code, + _M_bucket_count); + if (__bkt != _M_bucket) + _M_cur = nullptr; + } + } + + _Hash_node<_Value, true>* _M_cur; + std::size_t _M_bucket; + std::size_t _M_bucket_count; + + public: + const void* + _M_curr() const { return _M_cur; } // for equality ops + + std::size_t + _M_get_bucket() const { return _M_bucket; } // for debug mode + }; + + // Uninitialized storage for a _Hash_code_base. + // This type is DefaultConstructible and Assignable even if the + // _Hash_code_base type isn't, so that _Local_iterator_base<..., false> + // can be DefaultConstructible and Assignable. + template::value> + struct _Hash_code_storage + { + __gnu_cxx::__aligned_buffer<_Tp> _M_storage; + + _Tp* + _M_h() { return _M_storage._M_ptr(); } + + const _Tp* + _M_h() const { return _M_storage._M_ptr(); } + }; + + // Empty partial specialization for empty _Hash_code_base types. + template + struct _Hash_code_storage<_Tp, true> + { + static_assert( std::is_empty<_Tp>::value, "Type must be empty" ); + + // As _Tp is an empty type there will be no bytes written/read through + // the cast pointer, so no strict-aliasing violation. + _Tp* + _M_h() { return reinterpret_cast<_Tp*>(this); } + + const _Tp* + _M_h() const { return reinterpret_cast(this); } + }; + + template + using __hash_code_for_local_iter + = _Hash_code_storage<_Hash_code_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, false>>; + + // Partial specialization used when hash codes are not cached + template + struct _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, false> + : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash> + { + protected: + using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, false>; + + _Local_iterator_base() : _M_bucket_count(-1) { } + + _Local_iterator_base(const __hash_code_base& __base, + _Hash_node<_Value, false>* __p, + std::size_t __bkt, std::size_t __bkt_count) + : _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) + { _M_init(__base); } + + ~_Local_iterator_base() + { + if (_M_bucket_count != -1) + _M_destroy(); + } + + _Local_iterator_base(const _Local_iterator_base& __iter) + : _M_cur(__iter._M_cur), _M_bucket(__iter._M_bucket), + _M_bucket_count(__iter._M_bucket_count) + { + if (_M_bucket_count != -1) + _M_init(*__iter._M_h()); + } + + _Local_iterator_base& + operator=(const _Local_iterator_base& __iter) + { + if (_M_bucket_count != -1) + _M_destroy(); + _M_cur = __iter._M_cur; + _M_bucket = __iter._M_bucket; + _M_bucket_count = __iter._M_bucket_count; + if (_M_bucket_count != -1) + _M_init(*__iter._M_h()); + return *this; + } + + void + _M_incr() + { + _M_cur = _M_cur->_M_next(); + if (_M_cur) + { + std::size_t __bkt = this->_M_h()->_M_bucket_index(_M_cur, + _M_bucket_count); + if (__bkt != _M_bucket) + _M_cur = nullptr; + } + } + + _Hash_node<_Value, false>* _M_cur; + std::size_t _M_bucket; + std::size_t _M_bucket_count; + + void + _M_init(const __hash_code_base& __base) + { ::new(this->_M_h()) __hash_code_base(__base); } + + void + _M_destroy() { this->_M_h()->~__hash_code_base(); } + + public: + const void* + _M_curr() const { return _M_cur; } // for equality ops and debug mode + + std::size_t + _M_get_bucket() const { return _M_bucket; } // for debug mode + }; + + template + inline bool + operator==(const _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache>& __x, + const _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache>& __y) + { return __x._M_curr() == __y._M_curr(); } + + template + inline bool + operator!=(const _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache>& __x, + const _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache>& __y) + { return __x._M_curr() != __y._M_curr(); } + + /// local iterators + template + struct _Local_iterator + : public _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache> + { + private: + using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache>; + using __hash_code_base = typename __base_type::__hash_code_base; + public: + typedef _Value value_type; + typedef typename std::conditional<__constant_iterators, + const _Value*, _Value*>::type + pointer; + typedef typename std::conditional<__constant_iterators, + const _Value&, _Value&>::type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Local_iterator() = default; + + _Local_iterator(const __hash_code_base& __base, + _Hash_node<_Value, __cache>* __p, + std::size_t __bkt, std::size_t __bkt_count) + : __base_type(__base, __p, __bkt, __bkt_count) + { } + + reference + operator*() const + { return this->_M_cur->_M_v(); } + + pointer + operator->() const + { return this->_M_cur->_M_valptr(); } + + _Local_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Local_iterator + operator++(int) + { + _Local_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + /// local const_iterators + template + struct _Local_const_iterator + : public _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache> + { + private: + using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, __cache>; + using __hash_code_base = typename __base_type::__hash_code_base; + + public: + typedef _Value value_type; + typedef const _Value* pointer; + typedef const _Value& reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Local_const_iterator() = default; + + _Local_const_iterator(const __hash_code_base& __base, + _Hash_node<_Value, __cache>* __p, + std::size_t __bkt, std::size_t __bkt_count) + : __base_type(__base, __p, __bkt, __bkt_count) + { } + + _Local_const_iterator(const _Local_iterator<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, + __constant_iterators, + __cache>& __x) + : __base_type(__x) + { } + + reference + operator*() const + { return this->_M_cur->_M_v(); } + + pointer + operator->() const + { return this->_M_cur->_M_valptr(); } + + _Local_const_iterator& + operator++() + { + this->_M_incr(); + return *this; + } + + _Local_const_iterator + operator++(int) + { + _Local_const_iterator __tmp(*this); + this->_M_incr(); + return __tmp; + } + }; + + /** + * Primary class template _Hashtable_base. + * + * Helper class adding management of _Equal functor to + * _Hash_code_base type. + * + * Base class templates are: + * - __detail::_Hash_code_base + * - __detail::_Hashtable_ebo_helper + */ + template + struct _Hashtable_base + : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, + _Traits::__hash_cached::value>, + private _Hashtable_ebo_helper<0, _Equal> + { + public: + typedef _Key key_type; + typedef _Value value_type; + typedef _Equal key_equal; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + using __traits_type = _Traits; + using __hash_cached = typename __traits_type::__hash_cached; + using __constant_iterators = typename __traits_type::__constant_iterators; + using __unique_keys = typename __traits_type::__unique_keys; + + using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, + _H1, _H2, _Hash, + __hash_cached::value>; + + using __hash_code = typename __hash_code_base::__hash_code; + using __node_type = typename __hash_code_base::__node_type; + + using iterator = __detail::_Node_iterator; + + using const_iterator = __detail::_Node_const_iterator; + + using local_iterator = __detail::_Local_iterator; + + using const_local_iterator = __detail::_Local_const_iterator; + + using __ireturn_type = typename std::conditional<__unique_keys::value, + std::pair, + iterator>::type; + private: + using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>; + using _EqualHelper = _Equal_helper<_Key, _Value, _ExtractKey, _Equal, + __hash_code, __hash_cached::value>; + + protected: + _Hashtable_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2, + const _Hash& __hash, const _Equal& __eq) + : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq) + { } + + bool + _M_equals(const _Key& __k, __hash_code __c, __node_type* __n) const + { + return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(), + __k, __c, __n); + } + + void + _M_swap(_Hashtable_base& __x) + { + __hash_code_base::_M_swap(__x); + std::swap(_M_eq(), __x._M_eq()); + } + + const _Equal& + _M_eq() const { return _EqualEBO::_S_cget(*this); } + + _Equal& + _M_eq() { return _EqualEBO::_S_get(*this); } + }; + + /** + * struct _Equality_base. + * + * Common types and functions for class _Equality. + */ + struct _Equality_base + { + protected: + template + static bool + _S_is_permutation(_Uiterator, _Uiterator, _Uiterator); + }; + + // See std::is_permutation in N3068. + template + bool + _Equality_base:: + _S_is_permutation(_Uiterator __first1, _Uiterator __last1, + _Uiterator __first2) + { + for (; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + break; + + if (__first1 == __last1) + return true; + + _Uiterator __last2 = __first2; + std::advance(__last2, std::distance(__first1, __last1)); + + for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1) + { + _Uiterator __tmp = __first1; + while (__tmp != __it1 && !bool(*__tmp == *__it1)) + ++__tmp; + + // We've seen this one before. + if (__tmp != __it1) + continue; + + std::ptrdiff_t __n2 = 0; + for (__tmp = __first2; __tmp != __last2; ++__tmp) + if (*__tmp == *__it1) + ++__n2; + + if (!__n2) + return false; + + std::ptrdiff_t __n1 = 0; + for (__tmp = __it1; __tmp != __last1; ++__tmp) + if (*__tmp == *__it1) + ++__n1; + + if (__n1 != __n2) + return false; + } + return true; + } + + /** + * Primary class template _Equality. + * + * This is for implementing equality comparison for unordered + * containers, per N3068, by John Lakos and Pablo Halpern. + * Algorithmically, we follow closely the reference implementations + * therein. + */ + template + struct _Equality; + + /// Specialization. + template + struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true> + { + using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>; + + bool + _M_equal(const __hashtable&) const; + }; + + template + bool + _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: + _M_equal(const __hashtable& __other) const + { + const __hashtable* __this = static_cast(this); + + if (__this->size() != __other.size()) + return false; + + for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx) + { + const auto __ity = __other.find(_ExtractKey()(*__itx)); + if (__ity == __other.end() || !bool(*__ity == *__itx)) + return false; + } + return true; + } + + /// Specialization. + template + struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, false> + : public _Equality_base + { + using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits>; + + bool + _M_equal(const __hashtable&) const; + }; + + template + bool + _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _H1, _H2, _Hash, _RehashPolicy, _Traits, false>:: + _M_equal(const __hashtable& __other) const + { + const __hashtable* __this = static_cast(this); + + if (__this->size() != __other.size()) + return false; + + for (auto __itx = __this->begin(); __itx != __this->end();) + { + const auto __xrange = __this->equal_range(_ExtractKey()(*__itx)); + const auto __yrange = __other.equal_range(_ExtractKey()(*__itx)); + + if (std::distance(__xrange.first, __xrange.second) + != std::distance(__yrange.first, __yrange.second)) + return false; + + if (!_S_is_permutation(__xrange.first, __xrange.second, + __yrange.first)) + return false; + + __itx = __xrange.second; + } + return true; + } + + /** + * This type deals with all allocation and keeps an allocator instance through + * inheritance to benefit from EBO when possible. + */ + template + struct _Hashtable_alloc : private _Hashtable_ebo_helper<0, _NodeAlloc> + { + private: + using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>; + public: + using __node_type = typename _NodeAlloc::value_type; + using __node_alloc_type = _NodeAlloc; + // Use __gnu_cxx to benefit from _S_always_equal and al. + using __node_alloc_traits = __gnu_cxx::__alloc_traits<__node_alloc_type>; + + using __value_type = typename __node_type::value_type; + using __value_alloc_type = + typename __alloctr_rebind<__node_alloc_type, __value_type>::__type; + using __value_alloc_traits = std::allocator_traits<__value_alloc_type>; + + using __node_base = __detail::_Hash_node_base; + using __bucket_type = __node_base*; + using __bucket_alloc_type = + typename __alloctr_rebind<__node_alloc_type, __bucket_type>::__type; + using __bucket_alloc_traits = std::allocator_traits<__bucket_alloc_type>; + + _Hashtable_alloc(const _Hashtable_alloc&) = default; + _Hashtable_alloc(_Hashtable_alloc&&) = default; + + template + _Hashtable_alloc(_Alloc&& __a) + : __ebo_node_alloc(std::forward<_Alloc>(__a)) + { } + + __node_alloc_type& + _M_node_allocator() + { return __ebo_node_alloc::_S_get(*this); } + + const __node_alloc_type& + _M_node_allocator() const + { return __ebo_node_alloc::_S_cget(*this); } + + template + __node_type* + _M_allocate_node(_Args&&... __args); + + void + _M_deallocate_node(__node_type* __n); + + // Deallocate the linked list of nodes pointed to by __n + void + _M_deallocate_nodes(__node_type* __n); + + __bucket_type* + _M_allocate_buckets(std::size_t __n); + + void + _M_deallocate_buckets(__bucket_type*, std::size_t __n); + }; + + // Definitions of class template _Hashtable_alloc's out-of-line member + // functions. + template + template + typename _Hashtable_alloc<_NodeAlloc>::__node_type* + _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args) + { + auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1); + __node_type* __n = std::addressof(*__nptr); + __try + { + __value_alloc_type __a(_M_node_allocator()); + ::new ((void*)__n) __node_type; + __value_alloc_traits::construct(__a, __n->_M_valptr(), + std::forward<_Args>(__args)...); + return __n; + } + __catch(...) + { + __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1); + __throw_exception_again; + } + } + + template + void + _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n) + { + typedef typename __node_alloc_traits::pointer _Ptr; + auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n); + __value_alloc_type __a(_M_node_allocator()); + __value_alloc_traits::destroy(__a, __n->_M_valptr()); + __n->~__node_type(); + __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1); + } + + template + void + _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_type* __n) + { + while (__n) + { + __node_type* __tmp = __n; + __n = __n->_M_next(); + _M_deallocate_node(__tmp); + } + } + + template + typename _Hashtable_alloc<_NodeAlloc>::__bucket_type* + _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __n) + { + __bucket_alloc_type __alloc(_M_node_allocator()); + + auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n); + __bucket_type* __p = std::addressof(*__ptr); + __builtin_memset(__p, 0, __n * sizeof(__bucket_type)); + return __p; + } + + template + void + _Hashtable_alloc<_NodeAlloc>::_M_deallocate_buckets(__bucket_type* __bkts, + std::size_t __n) + { + typedef typename __bucket_alloc_traits::pointer _Ptr; + auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts); + __bucket_alloc_type __alloc(_M_node_allocator()); + __bucket_alloc_traits::deallocate(__alloc, __ptr, __n); + } + + //@} hashtable-detail +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace __detail +} // namespace std + +// dank: addition + +namespace geode::stl::__detail { + + // The sentinel value is kept only for abi backward compatibility. + inline const unsigned long __prime_list[] = // 256 + 1 or 256 + 48 + 1 + { + 2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul, + 37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul, + 83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul, + 157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul, + 277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul, + 503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul, + 953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul, + 1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul, + 3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul, + 5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul, + 11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul, + 19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul, + 33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul, + 57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul, + 99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul, + 159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul, + 256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul, + 410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul, + 658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul, + 1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul, + 1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul, + 2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul, + 4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul, + 6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul, + 11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul, + 16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul, + 24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul, + 36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul, + 54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul, + 80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul, + 118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul, + 176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul, + 260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul, + 386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul, + 573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul, + 849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul, + 1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul, 1725587117ul, + 1866894511ul, 2019773507ul, 2185171673ul, 2364114217ul, 2557710269ul, + 2767159799ul, 2993761039ul, 3238918481ul, 3504151727ul, 3791104843ul, + 4101556399ul, 4294967291ul, + // Sentinel, so we don't have to test the result of lower_bound, + // or, on 64-bit machines, rest of the table. +#if __SIZEOF_LONG__ != 8 + 4294967291ul +#else + 6442450933ul, 8589934583ul, 12884901857ul, 17179869143ul, + 25769803693ul, 34359738337ul, 51539607367ul, 68719476731ul, + 103079215087ul, 137438953447ul, 206158430123ul, 274877906899ul, + 412316860387ul, 549755813881ul, 824633720731ul, 1099511627689ul, + 1649267441579ul, 2199023255531ul, 3298534883309ul, 4398046511093ul, + 6597069766607ul, 8796093022151ul, 13194139533241ul, 17592186044399ul, + 26388279066581ul, 35184372088777ul, 52776558133177ul, 70368744177643ul, + 105553116266399ul, 140737488355213ul, 211106232532861ul, 281474976710597ul, + 562949953421231ul, 1125899906842597ul, 2251799813685119ul, + 4503599627370449ul, 9007199254740881ul, 18014398509481951ul, + 36028797018963913ul, 72057594037927931ul, 144115188075855859ul, + 288230376151711717ul, 576460752303423433ul, + 1152921504606846883ul, 2305843009213693951ul, + 4611686018427387847ul, 9223372036854775783ul, + 18446744073709551557ul, 18446744073709551557ul +#endif + }; + + // Return a prime no smaller than n. + inline std::size_t + _Prime_rehash_policy::_M_next_bkt(std::size_t __n) const + { + // Optimize lookups involving the first elements of __prime_list. + // (useful to speed-up, eg, constructors) + static const unsigned char __fast_bkt[] + = { 2, 2, 2, 3, 5, 5, 7, 7, 11, 11, 11, 11, 13, 13 }; + + if (__n < sizeof(__fast_bkt)) + { + if (__n == 0) + // Special case on container 1st initialization with 0 bucket count + // hint. We keep _M_next_resize to 0 to make sure that next time we + // want to add an element allocation will take place. + return 1; + + _M_next_resize = + __builtin_floor(__fast_bkt[__n] * (double)_M_max_load_factor); + return __fast_bkt[__n]; + } + + // Number of primes (without sentinel). + constexpr auto __n_primes + = sizeof(__prime_list) / sizeof(unsigned long) - 1; + + // Don't include the last prime in the search, so that anything + // higher than the second-to-last prime returns a past-the-end + // iterator that can be dereferenced to get the last prime. + constexpr auto __last_prime = __prime_list + __n_primes - 1; + + const unsigned long* __next_bkt = + std::lower_bound(__prime_list + 6, __last_prime, __n); + + if (__next_bkt == __last_prime) + // Set next resize to the max value so that we never try to rehash again + // as we already reach the biggest possible bucket number. + // Note that it might result in max_load_factor not being respected. + _M_next_resize = size_t(-1); + else + _M_next_resize = + __builtin_floor(*__next_bkt * (double)_M_max_load_factor); + + return *__next_bkt; + } + + inline std::pair + _Prime_rehash_policy:: + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) const + { + if (__n_elt + __n_ins > _M_next_resize) + { + // If _M_next_resize is 0 it means that we have nothing allocated so + // far and that we start inserting elements. In this case we start + // with an initial bucket size of 11. + double __min_bkts + = std::max(__n_elt + __n_ins, _M_next_resize ? 0 : 11) + / (double)_M_max_load_factor; + if (__min_bkts >= __n_bkt) + return { true, + _M_next_bkt(std::max(__builtin_floor(__min_bkts) + 1, + __n_bkt * _S_growth_factor)) }; + + _M_next_resize + = __builtin_floor(__n_bkt * (double)_M_max_load_factor); + return { false, 0 }; + } + else + return { false, 0 }; + } +} \ No newline at end of file diff --git a/loader/include/Geode/c++stl/gnustl/memoryfwd.h b/loader/include/Geode/c++stl/gnustl/memoryfwd.h new file mode 100644 index 00000000..4d31fd88 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/memoryfwd.h @@ -0,0 +1,77 @@ +// Forward declarations -*- C++ -*- + +// Copyright (C) 2001-2014 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 +// . + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file bits/memoryfwd.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#ifndef _MEMORYFWD_H +#define _MEMORYFWD_H 1 + +#pragma GCC system_header + +#include "c++config.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup allocators Allocators + * @ingroup memory + * + * Classes encapsulating memory operations. + * + * @{ + */ + + template + class allocator; + + template<> + class allocator; + + /// Declare uses_allocator so it can be specialized in \ etc. + template + struct uses_allocator; + + /// @} group memory + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/new_allocator.h b/loader/include/Geode/c++stl/gnustl/new_allocator.h new file mode 100644 index 00000000..2909cd82 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/new_allocator.h @@ -0,0 +1,157 @@ +// Allocator that wraps operator new -*- C++ -*- + +// Copyright (C) 2001-2014 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 +// . + +/** @file ext/new_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _NEW_ALLOCATOR_H +#define _NEW_ALLOCATOR_H 1 + +#include "c++config.h" +#include +#include +#include +#if __cplusplus >= 201103L +#include +#endif + +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + using std::size_t; + using std::ptrdiff_t; + + /** + * @brief An allocator that uses global new, as per [20.4]. + * @ingroup allocators + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * @tparam _Tp Type of allocated object. + */ + template + class new_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template + struct rebind + { typedef new_allocator<_Tp1> other; }; + +#if __cplusplus >= 201103L + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2103. propagate_on_container_move_assignment + typedef std::true_type propagate_on_container_move_assignment; +#endif + + new_allocator() _GLIBCXX_USE_NOEXCEPT { } + + new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { } + + template + new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } + + ~new_allocator() _GLIBCXX_USE_NOEXCEPT { } + + pointer + address(reference __x) const _GLIBCXX_NOEXCEPT + { return std::__addressof(__x); } + + const_pointer + address(const_reference __x) const _GLIBCXX_NOEXCEPT + { return std::__addressof(__x); } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { + if (__n > this->max_size()) + std::__throw_bad_alloc(); + + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } + +#ifdef __GXX_DELETE_WITH_SIZE__ + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type __t) + { ::operator delete(__p, __t * sizeof(_Tp)); } +#else + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } +#endif + + size_type + max_size() const _GLIBCXX_USE_NOEXCEPT + { return size_t(-1) / sizeof(_Tp); } + +#if __cplusplus >= 201103L + template + void + construct(_Up* __p, _Args&&... __args) + { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + + template + void + destroy(_Up* __p) { __p->~_Up(); } +#else + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new((void *)__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } +#endif + }; + + template + inline bool + operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return true; } + + template + inline bool + operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return false; } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif diff --git a/loader/include/Geode/c++stl/gnustl/ptr_traits.h b/loader/include/Geode/c++stl/gnustl/ptr_traits.h new file mode 100644 index 00000000..705e4a06 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/ptr_traits.h @@ -0,0 +1,184 @@ +// Pointer Traits -*- C++ -*- + +// Copyright (C) 2011-2014 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 +// . + +/** @file bits/ptr_traits.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{memory} + */ + +#pragma once + +#if __cplusplus >= 201103L +#include "c++config.h" + +#include +#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ + template> \ + struct __has_##_NTYPE \ + : std::false_type \ + { }; \ + template \ + struct __has_##_NTYPE<_Tp, std::void_t> \ + : std::true_type \ + { }; + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +_GLIBCXX_HAS_NESTED_TYPE(element_type) +_GLIBCXX_HAS_NESTED_TYPE(difference_type) + + template::value> + struct __ptrtr_elt_type; + + template + struct __ptrtr_elt_type<_Tp, true> + { + typedef typename _Tp::element_type __type; + }; + + template class _SomePtr, typename _Tp, + typename... _Args> + struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false> + { + typedef _Tp __type; + }; + + template::value> + struct __ptrtr_diff_type + { + typedef typename _Tp::difference_type __type; + }; + + template + struct __ptrtr_diff_type<_Tp, false> + { + typedef ptrdiff_t __type; + }; + + template + class __ptrtr_rebind_helper + { + template + static constexpr std::true_type + _S_chk(typename _Ptr2::template rebind<_Up2>*); + + template + static constexpr std::false_type + _S_chk(...); + + public: + using __type = decltype(_S_chk<_Ptr, _Up>(nullptr)); + }; + + template::__type::value> + struct __ptrtr_rebind; + + template + struct __ptrtr_rebind<_Tp, _Up, true> + { + typedef typename _Tp::template rebind<_Up> __type; + }; + + template class _SomePtr, typename _Up, + typename _Tp, typename... _Args> + struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false> + { + typedef _SomePtr<_Up, _Args...> __type; + }; + + template::type> + struct __ptrtr_not_void + { + typedef _Tp __type; + }; + + template + struct __ptrtr_not_void<_Tp, void> + { + struct __type { }; + }; + + template + class __ptrtr_pointer_to + { + typedef typename __ptrtr_elt_type<_Ptr>::__type __orig_type; + typedef typename __ptrtr_not_void<__orig_type>::__type __element_type; + + public: + static _Ptr pointer_to(__element_type& __e) + { return _Ptr::pointer_to(__e); } + }; + + /** + * @brief Uniform interface to all pointer-like types + * @ingroup pointer_abstractions + */ + template + struct pointer_traits : __ptrtr_pointer_to<_Ptr> + { + /// The pointer type + typedef _Ptr pointer; + /// The type pointed to + typedef typename __ptrtr_elt_type<_Ptr>::__type element_type; + /// Type used to represent the difference between two pointers + typedef typename __ptrtr_diff_type<_Ptr>::__type difference_type; + + template + using rebind = typename __ptrtr_rebind<_Ptr, _Up>::__type; + }; + + /** + * @brief Partial specialization for built-in pointers. + * @ingroup pointer_abstractions + */ + template + struct pointer_traits<_Tp*> + { + /// The pointer type + typedef _Tp* pointer; + /// The type pointed to + typedef _Tp element_type; + /// Type used to represent the difference between two pointers + typedef ptrdiff_t difference_type; + + template + using rebind = _Up*; + + /** + * @brief Obtain a pointer to an object + * @param __r A reference to an object of type @c element_type + * @return @c addressof(__r) + */ + static pointer + pointer_to(typename __ptrtr_not_void::__type& __r) noexcept + { return std::addressof(__r); } + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif + diff --git a/loader/include/Geode/c++stl/gnustl/range_access.h b/loader/include/Geode/c++stl/gnustl/range_access.h new file mode 100644 index 00000000..9b2f4a25 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/range_access.h @@ -0,0 +1,103 @@ +// -*- C++ -*- + +// Copyright (C) 2010-2014 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 +// . + +/** @file bits/range_access.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{iterator} + */ + +#pragma once + +#pragma GCC system_header + +#if __cplusplus >= 201103L + +#include "c++config.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @brief Return an iterator pointing to the first element of + * the container. + * @param __cont Container. + */ + template + inline auto + begin(_Container& __cont) -> decltype(__cont.begin()) + { return __cont.begin(); } + + /** + * @brief Return an iterator pointing to the first element of + * the const container. + * @param __cont Container. + */ + template + inline auto + begin(const _Container& __cont) -> decltype(__cont.begin()) + { return __cont.begin(); } + + /** + * @brief Return an iterator pointing to one past the last element of + * the container. + * @param __cont Container. + */ + template + inline auto + end(_Container& __cont) -> decltype(__cont.end()) + { return __cont.end(); } + + /** + * @brief Return an iterator pointing to one past the last element of + * the const container. + * @param __cont Container. + */ + template + inline auto + end(const _Container& __cont) -> decltype(__cont.end()) + { return __cont.end(); } + + /** + * @brief Return an iterator pointing to the first element of the array. + * @param __arr Array. + */ + template + inline _Tp* + begin(_Tp (&__arr)[_Nm]) + { return __arr; } + + /** + * @brief Return an iterator pointing to one past the last element + * of the array. + * @param __arr Array. + */ + template + inline _Tp* + end(_Tp (&__arr)[_Nm]) + { return __arr + _Nm; } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif // C++11 diff --git a/loader/include/Geode/c++stl/gnustl/stl_function.h b/loader/include/Geode/c++stl/gnustl/stl_function.h new file mode 100644 index 00000000..22bd9263 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/stl_function.h @@ -0,0 +1,1078 @@ +// Functor implementations -*- C++ -*- + +// Copyright (C) 2001-2014 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 +// . + +/* + * + * 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 bits/stl_function.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{functional} + */ + +#pragma once + +#include "c++config.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // 20.3.1 base classes + /** @defgroup functors Function Objects + * @ingroup utilities + * + * Function objects, or @e functors, are objects with an @c operator() + * defined and accessible. They can be passed as arguments to algorithm + * templates and used in place of a function pointer. Not only is the + * resulting expressiveness of the library increased, but the generated + * code can be more efficient than what you might write by hand. When we + * refer to @a functors, then, generally we include function pointers in + * the description as well. + * + * Often, functors are only created as temporaries passed to algorithm + * calls, rather than being created as named variables. + * + * Two examples taken from the standard itself follow. To perform a + * by-element addition of two vectors @c a and @c b containing @c double, + * and put the result in @c a, use + * \code + * transform (a.begin(), a.end(), b.begin(), a.begin(), plus()); + * \endcode + * To negate every element in @c a, use + * \code + * transform(a.begin(), a.end(), a.begin(), negate()); + * \endcode + * The addition and negation functions will be inlined directly. + * + * The standard functors are derived from structs named @c unary_function + * and @c binary_function. These two classes contain nothing but typedefs, + * to aid in generic (template) programming. If you write your own + * functors, you might consider doing the same. + * + * @{ + */ + /** + * This is one of the @link functors functor base classes@endlink. + */ + template + struct unary_function + { + /// @c argument_type is the type of the argument + typedef _Arg argument_type; + + /// @c result_type is the return type + typedef _Result result_type; + }; + + /** + * This is one of the @link functors functor base classes@endlink. + */ + template + struct binary_function + { + /// @c first_argument_type is the type of the first argument + typedef _Arg1 first_argument_type; + + /// @c second_argument_type is the type of the second argument + typedef _Arg2 second_argument_type; + + /// @c result_type is the return type + typedef _Result result_type; + }; + /** @} */ + + // 20.3.2 arithmetic + /** @defgroup arithmetic_functors Arithmetic Classes + * @ingroup functors + * + * Because basic math often needs to be done during an algorithm, + * the library provides functors for those operations. See the + * documentation for @link functors the base classes@endlink + * for examples of their use. + * + * @{ + */ + +#if __cplusplus > 201103L + struct __is_transparent; // undefined + + template + struct plus; + + template + struct minus; + + template + struct multiplies; + + template + struct divides; + + template + struct modulus; + + template + struct negate; +#endif + + /// One of the @link arithmetic_functors math functors@endlink. + template + struct plus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template + struct minus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template + struct multiplies : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template + struct divides : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template + struct modulus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template + struct negate : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; + +#if __cplusplus > 201103L + +// #define __cpp_lib_transparent_operators 201210 // dank: redefined macro warning +//#define __cpp_lib_generic_associative_lookup 201304 + + template<> + struct plus + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) + std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) + std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) + std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template<> + struct minus + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) - std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) - std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) - std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template<> + struct multiplies + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) * std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) * std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) * std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template<> + struct divides + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) / std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) / std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) / std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template<> + struct modulus + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) % std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) % std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) % std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link arithmetic_functors math functors@endlink. + template<> + struct negate + { + template + auto + operator()(_Tp&& __t) const + noexcept(noexcept(-std::forward<_Tp>(__t))) + -> decltype(-std::forward<_Tp>(__t)) + { return -std::forward<_Tp>(__t); } + + typedef __is_transparent is_transparent; + }; +#endif + /** @} */ + + // 20.3.3 comparisons + /** @defgroup comparison_functors Comparison Classes + * @ingroup functors + * + * The library provides six wrapper functors for all the basic comparisons + * in C++, like @c <. + * + * @{ + */ +#if __cplusplus > 201103L + template + struct equal_to; + + template + struct not_equal_to; + + template + struct greater; + + template + struct less; + + template + struct greater_equal; + + template + struct less_equal; +#endif + + /// One of the @link comparison_functors comparison functors@endlink. + template + struct equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template + struct not_equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template + struct greater : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template + struct less : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template + struct greater_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template + struct less_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + +#if __cplusplus > 201103L + /// One of the @link comparison_functors comparison functors@endlink. + template<> + struct equal_to + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template<> + struct not_equal_to + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) != std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) != std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) != std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template<> + struct greater + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) > std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) > std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) > std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template<> + struct less + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) < std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template<> + struct greater_equal + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) >= std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) >= std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) >= std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link comparison_functors comparison functors@endlink. + template<> + struct less_equal + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) <= std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) <= std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) <= std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; +#endif + /** @} */ + + // 20.3.4 logical operations + /** @defgroup logical_functors Boolean Operations Classes + * @ingroup functors + * + * Here are wrapper functors for Boolean operations: @c &&, @c ||, + * and @c !. + * + * @{ + */ +#if __cplusplus > 201103L + template + struct logical_and; + + template + struct logical_or; + + template + struct logical_not; +#endif + + /// One of the @link logical_functors Boolean operations functors@endlink. + template + struct logical_and : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + /// One of the @link logical_functors Boolean operations functors@endlink. + template + struct logical_or : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + /// One of the @link logical_functors Boolean operations functors@endlink. + template + struct logical_not : public unary_function<_Tp, bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + +#if __cplusplus > 201103L + /// One of the @link logical_functors Boolean operations functors@endlink. + template<> + struct logical_and + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) && std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) && std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) && std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link logical_functors Boolean operations functors@endlink. + template<> + struct logical_or + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) || std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) || std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) || std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + /// One of the @link logical_functors Boolean operations functors@endlink. + template<> + struct logical_not + { + template + auto + operator()(_Tp&& __t) const + noexcept(noexcept(!std::forward<_Tp>(__t))) + -> decltype(!std::forward<_Tp>(__t)) + { return !std::forward<_Tp>(__t); } + + typedef __is_transparent is_transparent; + }; +#endif + /** @} */ + +#if __cplusplus > 201103L + template + struct bit_and; + + template + struct bit_or; + + template + struct bit_xor; + + template + struct bit_not; +#endif + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 660. Missing Bitwise Operations. + template + struct bit_and : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x & __y; } + }; + + template + struct bit_or : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x | __y; } + }; + + template + struct bit_xor : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x ^ __y; } + }; + + template + struct bit_not : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return ~__x; } + }; + +#if __cplusplus > 201103L + template <> + struct bit_and + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) & std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) & std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) & std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + template <> + struct bit_or + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) | std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) | std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) | std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + template <> + struct bit_xor + { + template + auto + operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u))) + -> decltype(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u)) + { return std::forward<_Tp>(__t) ^ std::forward<_Up>(__u); } + + typedef __is_transparent is_transparent; + }; + + template <> + struct bit_not + { + template + auto + operator()(_Tp&& __t) const + noexcept(noexcept(~std::forward<_Tp>(__t))) + -> decltype(~std::forward<_Tp>(__t)) + { return ~std::forward<_Tp>(__t); } + + typedef __is_transparent is_transparent; + }; +#endif + + // 20.3.5 negators + /** @defgroup negators Negators + * @ingroup functors + * + * The functions @c not1 and @c not2 each take a predicate functor + * and return an instance of @c unary_negate or + * @c binary_negate, respectively. These classes are functors whose + * @c operator() performs the stored predicate function and then returns + * the negation of the result. + * + * For example, given a vector of integers and a trivial predicate, + * \code + * struct IntGreaterThanThree + * : public std::unary_function + * { + * bool operator() (int x) { return x > 3; } + * }; + * + * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); + * \endcode + * The call to @c find_if will locate the first index (i) of @c v for which + * !(v[i] > 3) is true. + * + * The not1/unary_negate combination works on predicates taking a single + * argument. The not2/binary_negate combination works on predicates which + * take two arguments. + * + * @{ + */ + /// One of the @link negators negation functors@endlink. + template + class unary_negate + : public unary_function + { + protected: + _Predicate _M_pred; + + public: + explicit + unary_negate(const _Predicate& __x) : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; + + /// One of the @link negators negation functors@endlink. + template + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } + + /// One of the @link negators negation functors@endlink. + template + class binary_negate + : public binary_function + { + protected: + _Predicate _M_pred; + + public: + explicit + binary_negate(const _Predicate& __x) : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; + + /// One of the @link negators negation functors@endlink. + template + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } + /** @} */ + + // 20.3.7 adaptors pointers functions + /** @defgroup pointer_adaptors Adaptors for pointers to functions + * @ingroup functors + * + * The advantage of function objects over pointers to functions is that + * the objects in the standard library declare nested typedefs describing + * their argument and result types with uniform names (e.g., @c result_type + * from the base classes @c unary_function and @c binary_function). + * Sometimes those typedefs are required, not just optional. + * + * Adaptors are provided to turn pointers to unary (single-argument) and + * binary (double-argument) functions into function objects. The + * long-winded functor @c pointer_to_unary_function is constructed with a + * function pointer @c f, and its @c operator() called with argument @c x + * returns @c f(x). The functor @c pointer_to_binary_function does the same + * thing, but with a double-argument @c f and @c operator(). + * + * The function @c ptr_fun takes a pointer-to-function @c f and constructs + * an instance of the appropriate functor. + * + * @{ + */ + /// One of the @link pointer_adaptors adaptors for function pointers@endlink. + template + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + + public: + pointer_to_unary_function() { } + + explicit + pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) { } + + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; + + /// One of the @link pointer_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_unary_function<_Arg, _Result> + ptr_fun(_Result (*__x)(_Arg)) + { return pointer_to_unary_function<_Arg, _Result>(__x); } + + /// One of the @link pointer_adaptors adaptors for function pointers@endlink. + template + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + + public: + pointer_to_binary_function() { } + + explicit + pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) { } + + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; + + /// One of the @link pointer_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_binary_function<_Arg1, _Arg2, _Result> + ptr_fun(_Result (*__x)(_Arg1, _Arg2)) + { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } + /** @} */ + + template + struct _Identity + : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; + + template + struct _Select1st + : public unary_function<_Pair, typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + const typename _Pair::first_type& + operator()(const _Pair& __x) const + { return __x.first; } + +#if __cplusplus >= 201103L + template + typename _Pair2::first_type& + operator()(_Pair2& __x) const + { return __x.first; } + + template + const typename _Pair2::first_type& + operator()(const _Pair2& __x) const + { return __x.first; } +#endif + }; + + template + struct _Select2nd + : public unary_function<_Pair, typename _Pair::second_type> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; + + // 20.3.8 adaptors pointers members + /** @defgroup memory_adaptors Adaptors for pointers to members + * @ingroup functors + * + * There are a total of 8 = 2^3 function objects in this family. + * (1) Member functions taking no arguments vs member functions taking + * one argument. + * (2) Call through pointer vs call through reference. + * (3) Const vs non-const member function. + * + * All of this complexity is in the function objects themselves. You can + * ignore it by using the helper function mem_fun and mem_fun_ref, + * which create whichever type of adaptor is appropriate. + * + * @{ + */ + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit + mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) { } + + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) { } + + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit + mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) { } + + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class const_mem_fun1_t : public binary_function + { + public: + explicit + const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) { } + + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link memory_adaptors adaptors for member + /// pointers@endlink. + template + class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) { } + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + // Mem_fun adaptor helper functions. There are only two: + // mem_fun and mem_fun_ref. + template + inline mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_t<_Ret, _Tp> + mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret, _Tp>(__f); } + + template + inline mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline const_mem_fun_ref_t<_Ret, _Tp> + mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } + + template + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template + inline mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + template + inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + + /** @} */ + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + diff --git a/loader/include/Geode/c++stl/gnustl/type_traits.h b/loader/include/Geode/c++stl/gnustl/type_traits.h new file mode 100644 index 00000000..03d1aec5 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/type_traits.h @@ -0,0 +1,9 @@ +#pragma once + +#include "c++config.h" + +namespace geode::stl { + // Helper for SFINAE constraints + template + using _Require = std::enable_if_t::value>; +} \ No newline at end of file diff --git a/loader/include/Geode/c++stl/gnustl/unordered_map.h b/loader/include/Geode/c++stl/gnustl/unordered_map.h new file mode 100644 index 00000000..bbc5bf35 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/unordered_map.h @@ -0,0 +1,1478 @@ +// unordered_map implementation -*- C++ -*- + +// Copyright (C) 2010-2014 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 +// . + +/** @file bits/unordered_map.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{unordered_map} + */ + +#pragma once +#include "c++config.h" + +namespace geode::stl +{ +_GLIBCXX_BEGIN_NAMESPACE_CONTAINER + + /// Base types for unordered_map. + template + using __umap_traits = __detail::_Hashtable_traits<_Cache, false, true>; + + template, + typename _Pred = std::equal_to<_Key>, + typename _Alloc = std::allocator >, + typename _Tr = __umap_traits<__cache_default<_Key, _Hash>::value>> + using __umap_hashtable = _Hashtable<_Key, std::pair, + _Alloc, __detail::_Select1st, + _Pred, _Hash, + __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, _Tr>; + + /// Base types for unordered_multimap. + template + using __ummap_traits = __detail::_Hashtable_traits<_Cache, false, false>; + + template, + typename _Pred = std::equal_to<_Key>, + typename _Alloc = std::allocator >, + typename _Tr = __ummap_traits<__cache_default<_Key, _Hash>::value>> + using __ummap_hashtable = _Hashtable<_Key, std::pair, + _Alloc, __detail::_Select1st, + _Pred, _Hash, + __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, _Tr>; + + /** + * @brief A standard container composed of unique keys (containing + * at most one of each key value) that associates values of another type + * with the keys. + * + * @ingroup unordered_associative_containers + * + * @tparam _Key Type of key objects. + * @tparam _Tp Type of mapped objects. + * @tparam _Hash Hashing function object type, defaults to hash<_Value>. + * @tparam _Pred Predicate function object type, defaults + * to equal_to<_Value>. + * @tparam _Alloc Allocator type, defaults to + * std::allocator>. + * + * Meets the requirements of a container, and + * unordered associative container + * + * The resulting value type of the container is std::pair. + * + * Base is _Hashtable, dispatched at compile time via template + * alias __umap_hashtable. + */ + template, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator > > + class unordered_map + { + typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; + _Hashtable _M_h; + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef typename _Hashtable::key_type key_type; + typedef typename _Hashtable::value_type value_type; + typedef typename _Hashtable::mapped_type mapped_type; + typedef typename _Hashtable::hasher hasher; + typedef typename _Hashtable::key_equal key_equal; + typedef typename _Hashtable::allocator_type allocator_type; + //@} + + //@{ + /// Iterator-related typedefs. + typedef typename _Hashtable::pointer pointer; + typedef typename _Hashtable::const_pointer const_pointer; + typedef typename _Hashtable::reference reference; + typedef typename _Hashtable::const_reference const_reference; + typedef typename _Hashtable::iterator iterator; + typedef typename _Hashtable::const_iterator const_iterator; + typedef typename _Hashtable::local_iterator local_iterator; + typedef typename _Hashtable::const_local_iterator const_local_iterator; + typedef typename _Hashtable::size_type size_type; + typedef typename _Hashtable::difference_type difference_type; + //@} + + //construct/destroy/copy + + /** + * @brief Default constructor creates no elements. + * @param __n Initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + */ + explicit + unordered_map(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__n, __hf, __eql, __a) + { } + + /** + * @brief Builds an %unordered_map from a range. + * @param __first An input iterator. + * @param __last An input iterator. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_map consisting of copies of the elements from + * [__first,__last). This is linear in N (where N is + * distance(__first,__last)). + */ + template + unordered_map(_InputIterator __f, _InputIterator __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__f, __l, __n, __hf, __eql, __a) + { } + + /// Copy constructor. + unordered_map(const unordered_map&) = default; + + /// Move constructor. + unordered_map(unordered_map&&) = default; + + /** + * @brief Creates an %unordered_map with no elements. + * @param __a An allocator object. + */ + explicit + unordered_map(const allocator_type& __a) + : _M_h(__a) + { } + + /* + * @brief Copy constructor with allocator argument. + * @param __uset Input %unordered_map to copy. + * @param __a An allocator object. + */ + unordered_map(const unordered_map& __umap, + const allocator_type& __a) + : _M_h(__umap._M_h, __a) + { } + + /* + * @brief Move constructor with allocator argument. + * @param __uset Input %unordered_map to move. + * @param __a An allocator object. + */ + unordered_map(unordered_map&& __umap, + const allocator_type& __a) + : _M_h(std::move(__umap._M_h), __a) + { } + + /** + * @brief Builds an %unordered_map from an initializer_list. + * @param __l An initializer_list. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_map consisting of copies of the elements in the + * list. This is linear in N (where N is @a __l.size()). + */ + unordered_map(std::initializer_list __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + /// Copy assignment operator. + unordered_map& + operator=(const unordered_map&) = default; + + /// Move assignment operator. + unordered_map& + operator=(unordered_map&&) = default; + + /** + * @brief %Unordered_map list assignment operator. + * @param __l An initializer_list. + * + * This function fills an %unordered_map with copies of the elements in + * the initializer list @a __l. + * + * Note that the assignment completely changes the %unordered_map and + * that the resulting %unordered_map's size is the same as the number + * of elements assigned. Old data may be lost. + */ + unordered_map& + operator=(std::initializer_list __l) + { + _M_h = __l; + return *this; + } + + /// Returns the allocator object with which the %unordered_map was + /// constructed. + allocator_type + get_allocator() const noexcept + { return _M_h.get_allocator(); } + + // size and capacity: + + /// Returns true if the %unordered_map is empty. + bool + empty() const noexcept + { return _M_h.empty(); } + + /// Returns the size of the %unordered_map. + size_type + size() const noexcept + { return _M_h.size(); } + + /// Returns the maximum size of the %unordered_map. + size_type + max_size() const noexcept + { return _M_h.max_size(); } + + // iterators. + + /** + * Returns a read/write iterator that points to the first element in the + * %unordered_map. + */ + iterator + begin() noexcept + { return _M_h.begin(); } + + //@{ + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %unordered_map. + */ + const_iterator + begin() const noexcept + { return _M_h.begin(); } + + const_iterator + cbegin() const noexcept + { return _M_h.begin(); } + //@} + + /** + * Returns a read/write iterator that points one past the last element in + * the %unordered_map. + */ + iterator + end() noexcept + { return _M_h.end(); } + + //@{ + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %unordered_map. + */ + const_iterator + end() const noexcept + { return _M_h.end(); } + + const_iterator + cend() const noexcept + { return _M_h.end(); } + //@} + + // modifiers. + + /** + * @brief Attempts to build and insert a std::pair into the %unordered_map. + * + * @param __args Arguments used to generate a new pair instance (see + * std::piecewise_contruct for passing arguments to each + * part of the pair constructor). + * + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted pair, and the second is a bool that + * is true if the pair was actually inserted. + * + * This function attempts to build and insert a (key, value) %pair into + * the %unordered_map. + * An %unordered_map relies on unique keys and thus a %pair is only + * inserted if its first element (the key) is not already present in the + * %unordered_map. + * + * Insertion requires amortized constant time. + */ + template + std::pair + emplace(_Args&&... __args) + { return _M_h.emplace(std::forward<_Args>(__args)...); } + + /** + * @brief Attempts to build and insert a std::pair into the %unordered_map. + * + * @param __pos An iterator that serves as a hint as to where the pair + * should be inserted. + * @param __args Arguments used to generate a new pair instance (see + * std::piecewise_contruct for passing arguments to each + * part of the pair constructor). + * @return An iterator that points to the element with key of the + * std::pair built from @a __args (may or may not be that + * std::pair). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument emplace() + * does. + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * for more on @a hinting. + * + * Insertion requires amortized constant time. + */ + template + iterator + emplace_hint(const_iterator __pos, _Args&&... __args) + { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } + + //@{ + /** + * @brief Attempts to insert a std::pair into the %unordered_map. + + * @param __x Pair to be inserted (see std::make_pair for easy + * creation of pairs). + * + * @return A pair, of which the first element is an iterator that + * points to the possibly inserted pair, and the second is + * a bool that is true if the pair was actually inserted. + * + * This function attempts to insert a (key, value) %pair into the + * %unordered_map. An %unordered_map relies on unique keys and thus a + * %pair is only inserted if its first element (the key) is not already + * present in the %unordered_map. + * + * Insertion requires amortized constant time. + */ + std::pair + insert(const value_type& __x) + { return _M_h.insert(__x); } + + template::value>::type> + std::pair + insert(_Pair&& __x) + { return _M_h.insert(std::forward<_Pair>(__x)); } + //@} + + //@{ + /** + * @brief Attempts to insert a std::pair into the %unordered_map. + * @param __hint An iterator that serves as a hint as to where the + * pair should be inserted. + * @param __x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the element with key of + * @a __x (may or may not be the %pair passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument insert() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * for more on @a hinting. + * + * Insertion requires amortized constant time. + */ + iterator + insert(const_iterator __hint, const value_type& __x) + { return _M_h.insert(__hint, __x); } + + template::value>::type> + iterator + insert(const_iterator __hint, _Pair&& __x) + { return _M_h.insert(__hint, std::forward<_Pair>(__x)); } + //@} + + /** + * @brief A template function that attempts to insert a range of + * elements. + * @param __first Iterator pointing to the start of the range to be + * inserted. + * @param __last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_h.insert(__first, __last); } + + /** + * @brief Attempts to insert a list of elements into the %unordered_map. + * @param __l A std::initializer_list of elements + * to be inserted. + * + * Complexity similar to that of the range constructor. + */ + void + insert(std::initializer_list __l) + { _M_h.insert(__l); } + + //@{ + /** + * @brief Erases an element from an %unordered_map. + * @param __position An iterator pointing to the element to be erased. + * @return An iterator pointing to the element immediately following + * @a __position prior to the element being erased. If no such + * element exists, end() is returned. + * + * This function erases an element, pointed to by the given iterator, + * from an %unordered_map. + * Note that this function only erases the element, and that if the + * element is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __position) + { return _M_h.erase(__position); } + + // LWG 2059. + iterator + erase(iterator __it) + { return _M_h.erase(__it); } + //@} + + /** + * @brief Erases elements according to the provided key. + * @param __x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * an %unordered_map. For an %unordered_map the result of this function + * can only be 0 (not present) or 1 (present). + * Note that this function only erases the element, and that if the + * element is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibility. + */ + size_type + erase(const key_type& __x) + { return _M_h.erase(__x); } + + /** + * @brief Erases a [__first,__last) range of elements from an + * %unordered_map. + * @param __first Iterator pointing to the start of the range to be + * erased. + * @param __last Iterator pointing to the end of the range to + * be erased. + * @return The iterator @a __last. + * + * This function erases a sequence of elements from an %unordered_map. + * Note that this function only erases the elements, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __first, const_iterator __last) + { return _M_h.erase(__first, __last); } + + /** + * Erases all elements in an %unordered_map. + * Note that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + void + clear() noexcept + { _M_h.clear(); } + + /** + * @brief Swaps data with another %unordered_map. + * @param __x An %unordered_map of the same element and allocator + * types. + * + * This exchanges the elements between two %unordered_map in constant time. + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(unordered_map& __x) + noexcept( noexcept(_M_h.swap(__x._M_h)) ) + { _M_h.swap(__x._M_h); } + + // observers. + + /// Returns the hash functor object with which the %unordered_map was + /// constructed. + hasher + hash_function() const + { return _M_h.hash_function(); } + + /// Returns the key comparison object with which the %unordered_map was + /// constructed. + key_equal + key_eq() const + { return _M_h.key_eq(); } + + // lookup. + + //@{ + /** + * @brief Tries to locate an element in an %unordered_map. + * @param __x Key to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_h.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_h.find(__x); } + //@} + + /** + * @brief Finds the number of elements. + * @param __x Key to count. + * @return Number of elements with specified key. + * + * This function only makes sense for %unordered_multimap; for + * %unordered_map the result will either be 0 (not present) or 1 + * (present). + */ + size_type + count(const key_type& __x) const + { return _M_h.count(__x); } + + // dank: addition + bool contains(const key_type& x) const { + return _M_h.count(x) != 0; + } + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param __x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function probably only makes sense for %unordered_multimap. + */ + std::pair + equal_range(const key_type& __x) + { return _M_h.equal_range(__x); } + + std::pair + equal_range(const key_type& __x) const + { return _M_h.equal_range(__x); } + //@} + + //@{ + /** + * @brief Subscript ( @c [] ) access to %unordered_map data. + * @param __k The key for which data should be retrieved. + * @return A reference to the data of the (key,data) %pair. + * + * Allows for easy lookup with the subscript ( @c [] )operator. Returns + * data associated with the key specified in subscript. If the key does + * not exist, a pair with that key is created using default values, which + * is then returned. + * + * Lookup requires constant time. + */ + mapped_type& + operator[](const key_type& __k) + { return _M_h[__k]; } + + mapped_type& + operator[](key_type&& __k) + { return _M_h[std::move(__k)]; } + //@} + + //@{ + /** + * @brief Access to %unordered_map data. + * @param __k The key for which data should be retrieved. + * @return A reference to the data whose key is equal to @a __k, if + * such a data is present in the %unordered_map. + * @throw std::out_of_range If no such data is present. + */ + mapped_type& + at(const key_type& __k) + { return _M_h.at(__k); } + + const mapped_type& + at(const key_type& __k) const + { return _M_h.at(__k); } + //@} + + // bucket interface. + + /// Returns the number of buckets of the %unordered_map. + size_type + bucket_count() const noexcept + { return _M_h.bucket_count(); } + + /// Returns the maximum number of buckets of the %unordered_map. + size_type + max_bucket_count() const noexcept + { return _M_h.max_bucket_count(); } + + /* + * @brief Returns the number of elements in a given bucket. + * @param __n A bucket index. + * @return The number of elements in the bucket. + */ + size_type + bucket_size(size_type __n) const + { return _M_h.bucket_size(__n); } + + /* + * @brief Returns the bucket index of a given element. + * @param __key A key instance. + * @return The key bucket index. + */ + size_type + bucket(const key_type& __key) const + { return _M_h.bucket(__key); } + + /** + * @brief Returns a read/write iterator pointing to the first bucket + * element. + * @param __n The bucket index. + * @return A read/write local iterator. + */ + local_iterator + begin(size_type __n) + { return _M_h.begin(__n); } + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to the first + * bucket element. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + const_local_iterator + begin(size_type __n) const + { return _M_h.begin(__n); } + + const_local_iterator + cbegin(size_type __n) const + { return _M_h.cbegin(__n); } + //@} + + /** + * @brief Returns a read/write iterator pointing to one past the last + * bucket elements. + * @param __n The bucket index. + * @return A read/write local iterator. + */ + local_iterator + end(size_type __n) + { return _M_h.end(__n); } + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to one past + * the last bucket elements. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + const_local_iterator + end(size_type __n) const + { return _M_h.end(__n); } + + const_local_iterator + cend(size_type __n) const + { return _M_h.cend(__n); } + //@} + + // hash policy. + + /// Returns the average number of elements per bucket. + float + load_factor() const noexcept + { return _M_h.load_factor(); } + + /// Returns a positive number that the %unordered_map tries to keep the + /// load factor less than or equal to. + float + max_load_factor() const noexcept + { return _M_h.max_load_factor(); } + + /** + * @brief Change the %unordered_map maximum load factor. + * @param __z The new maximum load factor. + */ + void + max_load_factor(float __z) + { _M_h.max_load_factor(__z); } + + /** + * @brief May rehash the %unordered_map. + * @param __n The new number of buckets. + * + * Rehash will occur only if the new number of buckets respect the + * %unordered_map maximum load factor. + */ + void + rehash(size_type __n) + { _M_h.rehash(__n); } + + /** + * @brief Prepare the %unordered_map for a specified number of + * elements. + * @param __n Number of elements required. + * + * Same as rehash(ceil(n / max_load_factor())). + */ + void + reserve(size_type __n) + { _M_h.reserve(__n); } + + template + friend bool + operator==(const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&, + const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&); + }; + + /** + * @brief A standard container composed of equivalent keys + * (possibly containing multiple of each key value) that associates + * values of another type with the keys. + * + * @ingroup unordered_associative_containers + * + * @tparam _Key Type of key objects. + * @tparam _Tp Type of mapped objects. + * @tparam _Hash Hashing function object type, defaults to hash<_Value>. + * @tparam _Pred Predicate function object type, defaults + * to equal_to<_Value>. + * @tparam _Alloc Allocator type, defaults to + * std::allocator>. + * + * Meets the requirements of a container, and + * unordered associative container + * + * The resulting value type of the container is std::pair. + * + * Base is _Hashtable, dispatched at compile time via template + * alias __ummap_hashtable. + */ + template, + class _Pred = std::equal_to<_Key>, + class _Alloc = std::allocator > > + class unordered_multimap + { + typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; + _Hashtable _M_h; + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef typename _Hashtable::key_type key_type; + typedef typename _Hashtable::value_type value_type; + typedef typename _Hashtable::mapped_type mapped_type; + typedef typename _Hashtable::hasher hasher; + typedef typename _Hashtable::key_equal key_equal; + typedef typename _Hashtable::allocator_type allocator_type; + //@} + + //@{ + /// Iterator-related typedefs. + typedef typename _Hashtable::pointer pointer; + typedef typename _Hashtable::const_pointer const_pointer; + typedef typename _Hashtable::reference reference; + typedef typename _Hashtable::const_reference const_reference; + typedef typename _Hashtable::iterator iterator; + typedef typename _Hashtable::const_iterator const_iterator; + typedef typename _Hashtable::local_iterator local_iterator; + typedef typename _Hashtable::const_local_iterator const_local_iterator; + typedef typename _Hashtable::size_type size_type; + typedef typename _Hashtable::difference_type difference_type; + //@} + + //construct/destroy/copy + + /** + * @brief Default constructor creates no elements. + * @param __n Initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + */ + explicit + unordered_multimap(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__n, __hf, __eql, __a) + { } + + /** + * @brief Builds an %unordered_multimap from a range. + * @param __first An input iterator. + * @param __last An input iterator. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_multimap consisting of copies of the elements + * from [__first,__last). This is linear in N (where N is + * distance(__first,__last)). + */ + template + unordered_multimap(_InputIterator __f, _InputIterator __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__f, __l, __n, __hf, __eql, __a) + { } + + /// Copy constructor. + unordered_multimap(const unordered_multimap&) = default; + + /// Move constructor. + unordered_multimap(unordered_multimap&&) = default; + + /** + * @brief Creates an %unordered_multimap with no elements. + * @param __a An allocator object. + */ + explicit + unordered_multimap(const allocator_type& __a) + : _M_h(__a) + { } + + /* + * @brief Copy constructor with allocator argument. + * @param __uset Input %unordered_multimap to copy. + * @param __a An allocator object. + */ + unordered_multimap(const unordered_multimap& __ummap, + const allocator_type& __a) + : _M_h(__ummap._M_h, __a) + { } + + /* + * @brief Move constructor with allocator argument. + * @param __uset Input %unordered_multimap to move. + * @param __a An allocator object. + */ + unordered_multimap(unordered_multimap&& __ummap, + const allocator_type& __a) + : _M_h(std::move(__ummap._M_h), __a) + { } + + /** + * @brief Builds an %unordered_multimap from an initializer_list. + * @param __l An initializer_list. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_multimap consisting of copies of the elements in + * the list. This is linear in N (where N is @a __l.size()). + */ + unordered_multimap(std::initializer_list __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + /// Copy assignment operator. + unordered_multimap& + operator=(const unordered_multimap&) = default; + + /// Move assignment operator. + unordered_multimap& + operator=(unordered_multimap&&) = default; + + /** + * @brief %Unordered_multimap list assignment operator. + * @param __l An initializer_list. + * + * This function fills an %unordered_multimap with copies of the elements + * in the initializer list @a __l. + * + * Note that the assignment completely changes the %unordered_multimap + * and that the resulting %unordered_multimap's size is the same as the + * number of elements assigned. Old data may be lost. + */ + unordered_multimap& + operator=(std::initializer_list __l) + { + _M_h = __l; + return *this; + } + + /// Returns the allocator object with which the %unordered_multimap was + /// constructed. + allocator_type + get_allocator() const noexcept + { return _M_h.get_allocator(); } + + // size and capacity: + + /// Returns true if the %unordered_multimap is empty. + bool + empty() const noexcept + { return _M_h.empty(); } + + /// Returns the size of the %unordered_multimap. + size_type + size() const noexcept + { return _M_h.size(); } + + /// Returns the maximum size of the %unordered_multimap. + size_type + max_size() const noexcept + { return _M_h.max_size(); } + + // iterators. + + /** + * Returns a read/write iterator that points to the first element in the + * %unordered_multimap. + */ + iterator + begin() noexcept + { return _M_h.begin(); } + + //@{ + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %unordered_multimap. + */ + const_iterator + begin() const noexcept + { return _M_h.begin(); } + + const_iterator + cbegin() const noexcept + { return _M_h.begin(); } + //@} + + /** + * Returns a read/write iterator that points one past the last element in + * the %unordered_multimap. + */ + iterator + end() noexcept + { return _M_h.end(); } + + //@{ + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %unordered_multimap. + */ + const_iterator + end() const noexcept + { return _M_h.end(); } + + const_iterator + cend() const noexcept + { return _M_h.end(); } + //@} + + // modifiers. + + /** + * @brief Attempts to build and insert a std::pair into the + * %unordered_multimap. + * + * @param __args Arguments used to generate a new pair instance (see + * std::piecewise_contruct for passing arguments to each + * part of the pair constructor). + * + * @return An iterator that points to the inserted pair. + * + * This function attempts to build and insert a (key, value) %pair into + * the %unordered_multimap. + * + * Insertion requires amortized constant time. + */ + template + iterator + emplace(_Args&&... __args) + { return _M_h.emplace(std::forward<_Args>(__args)...); } + + /** + * @brief Attempts to build and insert a std::pair into the %unordered_multimap. + * + * @param __pos An iterator that serves as a hint as to where the pair + * should be inserted. + * @param __args Arguments used to generate a new pair instance (see + * std::piecewise_contruct for passing arguments to each + * part of the pair constructor). + * @return An iterator that points to the element with key of the + * std::pair built from @a __args. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * for more on @a hinting. + * + * Insertion requires amortized constant time. + */ + template + iterator + emplace_hint(const_iterator __pos, _Args&&... __args) + { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } + + //@{ + /** + * @brief Inserts a std::pair into the %unordered_multimap. + * @param __x Pair to be inserted (see std::make_pair for easy + * creation of pairs). + * + * @return An iterator that points to the inserted pair. + * + * Insertion requires amortized constant time. + */ + iterator + insert(const value_type& __x) + { return _M_h.insert(__x); } + + template::value>::type> + iterator + insert(_Pair&& __x) + { return _M_h.insert(std::forward<_Pair>(__x)); } + //@} + + //@{ + /** + * @brief Inserts a std::pair into the %unordered_multimap. + * @param __hint An iterator that serves as a hint as to where the + * pair should be inserted. + * @param __x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the element with key of + * @a __x (may or may not be the %pair passed in). + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * for more on @a hinting. + * + * Insertion requires amortized constant time. + */ + iterator + insert(const_iterator __hint, const value_type& __x) + { return _M_h.insert(__hint, __x); } + + template::value>::type> + iterator + insert(const_iterator __hint, _Pair&& __x) + { return _M_h.insert(__hint, std::forward<_Pair>(__x)); } + //@} + + /** + * @brief A template function that attempts to insert a range of + * elements. + * @param __first Iterator pointing to the start of the range to be + * inserted. + * @param __last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_h.insert(__first, __last); } + + /** + * @brief Attempts to insert a list of elements into the + * %unordered_multimap. + * @param __l A std::initializer_list of elements + * to be inserted. + * + * Complexity similar to that of the range constructor. + */ + void + insert(std::initializer_list __l) + { _M_h.insert(__l); } + + //@{ + /** + * @brief Erases an element from an %unordered_multimap. + * @param __position An iterator pointing to the element to be erased. + * @return An iterator pointing to the element immediately following + * @a __position prior to the element being erased. If no such + * element exists, end() is returned. + * + * This function erases an element, pointed to by the given iterator, + * from an %unordered_multimap. + * Note that this function only erases the element, and that if the + * element is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __position) + { return _M_h.erase(__position); } + + // LWG 2059. + iterator + erase(iterator __it) + { return _M_h.erase(__it); } + //@} + + /** + * @brief Erases elements according to the provided key. + * @param __x Key of elements to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * an %unordered_multimap. + * Note that this function only erases the element, and that if the + * element is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibility. + */ + size_type + erase(const key_type& __x) + { return _M_h.erase(__x); } + + /** + * @brief Erases a [__first,__last) range of elements from an + * %unordered_multimap. + * @param __first Iterator pointing to the start of the range to be + * erased. + * @param __last Iterator pointing to the end of the range to + * be erased. + * @return The iterator @a __last. + * + * This function erases a sequence of elements from an + * %unordered_multimap. + * Note that this function only erases the elements, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __first, const_iterator __last) + { return _M_h.erase(__first, __last); } + + /** + * Erases all elements in an %unordered_multimap. + * Note that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + void + clear() noexcept + { _M_h.clear(); } + + /** + * @brief Swaps data with another %unordered_multimap. + * @param __x An %unordered_multimap of the same element and allocator + * types. + * + * This exchanges the elements between two %unordered_multimap in + * constant time. + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(unordered_multimap& __x) + noexcept( noexcept(_M_h.swap(__x._M_h)) ) + { _M_h.swap(__x._M_h); } + + // observers. + + /// Returns the hash functor object with which the %unordered_multimap + /// was constructed. + hasher + hash_function() const + { return _M_h.hash_function(); } + + /// Returns the key comparison object with which the %unordered_multimap + /// was constructed. + key_equal + key_eq() const + { return _M_h.key_eq(); } + + // lookup. + + //@{ + /** + * @brief Tries to locate an element in an %unordered_multimap. + * @param __x Key to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_h.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_h.find(__x); } + //@} + + /** + * @brief Finds the number of elements. + * @param __x Key to count. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_h.count(__x); } + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param __x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + */ + std::pair + equal_range(const key_type& __x) + { return _M_h.equal_range(__x); } + + std::pair + equal_range(const key_type& __x) const + { return _M_h.equal_range(__x); } + //@} + + // bucket interface. + + /// Returns the number of buckets of the %unordered_multimap. + size_type + bucket_count() const noexcept + { return _M_h.bucket_count(); } + + /// Returns the maximum number of buckets of the %unordered_multimap. + size_type + max_bucket_count() const noexcept + { return _M_h.max_bucket_count(); } + + /* + * @brief Returns the number of elements in a given bucket. + * @param __n A bucket index. + * @return The number of elements in the bucket. + */ + size_type + bucket_size(size_type __n) const + { return _M_h.bucket_size(__n); } + + /* + * @brief Returns the bucket index of a given element. + * @param __key A key instance. + * @return The key bucket index. + */ + size_type + bucket(const key_type& __key) const + { return _M_h.bucket(__key); } + + /** + * @brief Returns a read/write iterator pointing to the first bucket + * element. + * @param __n The bucket index. + * @return A read/write local iterator. + */ + local_iterator + begin(size_type __n) + { return _M_h.begin(__n); } + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to the first + * bucket element. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + const_local_iterator + begin(size_type __n) const + { return _M_h.begin(__n); } + + const_local_iterator + cbegin(size_type __n) const + { return _M_h.cbegin(__n); } + //@} + + /** + * @brief Returns a read/write iterator pointing to one past the last + * bucket elements. + * @param __n The bucket index. + * @return A read/write local iterator. + */ + local_iterator + end(size_type __n) + { return _M_h.end(__n); } + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to one past + * the last bucket elements. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + const_local_iterator + end(size_type __n) const + { return _M_h.end(__n); } + + const_local_iterator + cend(size_type __n) const + { return _M_h.cend(__n); } + //@} + + // hash policy. + + /// Returns the average number of elements per bucket. + float + load_factor() const noexcept + { return _M_h.load_factor(); } + + /// Returns a positive number that the %unordered_multimap tries to keep + /// the load factor less than or equal to. + float + max_load_factor() const noexcept + { return _M_h.max_load_factor(); } + + /** + * @brief Change the %unordered_multimap maximum load factor. + * @param __z The new maximum load factor. + */ + void + max_load_factor(float __z) + { _M_h.max_load_factor(__z); } + + /** + * @brief May rehash the %unordered_multimap. + * @param __n The new number of buckets. + * + * Rehash will occur only if the new number of buckets respect the + * %unordered_multimap maximum load factor. + */ + void + rehash(size_type __n) + { _M_h.rehash(__n); } + + /** + * @brief Prepare the %unordered_multimap for a specified number of + * elements. + * @param __n Number of elements required. + * + * Same as rehash(ceil(n / max_load_factor())). + */ + void + reserve(size_type __n) + { _M_h.reserve(__n); } + + template + friend bool + operator==(const unordered_multimap<_Key1, _Tp1, + _Hash1, _Pred1, _Alloc1>&, + const unordered_multimap<_Key1, _Tp1, + _Hash1, _Pred1, _Alloc1>&); + }; + + template + inline void + swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + + template + inline void + swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + + template + inline bool + operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { return __x._M_h._M_equal(__y._M_h); } + + template + inline bool + operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { return !(__x == __y); } + + template + inline bool + operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { return __x._M_h._M_equal(__y._M_h); } + + template + inline bool + operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, + const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + { return !(__x == __y); } + +_GLIBCXX_END_NAMESPACE_CONTAINER +} // namespace std diff --git a/loader/include/Geode/c++stl/gnustl/unordered_map.hpp b/loader/include/Geode/c++stl/gnustl/unordered_map.hpp new file mode 100644 index 00000000..10c8f6fc --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/unordered_map.hpp @@ -0,0 +1,48 @@ +// -*- C++ -*- + +// Copyright (C) 2007-2014 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 +// . + +/** @file include/unordered_map + * This is a Standard C++ Library header. + */ + +#pragma once + +#if __cplusplus < 201103L +# error not c++11 +#else + +#include +#include +#include +#include +#include "allocator.h" +#include "ext/alloc_traits.h" +#include "ext/aligned_buffer.h" +#include "stl_function.h" // equal_to, _Identity, _Select1st +#include "functional_hash.h" +#include "hashtable.h" +#include "unordered_map.h" +#include "range_access.h" + +#endif // C++11 diff --git a/loader/include/Geode/c++stl/gnustl/unordered_set.h b/loader/include/Geode/c++stl/gnustl/unordered_set.h new file mode 100644 index 00000000..b4081e05 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/unordered_set.h @@ -0,0 +1,1354 @@ +// unordered_set implementation -*- C++ -*- + +// Copyright (C) 2010-2014 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 +// . + +/** @file bits/unordered_set.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{unordered_set} + */ + +#pragma once + +#include "c++config.h" + +namespace geode::stl { +_GLIBCXX_BEGIN_NAMESPACE_CONTAINER + + /// Base types for unordered_set. + template + using __uset_traits = __detail::_Hashtable_traits<_Cache, true, true>; + + template, + typename _Pred = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value>, + typename _Tr = __uset_traits<__cache_default<_Value, _Hash>::value>> + using __uset_hashtable = _Hashtable<_Value, _Value, _Alloc, + __detail::_Identity, _Pred, _Hash, + __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, _Tr>; + + /// Base types for unordered_multiset. + template + using __umset_traits = __detail::_Hashtable_traits<_Cache, true, false>; + + template, + typename _Pred = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value>, + typename _Tr = __umset_traits<__cache_default<_Value, _Hash>::value>> + using __umset_hashtable = _Hashtable<_Value, _Value, _Alloc, + __detail::_Identity, + _Pred, _Hash, + __detail::_Mod_range_hashing, + __detail::_Default_ranged_hash, + __detail::_Prime_rehash_policy, _Tr>; + + /** + * @brief A standard container composed of unique keys (containing + * at most one of each key value) in which the elements' keys are + * the elements themselves. + * + * @ingroup unordered_associative_containers + * + * @tparam _Value Type of key objects. + * @tparam _Hash Hashing function object type, defaults to hash<_Value>. + + * @tparam _Pred Predicate function object type, defaults to + * equal_to<_Value>. + * + * @tparam _Alloc Allocator type, defaults to allocator<_Key>. + * + * Meets the requirements of a container, and + * unordered associative container + * + * Base is _Hashtable, dispatched at compile time via template + * alias __uset_hashtable. + */ + template, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class unordered_set + { + typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable; + _Hashtable _M_h; + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef typename _Hashtable::key_type key_type; + typedef typename _Hashtable::value_type value_type; + typedef typename _Hashtable::hasher hasher; + typedef typename _Hashtable::key_equal key_equal; + typedef typename _Hashtable::allocator_type allocator_type; + //@} + + //@{ + /// Iterator-related typedefs. + typedef typename _Hashtable::pointer pointer; + typedef typename _Hashtable::const_pointer const_pointer; + typedef typename _Hashtable::reference reference; + typedef typename _Hashtable::const_reference const_reference; + typedef typename _Hashtable::iterator iterator; + typedef typename _Hashtable::const_iterator const_iterator; + typedef typename _Hashtable::local_iterator local_iterator; + typedef typename _Hashtable::const_local_iterator const_local_iterator; + typedef typename _Hashtable::size_type size_type; + typedef typename _Hashtable::difference_type difference_type; + //@} + + // construct/destroy/copy + /** + * @brief Default constructor creates no elements. + * @param __n Initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + */ + explicit + unordered_set(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__n, __hf, __eql, __a) + { } + + /** + * @brief Builds an %unordered_set from a range. + * @param __first An input iterator. + * @param __last An input iterator. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_set consisting of copies of the elements from + * [__first,__last). This is linear in N (where N is + * distance(__first,__last)). + */ + template + unordered_set(_InputIterator __f, _InputIterator __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__f, __l, __n, __hf, __eql, __a) + { } + + /// Copy constructor. + unordered_set(const unordered_set&) = default; + + /// Move constructor. + unordered_set(unordered_set&&) = default; + + /** + * @brief Creates an %unordered_set with no elements. + * @param __a An allocator object. + */ + explicit + unordered_set(const allocator_type& __a) + : _M_h(__a) + { } + + /* + * @brief Copy constructor with allocator argument. + * @param __uset Input %unordered_set to copy. + * @param __a An allocator object. + */ + unordered_set(const unordered_set& __uset, + const allocator_type& __a) + : _M_h(__uset._M_h, __a) + { } + + /* + * @brief Move constructor with allocator argument. + * @param __uset Input %unordered_set to move. + * @param __a An allocator object. + */ + unordered_set(unordered_set&& __uset, + const allocator_type& __a) + : _M_h(std::move(__uset._M_h), __a) + { } + + /** + * @brief Builds an %unordered_set from an initializer_list. + * @param __l An initializer_list. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_set consisting of copies of the elements in the + * list. This is linear in N (where N is @a __l.size()). + */ + unordered_set(std::initializer_list __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + /// Copy assignment operator. + unordered_set& + operator=(const unordered_set&) = default; + + /// Move assignment operator. + unordered_set& + operator=(unordered_set&&) = default; + + /** + * @brief %Unordered_set list assignment operator. + * @param __l An initializer_list. + * + * This function fills an %unordered_set with copies of the elements in + * the initializer list @a __l. + * + * Note that the assignment completely changes the %unordered_set and + * that the resulting %unordered_set's size is the same as the number + * of elements assigned. Old data may be lost. + */ + unordered_set& + operator=(std::initializer_list __l) + { + _M_h = __l; + return *this; + } + + /// Returns the allocator object with which the %unordered_set was + /// constructed. + allocator_type + get_allocator() const noexcept + { return _M_h.get_allocator(); } + + // size and capacity: + + /// Returns true if the %unordered_set is empty. + bool + empty() const noexcept + { return _M_h.empty(); } + + /// Returns the size of the %unordered_set. + size_type + size() const noexcept + { return _M_h.size(); } + + /// Returns the maximum size of the %unordered_set. + size_type + max_size() const noexcept + { return _M_h.max_size(); } + + // iterators. + + //@{ + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %unordered_set. + */ + iterator + begin() noexcept + { return _M_h.begin(); } + + const_iterator + begin() const noexcept + { return _M_h.begin(); } + //@} + + //@{ + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %unordered_set. + */ + iterator + end() noexcept + { return _M_h.end(); } + + const_iterator + end() const noexcept + { return _M_h.end(); } + //@} + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %unordered_set. + */ + const_iterator + cbegin() const noexcept + { return _M_h.begin(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %unordered_set. + */ + const_iterator + cend() const noexcept + { return _M_h.end(); } + + // modifiers. + + /** + * @brief Attempts to build and insert an element into the + * %unordered_set. + * @param __args Arguments used to generate an element. + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. + * + * This function attempts to build and insert an element into the + * %unordered_set. An %unordered_set relies on unique keys and thus an + * element is only inserted if it is not already present in the + * %unordered_set. + * + * Insertion requires amortized constant time. + */ + template + std::pair + emplace(_Args&&... __args) + { return _M_h.emplace(std::forward<_Args>(__args)...); } + + /** + * @brief Attempts to insert an element into the %unordered_set. + * @param __pos An iterator that serves as a hint as to where the + * element should be inserted. + * @param __args Arguments used to generate the element to be + * inserted. + * @return An iterator that points to the element with key equivalent to + * the one generated from @a __args (may or may not be the + * element itself). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument emplace() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * For more on @a hinting, see: + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * + * Insertion requires amortized constant time. + */ + template + iterator + emplace_hint(const_iterator __pos, _Args&&... __args) + { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } + + //@{ + /** + * @brief Attempts to insert an element into the %unordered_set. + * @param __x Element to be inserted. + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. + * + * This function attempts to insert an element into the %unordered_set. + * An %unordered_set relies on unique keys and thus an element is only + * inserted if it is not already present in the %unordered_set. + * + * Insertion requires amortized constant time. + */ + std::pair + insert(const value_type& __x) + { return _M_h.insert(__x); } + + std::pair + insert(value_type&& __x) + { return _M_h.insert(std::move(__x)); } + //@} + + //@{ + /** + * @brief Attempts to insert an element into the %unordered_set. + * @param __hint An iterator that serves as a hint as to where the + * element should be inserted. + * @param __x Element to be inserted. + * @return An iterator that points to the element with key of + * @a __x (may or may not be the element passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument insert() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * For more on @a hinting, see: + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * + * Insertion requires amortized constant. + */ + iterator + insert(const_iterator __hint, const value_type& __x) + { return _M_h.insert(__hint, __x); } + + iterator + insert(const_iterator __hint, value_type&& __x) + { return _M_h.insert(__hint, std::move(__x)); } + //@} + + /** + * @brief A template function that attempts to insert a range of + * elements. + * @param __first Iterator pointing to the start of the range to be + * inserted. + * @param __last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_h.insert(__first, __last); } + + /** + * @brief Attempts to insert a list of elements into the %unordered_set. + * @param __l A std::initializer_list of elements + * to be inserted. + * + * Complexity similar to that of the range constructor. + */ + void + insert(std::initializer_list __l) + { _M_h.insert(__l); } + + //@{ + /** + * @brief Erases an element from an %unordered_set. + * @param __position An iterator pointing to the element to be erased. + * @return An iterator pointing to the element immediately following + * @a __position prior to the element being erased. If no such + * element exists, end() is returned. + * + * This function erases an element, pointed to by the given iterator, + * from an %unordered_set. Note that this function only erases the + * element, and that if the element is itself a pointer, the pointed-to + * memory is not touched in any way. Managing the pointer is the user's + * responsibility. + */ + iterator + erase(const_iterator __position) + { return _M_h.erase(__position); } + + // LWG 2059. + iterator + erase(iterator __it) + { return _M_h.erase(__it); } + //@} + + /** + * @brief Erases elements according to the provided key. + * @param __x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * an %unordered_set. For an %unordered_set the result of this function + * can only be 0 (not present) or 1 (present). + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + size_type + erase(const key_type& __x) + { return _M_h.erase(__x); } + + /** + * @brief Erases a [__first,__last) range of elements from an + * %unordered_set. + * @param __first Iterator pointing to the start of the range to be + * erased. + * @param __last Iterator pointing to the end of the range to + * be erased. + * @return The iterator @a __last. + * + * This function erases a sequence of elements from an %unordered_set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __first, const_iterator __last) + { return _M_h.erase(__first, __last); } + + /** + * Erases all elements in an %unordered_set. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibility. + */ + void + clear() noexcept + { _M_h.clear(); } + + /** + * @brief Swaps data with another %unordered_set. + * @param __x An %unordered_set of the same element and allocator + * types. + * + * This exchanges the elements between two sets in constant time. + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(unordered_set& __x) + noexcept( noexcept(_M_h.swap(__x._M_h)) ) + { _M_h.swap(__x._M_h); } + + // observers. + + /// Returns the hash functor object with which the %unordered_set was + /// constructed. + hasher + hash_function() const + { return _M_h.hash_function(); } + + /// Returns the key comparison object with which the %unordered_set was + /// constructed. + key_equal + key_eq() const + { return _M_h.key_eq(); } + + // lookup. + + //@{ + /** + * @brief Tries to locate an element in an %unordered_set. + * @param __x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_h.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_h.find(__x); } + //@} + + /** + * @brief Finds the number of elements. + * @param __x Element to located. + * @return Number of elements with specified key. + * + * This function only makes sense for unordered_multisets; for + * unordered_set the result will either be 0 (not present) or 1 + * (present). + */ + size_type + count(const key_type& __x) const + { return _M_h.count(__x); } + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param __x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function probably only makes sense for multisets. + */ + std::pair + equal_range(const key_type& __x) + { return _M_h.equal_range(__x); } + + std::pair + equal_range(const key_type& __x) const + { return _M_h.equal_range(__x); } + //@} + + // bucket interface. + + /// Returns the number of buckets of the %unordered_set. + size_type + bucket_count() const noexcept + { return _M_h.bucket_count(); } + + /// Returns the maximum number of buckets of the %unordered_set. + size_type + max_bucket_count() const noexcept + { return _M_h.max_bucket_count(); } + + /* + * @brief Returns the number of elements in a given bucket. + * @param __n A bucket index. + * @return The number of elements in the bucket. + */ + size_type + bucket_size(size_type __n) const + { return _M_h.bucket_size(__n); } + + /* + * @brief Returns the bucket index of a given element. + * @param __key A key instance. + * @return The key bucket index. + */ + size_type + bucket(const key_type& __key) const + { return _M_h.bucket(__key); } + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to the first + * bucket element. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + local_iterator + begin(size_type __n) + { return _M_h.begin(__n); } + + const_local_iterator + begin(size_type __n) const + { return _M_h.begin(__n); } + + const_local_iterator + cbegin(size_type __n) const + { return _M_h.cbegin(__n); } + //@} + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to one past + * the last bucket elements. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + local_iterator + end(size_type __n) + { return _M_h.end(__n); } + + const_local_iterator + end(size_type __n) const + { return _M_h.end(__n); } + + const_local_iterator + cend(size_type __n) const + { return _M_h.cend(__n); } + //@} + + // hash policy. + + /// Returns the average number of elements per bucket. + float + load_factor() const noexcept + { return _M_h.load_factor(); } + + /// Returns a positive number that the %unordered_set tries to keep the + /// load factor less than or equal to. + float + max_load_factor() const noexcept + { return _M_h.max_load_factor(); } + + /** + * @brief Change the %unordered_set maximum load factor. + * @param __z The new maximum load factor. + */ + void + max_load_factor(float __z) + { _M_h.max_load_factor(__z); } + + /** + * @brief May rehash the %unordered_set. + * @param __n The new number of buckets. + * + * Rehash will occur only if the new number of buckets respect the + * %unordered_set maximum load factor. + */ + void + rehash(size_type __n) + { _M_h.rehash(__n); } + + /** + * @brief Prepare the %unordered_set for a specified number of + * elements. + * @param __n Number of elements required. + * + * Same as rehash(ceil(n / max_load_factor())). + */ + void + reserve(size_type __n) + { _M_h.reserve(__n); } + + template + friend bool + operator==(const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&, + const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&); + }; + + /** + * @brief A standard container composed of equivalent keys + * (possibly containing multiple of each key value) in which the + * elements' keys are the elements themselves. + * + * @ingroup unordered_associative_containers + * + * @tparam _Value Type of key objects. + * @tparam _Hash Hashing function object type, defaults to hash<_Value>. + * @tparam _Pred Predicate function object type, defaults + * to equal_to<_Value>. + * @tparam _Alloc Allocator type, defaults to allocator<_Key>. + * + * Meets the requirements of a container, and + * unordered associative container + * + * Base is _Hashtable, dispatched at compile time via template + * alias __umset_hashtable. + */ + template, + class _Pred = std::equal_to<_Value>, + class _Alloc = std::allocator<_Value> > + class unordered_multiset + { + typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable; + _Hashtable _M_h; + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef typename _Hashtable::key_type key_type; + typedef typename _Hashtable::value_type value_type; + typedef typename _Hashtable::hasher hasher; + typedef typename _Hashtable::key_equal key_equal; + typedef typename _Hashtable::allocator_type allocator_type; + //@} + + //@{ + /// Iterator-related typedefs. + typedef typename _Hashtable::pointer pointer; + typedef typename _Hashtable::const_pointer const_pointer; + typedef typename _Hashtable::reference reference; + typedef typename _Hashtable::const_reference const_reference; + typedef typename _Hashtable::iterator iterator; + typedef typename _Hashtable::const_iterator const_iterator; + typedef typename _Hashtable::local_iterator local_iterator; + typedef typename _Hashtable::const_local_iterator const_local_iterator; + typedef typename _Hashtable::size_type size_type; + typedef typename _Hashtable::difference_type difference_type; + //@} + + // construct/destroy/copy + /** + * @brief Default constructor creates no elements. + * @param __n Initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + */ + explicit + unordered_multiset(size_type __n = 10, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__n, __hf, __eql, __a) + { } + + /** + * @brief Builds an %unordered_multiset from a range. + * @param __first An input iterator. + * @param __last An input iterator. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_multiset consisting of copies of the elements + * from [__first,__last). This is linear in N (where N is + * distance(__first,__last)). + */ + template + unordered_multiset(_InputIterator __f, _InputIterator __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__f, __l, __n, __hf, __eql, __a) + { } + + /// Copy constructor. + unordered_multiset(const unordered_multiset&) = default; + + /// Move constructor. + unordered_multiset(unordered_multiset&&) = default; + + /** + * @brief Builds an %unordered_multiset from an initializer_list. + * @param __l An initializer_list. + * @param __n Minimal initial number of buckets. + * @param __hf A hash functor. + * @param __eql A key equality functor. + * @param __a An allocator object. + * + * Create an %unordered_multiset consisting of copies of the elements in + * the list. This is linear in N (where N is @a __l.size()). + */ + unordered_multiset(std::initializer_list __l, + size_type __n = 0, + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + /// Copy assignment operator. + unordered_multiset& + operator=(const unordered_multiset&) = default; + + /// Move assignment operator. + unordered_multiset& + operator=(unordered_multiset&&) = default; + + /** + * @brief Creates an %unordered_multiset with no elements. + * @param __a An allocator object. + */ + explicit + unordered_multiset(const allocator_type& __a) + : _M_h(__a) + { } + + /* + * @brief Copy constructor with allocator argument. + * @param __uset Input %unordered_multiset to copy. + * @param __a An allocator object. + */ + unordered_multiset(const unordered_multiset& __umset, + const allocator_type& __a) + : _M_h(__umset._M_h, __a) + { } + + /* + * @brief Move constructor with allocator argument. + * @param __umset Input %unordered_multiset to move. + * @param __a An allocator object. + */ + unordered_multiset(unordered_multiset&& __umset, + const allocator_type& __a) + : _M_h(std::move(__umset._M_h), __a) + { } + + /** + * @brief %Unordered_multiset list assignment operator. + * @param __l An initializer_list. + * + * This function fills an %unordered_multiset with copies of the elements + * in the initializer list @a __l. + * + * Note that the assignment completely changes the %unordered_multiset + * and that the resulting %unordered_set's size is the same as the number + * of elements assigned. Old data may be lost. + */ + unordered_multiset& + operator=(std::initializer_list __l) + { + _M_h = __l; + return *this; + } + + /// Returns the allocator object with which the %unordered_multiset was + /// constructed. + allocator_type + get_allocator() const noexcept + { return _M_h.get_allocator(); } + + // size and capacity: + + /// Returns true if the %unordered_multiset is empty. + bool + empty() const noexcept + { return _M_h.empty(); } + + /// Returns the size of the %unordered_multiset. + size_type + size() const noexcept + { return _M_h.size(); } + + /// Returns the maximum size of the %unordered_multiset. + size_type + max_size() const noexcept + { return _M_h.max_size(); } + + // iterators. + + //@{ + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %unordered_multiset. + */ + iterator + begin() noexcept + { return _M_h.begin(); } + + const_iterator + begin() const noexcept + { return _M_h.begin(); } + //@} + + //@{ + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %unordered_multiset. + */ + iterator + end() noexcept + { return _M_h.end(); } + + const_iterator + end() const noexcept + { return _M_h.end(); } + //@} + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %unordered_multiset. + */ + const_iterator + cbegin() const noexcept + { return _M_h.begin(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %unordered_multiset. + */ + const_iterator + cend() const noexcept + { return _M_h.end(); } + + // modifiers. + + /** + * @brief Builds and insert an element into the %unordered_multiset. + * @param __args Arguments used to generate an element. + * @return An iterator that points to the inserted element. + * + * Insertion requires amortized constant time. + */ + template + iterator + emplace(_Args&&... __args) + { return _M_h.emplace(std::forward<_Args>(__args)...); } + + /** + * @brief Inserts an element into the %unordered_multiset. + * @param __pos An iterator that serves as a hint as to where the + * element should be inserted. + * @param __args Arguments used to generate the element to be + * inserted. + * @return An iterator that points to the inserted element. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * For more on @a hinting, see: + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * + * Insertion requires amortized constant time. + */ + template + iterator + emplace_hint(const_iterator __pos, _Args&&... __args) + { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } + + //@{ + /** + * @brief Inserts an element into the %unordered_multiset. + * @param __x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * Insertion requires amortized constant time. + */ + iterator + insert(const value_type& __x) + { return _M_h.insert(__x); } + + iterator + insert(value_type&& __x) + { return _M_h.insert(std::move(__x)); } + //@} + + //@{ + /** + * @brief Inserts an element into the %unordered_multiset. + * @param __hint An iterator that serves as a hint as to where the + * element should be inserted. + * @param __x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * For more on @a hinting, see: + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt07ch17.html + * + * Insertion requires amortized constant. + */ + iterator + insert(const_iterator __hint, const value_type& __x) + { return _M_h.insert(__hint, __x); } + + iterator + insert(const_iterator __hint, value_type&& __x) + { return _M_h.insert(__hint, std::move(__x)); } + //@} + + /** + * @brief A template function that inserts a range of elements. + * @param __first Iterator pointing to the start of the range to be + * inserted. + * @param __last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_h.insert(__first, __last); } + + /** + * @brief Inserts a list of elements into the %unordered_multiset. + * @param __l A std::initializer_list of elements to be + * inserted. + * + * Complexity similar to that of the range constructor. + */ + void + insert(std::initializer_list __l) + { _M_h.insert(__l); } + + //@{ + /** + * @brief Erases an element from an %unordered_multiset. + * @param __position An iterator pointing to the element to be erased. + * @return An iterator pointing to the element immediately following + * @a __position prior to the element being erased. If no such + * element exists, end() is returned. + * + * This function erases an element, pointed to by the given iterator, + * from an %unordered_multiset. + * + * Note that this function only erases the element, and that if the + * element is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __position) + { return _M_h.erase(__position); } + + // LWG 2059. + iterator + erase(iterator __it) + { return _M_h.erase(__it); } + //@} + + + /** + * @brief Erases elements according to the provided key. + * @param __x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * an %unordered_multiset. + * + * Note that this function only erases the element, and that if the + * element is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibility. + */ + size_type + erase(const key_type& __x) + { return _M_h.erase(__x); } + + /** + * @brief Erases a [__first,__last) range of elements from an + * %unordered_multiset. + * @param __first Iterator pointing to the start of the range to be + * erased. + * @param __last Iterator pointing to the end of the range to + * be erased. + * @return The iterator @a __last. + * + * This function erases a sequence of elements from an + * %unordered_multiset. + * + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + iterator + erase(const_iterator __first, const_iterator __last) + { return _M_h.erase(__first, __last); } + + /** + * Erases all elements in an %unordered_multiset. + * + * Note that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibility. + */ + void + clear() noexcept + { _M_h.clear(); } + + /** + * @brief Swaps data with another %unordered_multiset. + * @param __x An %unordered_multiset of the same element and allocator + * types. + * + * This exchanges the elements between two sets in constant time. + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(unordered_multiset& __x) + noexcept( noexcept(_M_h.swap(__x._M_h)) ) + { _M_h.swap(__x._M_h); } + + // observers. + + /// Returns the hash functor object with which the %unordered_multiset + /// was constructed. + hasher + hash_function() const + { return _M_h.hash_function(); } + + /// Returns the key comparison object with which the %unordered_multiset + /// was constructed. + key_equal + key_eq() const + { return _M_h.key_eq(); } + + // lookup. + + //@{ + /** + * @brief Tries to locate an element in an %unordered_multiset. + * @param __x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_h.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_h.find(__x); } + //@} + + /** + * @brief Finds the number of elements. + * @param __x Element to located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_h.count(__x); } + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param __x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + */ + std::pair + equal_range(const key_type& __x) + { return _M_h.equal_range(__x); } + + std::pair + equal_range(const key_type& __x) const + { return _M_h.equal_range(__x); } + //@} + + // bucket interface. + + /// Returns the number of buckets of the %unordered_multiset. + size_type + bucket_count() const noexcept + { return _M_h.bucket_count(); } + + /// Returns the maximum number of buckets of the %unordered_multiset. + size_type + max_bucket_count() const noexcept + { return _M_h.max_bucket_count(); } + + /* + * @brief Returns the number of elements in a given bucket. + * @param __n A bucket index. + * @return The number of elements in the bucket. + */ + size_type + bucket_size(size_type __n) const + { return _M_h.bucket_size(__n); } + + /* + * @brief Returns the bucket index of a given element. + * @param __key A key instance. + * @return The key bucket index. + */ + size_type + bucket(const key_type& __key) const + { return _M_h.bucket(__key); } + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to the first + * bucket element. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + local_iterator + begin(size_type __n) + { return _M_h.begin(__n); } + + const_local_iterator + begin(size_type __n) const + { return _M_h.begin(__n); } + + const_local_iterator + cbegin(size_type __n) const + { return _M_h.cbegin(__n); } + //@} + + //@{ + /** + * @brief Returns a read-only (constant) iterator pointing to one past + * the last bucket elements. + * @param __n The bucket index. + * @return A read-only local iterator. + */ + local_iterator + end(size_type __n) + { return _M_h.end(__n); } + + const_local_iterator + end(size_type __n) const + { return _M_h.end(__n); } + + const_local_iterator + cend(size_type __n) const + { return _M_h.cend(__n); } + //@} + + // hash policy. + + /// Returns the average number of elements per bucket. + float + load_factor() const noexcept + { return _M_h.load_factor(); } + + /// Returns a positive number that the %unordered_multiset tries to keep the + /// load factor less than or equal to. + float + max_load_factor() const noexcept + { return _M_h.max_load_factor(); } + + /** + * @brief Change the %unordered_multiset maximum load factor. + * @param __z The new maximum load factor. + */ + void + max_load_factor(float __z) + { _M_h.max_load_factor(__z); } + + /** + * @brief May rehash the %unordered_multiset. + * @param __n The new number of buckets. + * + * Rehash will occur only if the new number of buckets respect the + * %unordered_multiset maximum load factor. + */ + void + rehash(size_type __n) + { _M_h.rehash(__n); } + + /** + * @brief Prepare the %unordered_multiset for a specified number of + * elements. + * @param __n Number of elements required. + * + * Same as rehash(ceil(n / max_load_factor())). + */ + void + reserve(size_type __n) + { _M_h.reserve(__n); } + + template + friend bool + operator==(const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&, + const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&); + }; + + template + inline void + swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, + unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + + template + inline void + swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) + { __x.swap(__y); } + + template + inline bool + operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, + const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) + { return __x._M_h._M_equal(__y._M_h); } + + template + inline bool + operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, + const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) + { return !(__x == __y); } + + template + inline bool + operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) + { return __x._M_h._M_equal(__y._M_h); } + + template + inline bool + operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, + const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) + { return !(__x == __y); } + +_GLIBCXX_END_NAMESPACE_CONTAINER +} // namespace std diff --git a/loader/include/Geode/c++stl/gnustl/unordered_set.hpp b/loader/include/Geode/c++stl/gnustl/unordered_set.hpp new file mode 100644 index 00000000..c7f3f242 --- /dev/null +++ b/loader/include/Geode/c++stl/gnustl/unordered_set.hpp @@ -0,0 +1,53 @@ +// -*- C++ -*- + +// Copyright (C) 2007-2014 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 +// . + +/** @file include/unordered_set + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_UNORDERED_SET +#define _GLIBCXX_UNORDERED_SET 1 + +#pragma GCC system_header + +#if __cplusplus < 201103L +# error "not c++11" +#else + +#include +#include +#include +#include +#include "allocator.h" +#include "ext/alloc_traits.h" +#include "ext/aligned_buffer.h" +#include "stl_function.h" // equal_to, _Identity, _Select1st +#include "functional_hash.h" +#include "hashtable.h" +#include "unordered_set.h" +#include "range_access.h" + +#endif // C++11 + +#endif // _GLIBCXX_UNORDERED_SET