�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PKgd1]XsT T 8/iteratornu[// -*- C++ -*- // Copyright (C) 2001-2018 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,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 include/iterator * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ITERATOR #define _GLIBCXX_ITERATOR 1 #pragma GCC system_header #include #include #include #include #include #include #include #include #include #endif /* _GLIBCXX_ITERATOR */ PKgd1]AuAu 8/streambufnu[// Stream buffer classes -*- C++ -*- // Copyright (C) 1997-2018 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/streambuf * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.5 Stream buffers // #ifndef _GLIBXX_STREAMBUF #define _GLIBXX_STREAMBUF 1 #pragma GCC system_header #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #define _IsUnused __attribute__ ((__unused__)) template streamsize __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>*, basic_streambuf<_CharT, _Traits>*, bool&); /** * @brief The actual work of input and output (interface). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This is a base class. Derived stream buffers each control a * pair of character sequences: one for input, and one for output. * * Section [27.5.1] of the standard describes the requirements and * behavior of stream buffer classes. That section (three paragraphs) * is reproduced here, for simplicity and accuracy. * * -# Stream buffers can impose various constraints on the sequences * they control. Some constraints are: * - The controlled input sequence can be not readable. * - The controlled output sequence can be not writable. * - The controlled sequences can be associated with the contents of * other representations for character sequences, such as external * files. * - The controlled sequences can support operations @e directly to or * from associated sequences. * - The controlled sequences can impose limitations on how the * program can read characters from a sequence, write characters to * a sequence, put characters back into an input sequence, or alter * the stream position. * . * -# Each sequence is characterized by three pointers which, if non-null, * all point into the same @c charT array object. The array object * represents, at any moment, a (sub)sequence of characters from the * sequence. Operations performed on a sequence alter the values * stored in these pointers, perform reads and writes directly to or * from associated sequences, and alter the stream position and * conversion state as needed to maintain this subsequence relationship. * The three pointers are: * - the beginning pointer, or lowest element address in the * array (called @e xbeg here); * - the next pointer, or next element address that is a * current candidate for reading or writing (called @e xnext here); * - the end pointer, or first element address beyond the * end of the array (called @e xend here). * . * -# The following semantic constraints shall always apply for any set * of three pointers for a sequence, using the pointer names given * immediately above: * - If @e xnext is not a null pointer, then @e xbeg and @e xend shall * also be non-null pointers into the same @c charT array, as * described above; otherwise, @e xbeg and @e xend shall also be null. * - If @e xnext is not a null pointer and @e xnext < @e xend for an * output sequence, then a write position is available. * In this case, @e *xnext shall be assignable as the next element * to write (to put, or to store a character value, into the sequence). * - If @e xnext is not a null pointer and @e xbeg < @e xnext for an * input sequence, then a putback position is available. * In this case, @e xnext[-1] shall have a defined value and is the * next (preceding) element to store a character that is put back * into the input sequence. * - If @e xnext is not a null pointer and @e xnext< @e xend for an * input sequence, then a read position is available. * In this case, @e *xnext shall have a defined value and is the * next element to read (to get, or to obtain a character value, * from the sequence). */ template class basic_streambuf { public: //@{ /** * These are standard types. They permit a standardized way of * referring to names of (or names dependent on) the template * parameters, which are specific to the implementation. */ typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; //@} //@{ /// This is a non-standard type. typedef basic_streambuf __streambuf_type; //@} friend class basic_ios; friend class basic_istream; friend class basic_ostream; friend class istreambuf_iterator; friend class ostreambuf_iterator; friend streamsize __copy_streambufs_eof<>(basic_streambuf*, basic_streambuf*, bool&); template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, _CharT2*>::__type __copy_move_a2(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, _CharT2*); template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, istreambuf_iterator<_CharT2> >::__type find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, void>::__type advance(istreambuf_iterator<_CharT2>&, _Distance); template friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); template friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, basic_string<_CharT2, _Traits2, _Alloc>&); template friend basic_istream<_CharT2, _Traits2>& getline(basic_istream<_CharT2, _Traits2>&, basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2); protected: /* * This is based on _IO_FILE, just reordered to be more consistent, * and is intended to be the most minimal abstraction for an * internal buffer. * - get == input == read * - put == output == write */ char_type* _M_in_beg; ///< Start of get area. char_type* _M_in_cur; ///< Current read area. char_type* _M_in_end; ///< End of get area. char_type* _M_out_beg; ///< Start of put area. char_type* _M_out_cur; ///< Current put area. char_type* _M_out_end; ///< End of put area. /// Current locale setting. locale _M_buf_locale; public: /// Destructor deallocates no buffer space. virtual ~basic_streambuf() { } // [27.5.2.2.1] locales /** * @brief Entry point for imbue(). * @param __loc The new locale. * @return The previous locale. * * Calls the derived imbue(__loc). */ locale pubimbue(const locale& __loc) { locale __tmp(this->getloc()); this->imbue(__loc); _M_buf_locale = __loc; return __tmp; } /** * @brief Locale access. * @return The current locale in effect. * * If pubimbue(loc) has been called, then the most recent @c loc * is returned. Otherwise the global locale in effect at the time * of construction is returned. */ locale getloc() const { return _M_buf_locale; } // [27.5.2.2.2] buffer management and positioning //@{ /** * @brief Entry points for derived buffer functions. * * The public versions of @c pubfoo dispatch to the protected * derived @c foo member functions, passing the arguments (if any) * and returning the result unchanged. */ basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) { return this->setbuf(__s, __n); } /** * @brief Alters the stream position. * @param __off Offset. * @param __way Value for ios_base::seekdir. * @param __mode Value for ios_base::openmode. * * Calls virtual seekoff function. */ pos_type pubseekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode = ios_base::in | ios_base::out) { return this->seekoff(__off, __way, __mode); } /** * @brief Alters the stream position. * @param __sp Position * @param __mode Value for ios_base::openmode. * * Calls virtual seekpos function. */ pos_type pubseekpos(pos_type __sp, ios_base::openmode __mode = ios_base::in | ios_base::out) { return this->seekpos(__sp, __mode); } /** * @brief Calls virtual sync function. */ int pubsync() { return this->sync(); } //@} // [27.5.2.2.3] get area /** * @brief Looking ahead into the stream. * @return The number of characters available. * * If a read position is available, returns the number of characters * available for reading before the buffer must be refilled. * Otherwise returns the derived @c showmanyc(). */ streamsize in_avail() { const streamsize __ret = this->egptr() - this->gptr(); return __ret ? __ret : this->showmanyc(); } /** * @brief Getting the next character. * @return The next character, or eof. * * Calls @c sbumpc(), and if that function returns * @c traits::eof(), so does this function. Otherwise, @c sgetc(). */ int_type snextc() { int_type __ret = traits_type::eof(); if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), __ret), true)) __ret = this->sgetc(); return __ret; } /** * @brief Getting the next character. * @return The next character, or eof. * * If the input read position is available, returns that character * and increments the read pointer, otherwise calls and returns * @c uflow(). */ int_type sbumpc() { int_type __ret; if (__builtin_expect(this->gptr() < this->egptr(), true)) { __ret = traits_type::to_int_type(*this->gptr()); this->gbump(1); } else __ret = this->uflow(); return __ret; } /** * @brief Getting the next character. * @return The next character, or eof. * * If the input read position is available, returns that character, * otherwise calls and returns @c underflow(). Does not move the * read position after fetching the character. */ int_type sgetc() { int_type __ret; if (__builtin_expect(this->gptr() < this->egptr(), true)) __ret = traits_type::to_int_type(*this->gptr()); else __ret = this->underflow(); return __ret; } /** * @brief Entry point for xsgetn. * @param __s A buffer area. * @param __n A count. * * Returns xsgetn(__s,__n). The effect is to fill @a __s[0] through * @a __s[__n-1] with characters from the input sequence, if possible. */ streamsize sgetn(char_type* __s, streamsize __n) { return this->xsgetn(__s, __n); } // [27.5.2.2.4] putback /** * @brief Pushing characters back into the input stream. * @param __c The character to push back. * @return The previous character, if possible. * * Similar to sungetc(), but @a __c is pushed onto the stream * instead of the previous character. If successful, * the next character fetched from the input stream will be @a * __c. */ int_type sputbackc(char_type __c) { int_type __ret; const bool __testpos = this->eback() < this->gptr(); if (__builtin_expect(!__testpos || !traits_type::eq(__c, this->gptr()[-1]), false)) __ret = this->pbackfail(traits_type::to_int_type(__c)); else { this->gbump(-1); __ret = traits_type::to_int_type(*this->gptr()); } return __ret; } /** * @brief Moving backwards in the input stream. * @return The previous character, if possible. * * If a putback position is available, this function decrements * the input pointer and returns that character. Otherwise, * calls and returns pbackfail(). The effect is to @a unget * the last character @a gotten. */ int_type sungetc() { int_type __ret; if (__builtin_expect(this->eback() < this->gptr(), true)) { this->gbump(-1); __ret = traits_type::to_int_type(*this->gptr()); } else __ret = this->pbackfail(); return __ret; } // [27.5.2.2.5] put area /** * @brief Entry point for all single-character output functions. * @param __c A character to output. * @return @a __c, if possible. * * One of two public output functions. * * If a write position is available for the output sequence (i.e., * the buffer is not full), stores @a __c in that position, increments * the position, and returns @c traits::to_int_type(__c). If a write * position is not available, returns @c overflow(__c). */ int_type sputc(char_type __c) { int_type __ret; if (__builtin_expect(this->pptr() < this->epptr(), true)) { *this->pptr() = __c; this->pbump(1); __ret = traits_type::to_int_type(__c); } else __ret = this->overflow(traits_type::to_int_type(__c)); return __ret; } /** * @brief Entry point for all single-character output functions. * @param __s A buffer read area. * @param __n A count. * * One of two public output functions. * * * Returns xsputn(__s,__n). The effect is to write @a __s[0] through * @a __s[__n-1] to the output sequence, if possible. */ streamsize sputn(const char_type* __s, streamsize __n) { return this->xsputn(__s, __n); } protected: /** * @brief Base constructor. * * Only called from derived constructors, and sets up all the * buffer data to zero, including the pointers described in the * basic_streambuf class description. Note that, as a result, * - the class starts with no read nor write positions available, * - this is not an error */ basic_streambuf() : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), _M_out_end(0), _M_buf_locale(locale()) { } // [27.5.2.3.1] get area access //@{ /** * @brief Access to the get area. * * These functions are only available to other protected functions, * including derived classes. * * - eback() returns the beginning pointer for the input sequence * - gptr() returns the next pointer for the input sequence * - egptr() returns the end pointer for the input sequence */ char_type* eback() const { return _M_in_beg; } char_type* gptr() const { return _M_in_cur; } char_type* egptr() const { return _M_in_end; } //@} /** * @brief Moving the read position. * @param __n The delta by which to move. * * This just advances the read position without returning any data. */ void gbump(int __n) { _M_in_cur += __n; } /** * @brief Setting the three read area pointers. * @param __gbeg A pointer. * @param __gnext A pointer. * @param __gend A pointer. * @post @a __gbeg == @c eback(), @a __gnext == @c gptr(), and * @a __gend == @c egptr() */ void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) { _M_in_beg = __gbeg; _M_in_cur = __gnext; _M_in_end = __gend; } // [27.5.2.3.2] put area access //@{ /** * @brief Access to the put area. * * These functions are only available to other protected functions, * including derived classes. * * - pbase() returns the beginning pointer for the output sequence * - pptr() returns the next pointer for the output sequence * - epptr() returns the end pointer for the output sequence */ char_type* pbase() const { return _M_out_beg; } char_type* pptr() const { return _M_out_cur; } char_type* epptr() const { return _M_out_end; } //@} /** * @brief Moving the write position. * @param __n The delta by which to move. * * This just advances the write position without returning any data. */ void pbump(int __n) { _M_out_cur += __n; } /** * @brief Setting the three write area pointers. * @param __pbeg A pointer. * @param __pend A pointer. * @post @a __pbeg == @c pbase(), @a __pbeg == @c pptr(), and * @a __pend == @c epptr() */ void setp(char_type* __pbeg, char_type* __pend) { _M_out_beg = _M_out_cur = __pbeg; _M_out_end = __pend; } // [27.5.2.4] virtual functions // [27.5.2.4.1] locales /** * @brief Changes translations. * @param __loc A new locale. * * Translations done during I/O which depend on the current * locale are changed by this call. The standard adds, * Between invocations of this function a class derived * from streambuf can safely cache results of calls to locale * functions and to members of facets so obtained. * * @note Base class version does nothing. */ virtual void imbue(const locale& __loc _IsUnused) { } // [27.5.2.4.2] buffer management and positioning /** * @brief Manipulates the buffer. * * Each derived class provides its own appropriate behavior. See * the next-to-last paragraph of * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more on this function. * * @note Base class version does nothing, returns @c this. */ virtual basic_streambuf* setbuf(char_type*, streamsize) { return this; } /** * @brief Alters the stream positions. * * Each derived class provides its own appropriate behavior. * @note Base class version does nothing, returns a @c pos_type * that represents an invalid stream position. */ virtual pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) { return pos_type(off_type(-1)); } /** * @brief Alters the stream positions. * * Each derived class provides its own appropriate behavior. * @note Base class version does nothing, returns a @c pos_type * that represents an invalid stream position. */ virtual pos_type seekpos(pos_type, ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) { return pos_type(off_type(-1)); } /** * @brief Synchronizes the buffer arrays with the controlled sequences. * @return -1 on failure. * * Each derived class provides its own appropriate behavior, * including the definition of @a failure. * @note Base class version does nothing, returns zero. */ virtual int sync() { return 0; } // [27.5.2.4.3] get area /** * @brief Investigating the data available. * @return An estimate of the number of characters available in the * input sequence, or -1. * * If it returns a positive value, then successive calls to * @c underflow() will not return @c traits::eof() until at * least that number of characters have been supplied. If @c * showmanyc() returns -1, then calls to @c underflow() or @c * uflow() will fail. [27.5.2.4.3]/1 * * @note Base class version does nothing, returns zero. * @note The standard adds that the intention is not only that the * calls [to underflow or uflow] will not return @c eof() but * that they will return immediately. * @note The standard adds that the morphemes of @c showmanyc are * @b es-how-many-see, not @b show-manic. */ virtual streamsize showmanyc() { return 0; } /** * @brief Multiple character extraction. * @param __s A buffer area. * @param __n Maximum number of characters to assign. * @return The number of characters assigned. * * Fills @a __s[0] through @a __s[__n-1] with characters from the input * sequence, as if by @c sbumpc(). Stops when either @a __n characters * have been copied, or when @c traits::eof() would be copied. * * It is expected that derived classes provide a more efficient * implementation by overriding this definition. */ virtual streamsize xsgetn(char_type* __s, streamsize __n); /** * @brief Fetches more data from the controlled sequence. * @return The first character from the pending sequence. * * Informally, this function is called when the input buffer is * exhausted (or does not exist, as buffering need not actually be * done). If a buffer exists, it is @a refilled. In either case, the * next available character is returned, or @c traits::eof() to * indicate a null pending sequence. * * For a formal definition of the pending sequence, see a good text * such as Langer & Kreft, or [27.5.2.4.3]/7-14. * * A functioning input streambuf can be created by overriding only * this function (no buffer area will be used). For an example, see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html * * @note Base class version does nothing, returns eof(). */ virtual int_type underflow() { return traits_type::eof(); } /** * @brief Fetches more data from the controlled sequence. * @return The first character from the pending sequence. * * Informally, this function does the same thing as @c underflow(), * and in fact is required to call that function. It also returns * the new character, like @c underflow() does. However, this * function also moves the read position forward by one. */ virtual int_type uflow() { int_type __ret = traits_type::eof(); const bool __testeof = traits_type::eq_int_type(this->underflow(), __ret); if (!__testeof) { __ret = traits_type::to_int_type(*this->gptr()); this->gbump(1); } return __ret; } // [27.5.2.4.4] putback /** * @brief Tries to back up the input sequence. * @param __c The character to be inserted back into the sequence. * @return eof() on failure, some other value on success * @post The constraints of @c gptr(), @c eback(), and @c pptr() * are the same as for @c underflow(). * * @note Base class version does nothing, returns eof(). */ virtual int_type pbackfail(int_type __c _IsUnused = traits_type::eof()) { return traits_type::eof(); } // Put area: /** * @brief Multiple character insertion. * @param __s A buffer area. * @param __n Maximum number of characters to write. * @return The number of characters written. * * Writes @a __s[0] through @a __s[__n-1] to the output sequence, as if * by @c sputc(). Stops when either @a n characters have been * copied, or when @c sputc() would return @c traits::eof(). * * It is expected that derived classes provide a more efficient * implementation by overriding this definition. */ virtual streamsize xsputn(const char_type* __s, streamsize __n); /** * @brief Consumes data from the buffer; writes to the * controlled sequence. * @param __c An additional character to consume. * @return eof() to indicate failure, something else (usually * @a __c, or not_eof()) * * Informally, this function is called when the output buffer * is full (or does not exist, as buffering need not actually * be done). If a buffer exists, it is @a consumed, with * some effect on the controlled sequence. * (Typically, the buffer is written out to the sequence * verbatim.) In either case, the character @a c is also * written out, if @a __c is not @c eof(). * * For a formal definition of this function, see a good text * such as Langer & Kreft, or [27.5.2.4.5]/3-7. * * A functioning output streambuf can be created by overriding only * this function (no buffer area will be used). * * @note Base class version does nothing, returns eof(). */ virtual int_type overflow(int_type __c _IsUnused = traits_type::eof()) { return traits_type::eof(); } #if _GLIBCXX_USE_DEPRECATED && __cplusplus <= 201402L // Annex D.6 (removed in C++17) public: /** * @brief Tosses a character. * * Advances the read pointer, ignoring the character that would have * been read. * * See http://gcc.gnu.org/ml/libstdc++/2002-05/msg00168.html */ #if __cplusplus >= 201103L [[__deprecated__("stossc is deprecated, use sbumpc instead")]] #endif void stossc() { if (this->gptr() < this->egptr()) this->gbump(1); else this->uflow(); } #endif // Also used by specializations for char and wchar_t in src. void __safe_gbump(streamsize __n) { _M_in_cur += __n; } void __safe_pbump(streamsize __n) { _M_out_cur += __n; } #if __cplusplus < 201103L private: #else protected: #endif basic_streambuf(const basic_streambuf&); basic_streambuf& operator=(const basic_streambuf&); #if __cplusplus >= 201103L void swap(basic_streambuf& __sb) { std::swap(_M_in_beg, __sb._M_in_beg); std::swap(_M_in_cur, __sb._M_in_cur); std::swap(_M_in_end, __sb._M_in_end); std::swap(_M_out_beg, __sb._M_out_beg); std::swap(_M_out_cur, __sb._M_out_cur); std::swap(_M_out_end, __sb._M_out_end); std::swap(_M_buf_locale, __sb._M_buf_locale); } #endif }; #if __cplusplus >= 201103L template std::basic_streambuf<_CharT, _Traits>:: basic_streambuf(const basic_streambuf&) = default; template std::basic_streambuf<_CharT, _Traits>& std::basic_streambuf<_CharT, _Traits>:: operator=(const basic_streambuf&) = default; #endif // Explicit specialization declarations, defined in src/streambuf.cc. template<> streamsize __copy_streambufs_eof(basic_streambuf* __sbin, basic_streambuf* __sbout, bool& __ineof); #ifdef _GLIBCXX_USE_WCHAR_T template<> streamsize __copy_streambufs_eof(basic_streambuf* __sbin, basic_streambuf* __sbout, bool& __ineof); #endif #undef _IsUnused _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_STREAMBUF */ PKgd1]uPP 8/ctgmathnu[// -*- C++ -*- // Copyright (C) 2007-2018 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/ctgmath * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CTGMATH #define _GLIBCXX_CTGMATH 1 #if __cplusplus < 201103L # include #else # include extern "C++" { # include } #endif #endif PKgd1] 8/futurenu[// -*- C++ -*- // Copyright (C) 2009-2018 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/future * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FUTURE #define _GLIBCXX_FUTURE 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup futures Futures * @ingroup concurrency * * Classes for futures support. * @{ */ /// Error code for futures enum class future_errc { future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise }; /// Specialization. template<> struct is_error_code_enum : public true_type { }; /// Points to a statically-allocated object derived from error_category. const error_category& future_category() noexcept; /// Overload for make_error_code. inline error_code make_error_code(future_errc __errc) noexcept { return error_code(static_cast(__errc), future_category()); } /// Overload for make_error_condition. inline error_condition make_error_condition(future_errc __errc) noexcept { return error_condition(static_cast(__errc), future_category()); } /** * @brief Exception type thrown by futures. * @ingroup exceptions */ class future_error : public logic_error { public: explicit future_error(future_errc __errc) : future_error(std::make_error_code(__errc)) { } virtual ~future_error() noexcept; virtual const char* what() const noexcept; const error_code& code() const noexcept { return _M_code; } private: explicit future_error(error_code __ec) : logic_error("std::future_error: " + __ec.message()), _M_code(__ec) { } friend void __throw_future_error(int); error_code _M_code; }; // Forward declarations. template class future; template class shared_future; template class packaged_task; template class promise; /// Launch code for futures enum class launch { async = 1, deferred = 2 }; constexpr launch operator&(launch __x, launch __y) { return static_cast( static_cast(__x) & static_cast(__y)); } constexpr launch operator|(launch __x, launch __y) { return static_cast( static_cast(__x) | static_cast(__y)); } constexpr launch operator^(launch __x, launch __y) { return static_cast( static_cast(__x) ^ static_cast(__y)); } constexpr launch operator~(launch __x) { return static_cast(~static_cast(__x)); } inline launch& operator&=(launch& __x, launch __y) { return __x = __x & __y; } inline launch& operator|=(launch& __x, launch __y) { return __x = __x | __y; } inline launch& operator^=(launch& __x, launch __y) { return __x = __x ^ __y; } /// Status code for futures enum class future_status { ready, timeout, deferred }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2021. Further incorrect usages of result_of template using __async_result_of = typename result_of< typename decay<_Fn>::type(typename decay<_Args>::type...)>::type; template future<__async_result_of<_Fn, _Args...>> async(launch __policy, _Fn&& __fn, _Args&&... __args); template future<__async_result_of<_Fn, _Args...>> async(_Fn&& __fn, _Args&&... __args); #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) /// Base class and enclosing scope. struct __future_base { /// Base class for results. struct _Result_base { exception_ptr _M_error; _Result_base(const _Result_base&) = delete; _Result_base& operator=(const _Result_base&) = delete; // _M_destroy() allows derived classes to control deallocation virtual void _M_destroy() = 0; struct _Deleter { void operator()(_Result_base* __fr) const { __fr->_M_destroy(); } }; protected: _Result_base(); virtual ~_Result_base(); }; /// A unique_ptr for result objects. template using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>; /// A result object that has storage for an object of type _Res. template struct _Result : _Result_base { private: __gnu_cxx::__aligned_buffer<_Res> _M_storage; bool _M_initialized; public: typedef _Res result_type; _Result() noexcept : _M_initialized() { } ~_Result() { if (_M_initialized) _M_value().~_Res(); } // Return lvalue, future will add const or rvalue-reference _Res& _M_value() noexcept { return *_M_storage._M_ptr(); } void _M_set(const _Res& __res) { ::new (_M_storage._M_addr()) _Res(__res); _M_initialized = true; } void _M_set(_Res&& __res) { ::new (_M_storage._M_addr()) _Res(std::move(__res)); _M_initialized = true; } private: void _M_destroy() { delete this; } }; /// A result object that uses an allocator. template struct _Result_alloc final : _Result<_Res>, _Alloc { using __allocator_type = __alloc_rebind<_Alloc, _Result_alloc>; explicit _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a) { } private: void _M_destroy() { __allocator_type __a(*this); __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; this->~_Result_alloc(); } }; // Create a result object that uses an allocator. template static _Ptr<_Result_alloc<_Res, _Allocator>> _S_allocate_result(const _Allocator& __a) { using __result_type = _Result_alloc<_Res, _Allocator>; typename __result_type::__allocator_type __a2(__a); auto __guard = std::__allocate_guarded(__a2); __result_type* __p = ::new((void*)__guard.get()) __result_type{__a}; __guard = nullptr; return _Ptr<__result_type>(__p); } // Keep it simple for std::allocator. template static _Ptr<_Result<_Res>> _S_allocate_result(const std::allocator<_Tp>& __a) { return _Ptr<_Result<_Res>>(new _Result<_Res>); } // Base class for various types of shared state created by an // asynchronous provider (such as a std::promise) and shared with one // or more associated futures. class _State_baseV2 { typedef _Ptr<_Result_base> _Ptr_type; enum _Status : unsigned { __not_ready, __ready }; _Ptr_type _M_result; __atomic_futex_unsigned<> _M_status; atomic_flag _M_retrieved = ATOMIC_FLAG_INIT; once_flag _M_once; public: _State_baseV2() noexcept : _M_result(), _M_status(_Status::__not_ready) { } _State_baseV2(const _State_baseV2&) = delete; _State_baseV2& operator=(const _State_baseV2&) = delete; virtual ~_State_baseV2() = default; _Result_base& wait() { // Run any deferred function or join any asynchronous thread: _M_complete_async(); // Acquire MO makes sure this synchronizes with the thread that made // the future ready. _M_status._M_load_when_equal(_Status::__ready, memory_order_acquire); return *_M_result; } template future_status wait_for(const chrono::duration<_Rep, _Period>& __rel) { // First, check if the future has been made ready. Use acquire MO // to synchronize with the thread that made it ready. if (_M_status._M_load(memory_order_acquire) == _Status::__ready) return future_status::ready; if (_M_is_deferred_future()) return future_status::deferred; if (_M_status._M_load_when_equal_for(_Status::__ready, memory_order_acquire, __rel)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2100. timed waiting functions must also join // This call is a no-op by default except on an async future, // in which case the async thread is joined. It's also not a // no-op for a deferred future, but such a future will never // reach this point because it returns future_status::deferred // instead of waiting for the future to become ready (see // above). Async futures synchronize in this call, so we need // no further synchronization here. _M_complete_async(); return future_status::ready; } return future_status::timeout; } template future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs) { // First, check if the future has been made ready. Use acquire MO // to synchronize with the thread that made it ready. if (_M_status._M_load(memory_order_acquire) == _Status::__ready) return future_status::ready; if (_M_is_deferred_future()) return future_status::deferred; if (_M_status._M_load_when_equal_until(_Status::__ready, memory_order_acquire, __abs)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2100. timed waiting functions must also join // See wait_for(...) above. _M_complete_async(); return future_status::ready; } return future_status::timeout; } // Provide a result to the shared state and make it ready. // Calls at most once: _M_result = __res(); void _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) { bool __did_set = false; // all calls to this function are serialized, // side-effects of invoking __res only happen once call_once(_M_once, &_State_baseV2::_M_do_set, this, std::__addressof(__res), std::__addressof(__did_set)); if (__did_set) // Use release MO to synchronize with observers of the ready state. _M_status._M_store_notify_all(_Status::__ready, memory_order_release); else if (!__ignore_failure) __throw_future_error(int(future_errc::promise_already_satisfied)); } // Provide a result to the shared state but delay making it ready // until the calling thread exits. // Calls at most once: _M_result = __res(); void _M_set_delayed_result(function<_Ptr_type()> __res, weak_ptr<_State_baseV2> __self) { bool __did_set = false; unique_ptr<_Make_ready> __mr{new _Make_ready}; // all calls to this function are serialized, // side-effects of invoking __res only happen once call_once(_M_once, &_State_baseV2::_M_do_set, this, std::__addressof(__res), std::__addressof(__did_set)); if (!__did_set) __throw_future_error(int(future_errc::promise_already_satisfied)); __mr->_M_shared_state = std::move(__self); __mr->_M_set(); __mr.release(); } // Abandon this shared state. void _M_break_promise(_Ptr_type __res) { if (static_cast(__res)) { __res->_M_error = make_exception_ptr(future_error(future_errc::broken_promise)); // This function is only called when the last asynchronous result // provider is abandoning this shared state, so noone can be // trying to make the shared state ready at the same time, and // we can access _M_result directly instead of through call_once. _M_result.swap(__res); // Use release MO to synchronize with observers of the ready state. _M_status._M_store_notify_all(_Status::__ready, memory_order_release); } } // Called when this object is first passed to a future. void _M_set_retrieved_flag() { if (_M_retrieved.test_and_set()) __throw_future_error(int(future_errc::future_already_retrieved)); } template struct _Setter; // set lvalues template struct _Setter<_Res, _Arg&> { // check this is only used by promise::set_value(const R&) // or promise::set_value(R&) static_assert(is_same<_Res, _Arg&>::value // promise || is_same::value, // promise "Invalid specialisation"); // Used by std::promise to copy construct the result. typename promise<_Res>::_Ptr_type operator()() const { _M_promise->_M_storage->_M_set(*_M_arg); return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; _Arg* _M_arg; }; // set rvalues template struct _Setter<_Res, _Res&&> { // Used by std::promise to move construct the result. typename promise<_Res>::_Ptr_type operator()() const { _M_promise->_M_storage->_M_set(std::move(*_M_arg)); return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; _Res* _M_arg; }; // set void template struct _Setter<_Res, void> { static_assert(is_void<_Res>::value, "Only used for promise"); typename promise<_Res>::_Ptr_type operator()() const { return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; }; struct __exception_ptr_tag { }; // set exceptions template struct _Setter<_Res, __exception_ptr_tag> { // Used by std::promise to store an exception as the result. typename promise<_Res>::_Ptr_type operator()() const { _M_promise->_M_storage->_M_error = *_M_ex; return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; exception_ptr* _M_ex; }; template static _Setter<_Res, _Arg&&> __setter(promise<_Res>* __prom, _Arg&& __arg) { _S_check(__prom->_M_future); return _Setter<_Res, _Arg&&>{ __prom, std::__addressof(__arg) }; } template static _Setter<_Res, __exception_ptr_tag> __setter(exception_ptr& __ex, promise<_Res>* __prom) { _S_check(__prom->_M_future); return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex }; } template static _Setter<_Res, void> __setter(promise<_Res>* __prom) { _S_check(__prom->_M_future); return _Setter<_Res, void>{ __prom }; } template static void _S_check(const shared_ptr<_Tp>& __p) { if (!static_cast(__p)) __throw_future_error((int)future_errc::no_state); } private: // The function invoked with std::call_once(_M_once, ...). void _M_do_set(function<_Ptr_type()>* __f, bool* __did_set) { _Ptr_type __res = (*__f)(); // Notify the caller that we did try to set; if we do not throw an // exception, the caller will be aware that it did set (e.g., see // _M_set_result). *__did_set = true; _M_result.swap(__res); // nothrow } // Wait for completion of async function. virtual void _M_complete_async() { } // Return true if state corresponds to a deferred function. virtual bool _M_is_deferred_future() const { return false; } struct _Make_ready final : __at_thread_exit_elt { weak_ptr<_State_baseV2> _M_shared_state; static void _S_run(void*); void _M_set(); }; }; #ifdef _GLIBCXX_ASYNC_ABI_COMPAT class _State_base; class _Async_state_common; #else using _State_base = _State_baseV2; class _Async_state_commonV2; #endif template()())> class _Deferred_state; template()())> class _Async_state_impl; template class _Task_state_base; template class _Task_state; template static std::shared_ptr<_State_base> _S_make_deferred_state(_BoundFn&& __fn); template static std::shared_ptr<_State_base> _S_make_async_state(_BoundFn&& __fn); template struct _Task_setter; template static _Task_setter<_Res_ptr, _BoundFn> _S_task_setter(_Res_ptr& __ptr, _BoundFn& __call) { return { std::__addressof(__ptr), std::__addressof(__call) }; } }; /// Partial specialization for reference types. template struct __future_base::_Result<_Res&> : __future_base::_Result_base { typedef _Res& result_type; _Result() noexcept : _M_value_ptr() { } void _M_set(_Res& __res) noexcept { _M_value_ptr = std::addressof(__res); } _Res& _M_get() noexcept { return *_M_value_ptr; } private: _Res* _M_value_ptr; void _M_destroy() { delete this; } }; /// Explicit specialization for void. template<> struct __future_base::_Result : __future_base::_Result_base { typedef void result_type; private: void _M_destroy() { delete this; } }; #ifndef _GLIBCXX_ASYNC_ABI_COMPAT // Allow _Setter objects to be stored locally in std::function template struct __is_location_invariant <__future_base::_State_base::_Setter<_Res, _Arg>> : true_type { }; // Allow _Task_setter objects to be stored locally in std::function template struct __is_location_invariant <__future_base::_Task_setter<_Res_ptr, _Fn, _Res>> : true_type { }; /// Common implementation for future and shared_future. template class __basic_future : public __future_base { protected: typedef shared_ptr<_State_base> __state_type; typedef __future_base::_Result<_Res>& __result_type; private: __state_type _M_state; public: // Disable copying. __basic_future(const __basic_future&) = delete; __basic_future& operator=(const __basic_future&) = delete; bool valid() const noexcept { return static_cast(_M_state); } void wait() const { _State_base::_S_check(_M_state); _M_state->wait(); } template future_status wait_for(const chrono::duration<_Rep, _Period>& __rel) const { _State_base::_S_check(_M_state); return _M_state->wait_for(__rel); } template future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const { _State_base::_S_check(_M_state); return _M_state->wait_until(__abs); } protected: /// Wait for the state to be ready and rethrow any stored exception __result_type _M_get_result() const { _State_base::_S_check(_M_state); _Result_base& __res = _M_state->wait(); if (!(__res._M_error == 0)) rethrow_exception(__res._M_error); return static_cast<__result_type>(__res); } void _M_swap(__basic_future& __that) noexcept { _M_state.swap(__that._M_state); } // Construction of a future by promise::get_future() explicit __basic_future(const __state_type& __state) : _M_state(__state) { _State_base::_S_check(_M_state); _M_state->_M_set_retrieved_flag(); } // Copy construction from a shared_future explicit __basic_future(const shared_future<_Res>&) noexcept; // Move construction from a shared_future explicit __basic_future(shared_future<_Res>&&) noexcept; // Move construction from a future explicit __basic_future(future<_Res>&&) noexcept; constexpr __basic_future() noexcept : _M_state() { } struct _Reset { explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { } ~_Reset() { _M_fut._M_state.reset(); } __basic_future& _M_fut; }; }; /// Primary template for future. template class future : public __basic_future<_Res> { friend class promise<_Res>; template friend class packaged_task; template friend future<__async_result_of<_Fn, _Args...>> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: constexpr future() noexcept : _Base_type() { } /// Move constructor future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res get() { typename _Base_type::_Reset __reset(*this); return std::move(this->_M_get_result()._M_value()); } shared_future<_Res> share() noexcept; }; /// Partial specialization for future template class future<_Res&> : public __basic_future<_Res&> { friend class promise<_Res&>; template friend class packaged_task; template friend future<__async_result_of<_Fn, _Args...>> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res&> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: constexpr future() noexcept : _Base_type() { } /// Move constructor future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() { typename _Base_type::_Reset __reset(*this); return this->_M_get_result()._M_get(); } shared_future<_Res&> share() noexcept; }; /// Explicit specialization for future template<> class future : public __basic_future { friend class promise; template friend class packaged_task; template friend future<__async_result_of<_Fn, _Args...>> async(launch, _Fn&&, _Args&&...); typedef __basic_future _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: constexpr future() noexcept : _Base_type() { } /// Move constructor future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value void get() { typename _Base_type::_Reset __reset(*this); this->_M_get_result(); } shared_future share() noexcept; }; /// Primary template for shared_future. template class shared_future : public __basic_future<_Res> { typedef __basic_future<_Res> _Base_type; public: constexpr shared_future() noexcept : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) noexcept : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future<_Res>&& __uf) noexcept : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) noexcept : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) noexcept { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) noexcept { shared_future(std::move(__sf))._M_swap(*this); return *this; } /// Retrieving the value const _Res& get() const { return this->_M_get_result()._M_value(); } }; /// Partial specialization for shared_future template class shared_future<_Res&> : public __basic_future<_Res&> { typedef __basic_future<_Res&> _Base_type; public: constexpr shared_future() noexcept : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future<_Res&>&& __uf) noexcept : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) noexcept : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) noexcept { shared_future(std::move(__sf))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() const { return this->_M_get_result()._M_get(); } }; /// Explicit specialization for shared_future template<> class shared_future : public __basic_future { typedef __basic_future _Base_type; public: constexpr shared_future() noexcept : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) noexcept : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) noexcept { shared_future(std::move(__sf))._M_swap(*this); return *this; } // Retrieving the value void get() const { this->_M_get_result(); } }; // Now we can define the protected __basic_future constructors. template inline __basic_future<_Res>:: __basic_future(const shared_future<_Res>& __sf) noexcept : _M_state(__sf._M_state) { } template inline __basic_future<_Res>:: __basic_future(shared_future<_Res>&& __sf) noexcept : _M_state(std::move(__sf._M_state)) { } template inline __basic_future<_Res>:: __basic_future(future<_Res>&& __uf) noexcept : _M_state(std::move(__uf._M_state)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2556. Wide contract for future::share() template inline shared_future<_Res> future<_Res>::share() noexcept { return shared_future<_Res>(std::move(*this)); } template inline shared_future<_Res&> future<_Res&>::share() noexcept { return shared_future<_Res&>(std::move(*this)); } inline shared_future future::share() noexcept { return shared_future(std::move(*this)); } /// Primary template for promise template class promise { typedef __future_base::_State_base _State; typedef __future_base::_Result<_Res> _Res_type; typedef __future_base::_Ptr<_Res_type> _Ptr_type; template friend class _State::_Setter; friend _State; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) noexcept : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result<_Res>(__a)) { } template promise(allocator_arg_t, const _Allocator&, promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) noexcept { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) noexcept { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future<_Res> get_future() { return future<_Res>(_M_future); } // Setting the result void set_value(const _Res& __r) { _M_future->_M_set_result(_State::__setter(this, __r)); } void set_value(_Res&& __r) { _M_future->_M_set_result(_State::__setter(this, std::move(__r))); } void set_exception(exception_ptr __p) { _M_future->_M_set_result(_State::__setter(__p, this)); } void set_value_at_thread_exit(const _Res& __r) { _M_future->_M_set_delayed_result(_State::__setter(this, __r), _M_future); } void set_value_at_thread_exit(_Res&& __r) { _M_future->_M_set_delayed_result( _State::__setter(this, std::move(__r)), _M_future); } void set_exception_at_thread_exit(exception_ptr __p) { _M_future->_M_set_delayed_result(_State::__setter(__p, this), _M_future); } }; template inline void swap(promise<_Res>& __x, promise<_Res>& __y) noexcept { __x.swap(__y); } template struct uses_allocator, _Alloc> : public true_type { }; /// Partial specialization for promise template class promise<_Res&> { typedef __future_base::_State_base _State; typedef __future_base::_Result<_Res&> _Res_type; typedef __future_base::_Ptr<_Res_type> _Ptr_type; template friend class _State::_Setter; friend _State; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) noexcept : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result<_Res&>(__a)) { } template promise(allocator_arg_t, const _Allocator&, promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) noexcept { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) noexcept { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future<_Res&> get_future() { return future<_Res&>(_M_future); } // Setting the result void set_value(_Res& __r) { _M_future->_M_set_result(_State::__setter(this, __r)); } void set_exception(exception_ptr __p) { _M_future->_M_set_result(_State::__setter(__p, this)); } void set_value_at_thread_exit(_Res& __r) { _M_future->_M_set_delayed_result(_State::__setter(this, __r), _M_future); } void set_exception_at_thread_exit(exception_ptr __p) { _M_future->_M_set_delayed_result(_State::__setter(__p, this), _M_future); } }; /// Explicit specialization for promise template<> class promise { typedef __future_base::_State_base _State; typedef __future_base::_Result _Res_type; typedef __future_base::_Ptr<_Res_type> _Ptr_type; template friend class _State::_Setter; friend _State; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) noexcept : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result(__a)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2095. missing constructors needed for uses-allocator construction template promise(allocator_arg_t, const _Allocator&, promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) noexcept { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) noexcept { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future get_future() { return future(_M_future); } // Setting the result void set_value() { _M_future->_M_set_result(_State::__setter(this)); } void set_exception(exception_ptr __p) { _M_future->_M_set_result(_State::__setter(__p, this)); } void set_value_at_thread_exit() { _M_future->_M_set_delayed_result(_State::__setter(this), _M_future); } void set_exception_at_thread_exit(exception_ptr __p) { _M_future->_M_set_delayed_result(_State::__setter(__p, this), _M_future); } }; template struct __future_base::_Task_setter { // Invoke the function and provide the result to the caller. _Ptr_type operator()() const { __try { (*_M_result)->_M_set((*_M_fn)()); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; // will cause broken_promise } __catch(...) { (*_M_result)->_M_error = current_exception(); } return std::move(*_M_result); } _Ptr_type* _M_result; _Fn* _M_fn; }; template struct __future_base::_Task_setter<_Ptr_type, _Fn, void> { _Ptr_type operator()() const { __try { (*_M_fn)(); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; // will cause broken_promise } __catch(...) { (*_M_result)->_M_error = current_exception(); } return std::move(*_M_result); } _Ptr_type* _M_result; _Fn* _M_fn; }; // Holds storage for a packaged_task's result. template struct __future_base::_Task_state_base<_Res(_Args...)> : __future_base::_State_base { typedef _Res _Res_type; template _Task_state_base(const _Alloc& __a) : _M_result(_S_allocate_result<_Res>(__a)) { } // Invoke the stored task and make the state ready. virtual void _M_run(_Args&&... __args) = 0; // Invoke the stored task and make the state ready at thread exit. virtual void _M_run_delayed(_Args&&... __args, weak_ptr<_State_base>) = 0; virtual shared_ptr<_Task_state_base> _M_reset() = 0; typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; _Ptr_type _M_result; }; // Holds a packaged_task's stored task. template struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final : __future_base::_Task_state_base<_Res(_Args...)> { template _Task_state(_Fn2&& __fn, const _Alloc& __a) : _Task_state_base<_Res(_Args...)>(__a), _M_impl(std::forward<_Fn2>(__fn), __a) { } private: virtual void _M_run(_Args&&... __args) { auto __boundfn = [&] () -> typename result_of<_Fn&(_Args&&...)>::type { return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...); }; this->_M_set_result(_S_task_setter(this->_M_result, __boundfn)); } virtual void _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self) { auto __boundfn = [&] () -> typename result_of<_Fn&(_Args&&...)>::type { return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...); }; this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn), std::move(__self)); } virtual shared_ptr<_Task_state_base<_Res(_Args...)>> _M_reset(); struct _Impl : _Alloc { template _Impl(_Fn2&& __fn, const _Alloc& __a) : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { } _Fn _M_fn; } _M_impl; }; template static shared_ptr<__future_base::_Task_state_base<_Signature>> __create_task_state(_Fn&& __fn, const _Alloc& __a) { typedef typename decay<_Fn>::type _Fn2; typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State; return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a); } template shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>> __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset() { return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn), static_cast<_Alloc&>(_M_impl)); } template::type>::value> struct __constrain_pkgdtask { typedef void __type; }; template struct __constrain_pkgdtask<_Task, _Fn, true> { }; /// packaged_task template class packaged_task<_Res(_ArgTypes...)> { typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; shared_ptr<_State_type> _M_state; public: // Construction and destruction packaged_task() noexcept { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2095. missing constructors needed for uses-allocator construction template packaged_task(allocator_arg_t, const _Allocator& __a) noexcept { } template::__type> explicit packaged_task(_Fn&& __fn) : packaged_task(allocator_arg, std::allocator(), std::forward<_Fn>(__fn)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained // 2407. [this constructor should not be] explicit template::__type> packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) : _M_state(__create_task_state<_Res(_ArgTypes...)>( std::forward<_Fn>(__fn), __a)) { } ~packaged_task() { if (static_cast(_M_state) && !_M_state.unique()) _M_state->_M_break_promise(std::move(_M_state->_M_result)); } // No copy packaged_task(const packaged_task&) = delete; packaged_task& operator=(const packaged_task&) = delete; template packaged_task(allocator_arg_t, const _Allocator&, const packaged_task&) = delete; // Move support packaged_task(packaged_task&& __other) noexcept { this->swap(__other); } template packaged_task(allocator_arg_t, const _Allocator&, packaged_task&& __other) noexcept { this->swap(__other); } packaged_task& operator=(packaged_task&& __other) noexcept { packaged_task(std::move(__other)).swap(*this); return *this; } void swap(packaged_task& __other) noexcept { _M_state.swap(__other._M_state); } bool valid() const noexcept { return static_cast(_M_state); } // Result retrieval future<_Res> get_future() { return future<_Res>(_M_state); } // Execution void operator()(_ArgTypes... __args) { __future_base::_State_base::_S_check(_M_state); _M_state->_M_run(std::forward<_ArgTypes>(__args)...); } void make_ready_at_thread_exit(_ArgTypes... __args) { __future_base::_State_base::_S_check(_M_state); _M_state->_M_run_delayed(std::forward<_ArgTypes>(__args)..., _M_state); } void reset() { __future_base::_State_base::_S_check(_M_state); packaged_task __tmp; __tmp._M_state = _M_state; _M_state = _M_state->_M_reset(); } }; /// swap template inline void swap(packaged_task<_Res(_ArgTypes...)>& __x, packaged_task<_Res(_ArgTypes...)>& __y) noexcept { __x.swap(__y); } template struct uses_allocator, _Alloc> : public true_type { }; // Shared state created by std::async(). // Holds a deferred function and storage for its result. template class __future_base::_Deferred_state final : public __future_base::_State_base { public: explicit _Deferred_state(_BoundFn&& __fn) : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) { } private: typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; _Ptr_type _M_result; _BoundFn _M_fn; // Run the deferred function. virtual void _M_complete_async() { // Multiple threads can call a waiting function on the future and // reach this point at the same time. The call_once in _M_set_result // ensures only the first one run the deferred function, stores the // result in _M_result, swaps that with the base _M_result and makes // the state ready. Tell _M_set_result to ignore failure so all later // calls do nothing. _M_set_result(_S_task_setter(_M_result, _M_fn), true); } // Caller should check whether the state is ready first, because this // function will return true even after the deferred function has run. virtual bool _M_is_deferred_future() const { return true; } }; // Common functionality hoisted out of the _Async_state_impl template. class __future_base::_Async_state_commonV2 : public __future_base::_State_base { protected: ~_Async_state_commonV2() = default; // Make waiting functions block until the thread completes, as if joined. // // This function is used by wait() to satisfy the first requirement below // and by wait_for() / wait_until() to satisfy the second. // // [futures.async]: // // — a call to a waiting function on an asynchronous return object that // shares the shared state created by this async call shall block until // the associated thread has completed, as if joined, or else time out. // // — the associated thread completion synchronizes with the return from // the first function that successfully detects the ready status of the // shared state or with the return from the last function that releases // the shared state, whichever happens first. virtual void _M_complete_async() { _M_join(); } void _M_join() { std::call_once(_M_once, &thread::join, &_M_thread); } thread _M_thread; once_flag _M_once; }; // Shared state created by std::async(). // Starts a new thread that runs a function and makes the shared state ready. template class __future_base::_Async_state_impl final : public __future_base::_Async_state_commonV2 { public: explicit _Async_state_impl(_BoundFn&& __fn) : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) { _M_thread = std::thread{ [this] { __try { _M_set_result(_S_task_setter(_M_result, _M_fn)); } __catch (const __cxxabiv1::__forced_unwind&) { // make the shared state ready on thread cancellation if (static_cast(_M_result)) this->_M_break_promise(std::move(_M_result)); __throw_exception_again; } } }; } // Must not destroy _M_result and _M_fn until the thread finishes. // Call join() directly rather than through _M_join() because no other // thread can be referring to this state if it is being destroyed. ~_Async_state_impl() { if (_M_thread.joinable()) _M_thread.join(); } private: typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; _Ptr_type _M_result; _BoundFn _M_fn; }; template inline std::shared_ptr<__future_base::_State_base> __future_base::_S_make_deferred_state(_BoundFn&& __fn) { typedef typename remove_reference<_BoundFn>::type __fn_type; typedef _Deferred_state<__fn_type> __state_type; return std::make_shared<__state_type>(std::move(__fn)); } template inline std::shared_ptr<__future_base::_State_base> __future_base::_S_make_async_state(_BoundFn&& __fn) { typedef typename remove_reference<_BoundFn>::type __fn_type; typedef _Async_state_impl<__fn_type> __state_type; return std::make_shared<__state_type>(std::move(__fn)); } /// async template future<__async_result_of<_Fn, _Args...>> async(launch __policy, _Fn&& __fn, _Args&&... __args) { std::shared_ptr<__future_base::_State_base> __state; if ((__policy & launch::async) == launch::async) { __try { __state = __future_base::_S_make_async_state( std::thread::__make_invoker(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...) ); } #if __cpp_exceptions catch(const system_error& __e) { if (__e.code() != errc::resource_unavailable_try_again || (__policy & launch::deferred) != launch::deferred) throw; } #endif } if (!__state) { __state = __future_base::_S_make_deferred_state( std::thread::__make_invoker(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); } return future<__async_result_of<_Fn, _Args...>>(__state); } /// async, potential overload template inline future<__async_result_of<_Fn, _Args...>> async(_Fn&& __fn, _Args&&... __args) { return std::async(launch::async|launch::deferred, std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); } #endif // _GLIBCXX_ASYNC_ABI_COMPAT #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 // @} group futures _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_FUTURE PKgd1]KK 8/istreamnu[// Input streams -*- C++ -*- // Copyright (C) 1997-2018 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 // . // // ISO C++ 14882: 27.6.1 Input streams // /** @file include/istream * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ISTREAM #define _GLIBCXX_ISTREAM 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Template class basic_istream. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This is the base class for all input streams. It provides text * formatting of all builtin types, and communicates with any class * derived from basic_streambuf to do the actual input. */ template class basic_istream : virtual public basic_ios<_CharT, _Traits> { public: // Types (inherited from basic_ios (27.4.4)): typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; // Non-standard Types: typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_ios<_CharT, _Traits> __ios_type; typedef basic_istream<_CharT, _Traits> __istream_type; typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > __num_get_type; typedef ctype<_CharT> __ctype_type; protected: // Data Members: /** * The number of characters extracted in the previous unformatted * function; see gcount(). */ streamsize _M_gcount; public: /** * @brief Base constructor. * * This ctor is almost never called by the user directly, rather from * derived classes' initialization lists, which pass a pointer to * their own stream buffer. */ explicit basic_istream(__streambuf_type* __sb) : _M_gcount(streamsize(0)) { this->init(__sb); } /** * @brief Base destructor. * * This does very little apart from providing a virtual base dtor. */ virtual ~basic_istream() { _M_gcount = streamsize(0); } /// Safe prefix/suffix operations. class sentry; friend class sentry; //@{ /** * @brief Interface for manipulators. * * Manipulators such as @c std::ws and @c std::dec use these * functions in constructs like * std::cin >> std::ws. * For more information, see the iomanip header. */ __istream_type& operator>>(__istream_type& (*__pf)(__istream_type&)) { return __pf(*this); } __istream_type& operator>>(__ios_type& (*__pf)(__ios_type&)) { __pf(*this); return *this; } __istream_type& operator>>(ios_base& (*__pf)(ios_base&)) { __pf(*this); return *this; } //@} //@{ /** * @name Extractors * * All the @c operator>> functions (aka formatted input * functions) have some common behavior. Each starts by * constructing a temporary object of type std::basic_istream::sentry * with the second argument (noskipws) set to false. This has several * effects, concluding with the setting of a status flag; see the * sentry documentation for more. * * If the sentry status is good, the function tries to extract * whatever data is appropriate for the type of the argument. * * If an exception is thrown during extraction, ios_base::badbit * will be turned on in the stream's error state (without causing an * ios_base::failure to be thrown) and the original exception will * be rethrown if badbit is set in the exceptions mask. */ //@{ /** * @brief Integer arithmetic extractors * @param __n A variable of builtin integral type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to parse the input data. */ __istream_type& operator>>(bool& __n) { return _M_extract(__n); } __istream_type& operator>>(short& __n); __istream_type& operator>>(unsigned short& __n) { return _M_extract(__n); } __istream_type& operator>>(int& __n); __istream_type& operator>>(unsigned int& __n) { return _M_extract(__n); } __istream_type& operator>>(long& __n) { return _M_extract(__n); } __istream_type& operator>>(unsigned long& __n) { return _M_extract(__n); } #ifdef _GLIBCXX_USE_LONG_LONG __istream_type& operator>>(long long& __n) { return _M_extract(__n); } __istream_type& operator>>(unsigned long long& __n) { return _M_extract(__n); } #endif //@} //@{ /** * @brief Floating point arithmetic extractors * @param __f A variable of builtin floating point type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to parse the input data. */ __istream_type& operator>>(float& __f) { return _M_extract(__f); } __istream_type& operator>>(double& __f) { return _M_extract(__f); } __istream_type& operator>>(long double& __f) { return _M_extract(__f); } //@} /** * @brief Basic arithmetic extractors * @param __p A variable of pointer type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to parse the input data. */ __istream_type& operator>>(void*& __p) { return _M_extract(__p); } /** * @brief Extracting into another streambuf. * @param __sb A pointer to a streambuf * * This function behaves like one of the basic arithmetic extractors, * in that it also constructs a sentry object and has the same error * handling behavior. * * If @p __sb is NULL, the stream will set failbit in its error state. * * Characters are extracted from this stream and inserted into the * @p __sb streambuf until one of the following occurs: * * - the input stream reaches end-of-file, * - insertion into the output buffer fails (in this case, the * character that would have been inserted is not extracted), or * - an exception occurs (and in this case is caught) * * If the function inserts no characters, failbit is set. */ __istream_type& operator>>(__streambuf_type* __sb); //@} // [27.6.1.3] unformatted input /** * @brief Character counting * @return The number of characters extracted by the previous * unformatted input function dispatched for this stream. */ streamsize gcount() const { return _M_gcount; } //@{ /** * @name Unformatted Input Functions * * All the unformatted input functions have some common behavior. * Each starts by constructing a temporary object of type * std::basic_istream::sentry with the second argument (noskipws) * set to true. This has several effects, concluding with the * setting of a status flag; see the sentry documentation for more. * * If the sentry status is good, the function tries to extract * whatever data is appropriate for the type of the argument. * * The number of characters extracted is stored for later retrieval * by gcount(). * * If an exception is thrown during extraction, ios_base::badbit * will be turned on in the stream's error state (without causing an * ios_base::failure to be thrown) and the original exception will * be rethrown if badbit is set in the exceptions mask. */ /** * @brief Simple extraction. * @return A character, or eof(). * * Tries to extract a character. If none are available, sets failbit * and returns traits::eof(). */ int_type get(); /** * @brief Simple extraction. * @param __c The character in which to store data. * @return *this * * Tries to extract a character and store it in @a __c. If none are * available, sets failbit and returns traits::eof(). * * @note This function is not overloaded on signed char and * unsigned char. */ __istream_type& get(char_type& __c); /** * @brief Simple multiple-character extraction. * @param __s Pointer to an array. * @param __n Maximum number of characters to store in @a __s. * @param __delim A "stop" character. * @return *this * * Characters are extracted and stored into @a __s until one of the * following happens: * * - @c __n-1 characters are stored * - the input sequence reaches EOF * - the next character equals @a __delim, in which case the character * is not extracted * * If no characters are stored, failbit is set in the stream's error * state. * * In any case, a null character is stored into the next location in * the array. * * @note This function is not overloaded on signed char and * unsigned char. */ __istream_type& get(char_type* __s, streamsize __n, char_type __delim); /** * @brief Simple multiple-character extraction. * @param __s Pointer to an array. * @param __n Maximum number of characters to store in @a s. * @return *this * * Returns @c get(__s,__n,widen('\\n')). */ __istream_type& get(char_type* __s, streamsize __n) { return this->get(__s, __n, this->widen('\n')); } /** * @brief Extraction into another streambuf. * @param __sb A streambuf in which to store data. * @param __delim A "stop" character. * @return *this * * Characters are extracted and inserted into @a __sb until one of the * following happens: * * - the input sequence reaches EOF * - insertion into the output buffer fails (in this case, the * character that would have been inserted is not extracted) * - the next character equals @a __delim (in this case, the character * is not extracted) * - an exception occurs (and in this case is caught) * * If no characters are stored, failbit is set in the stream's error * state. */ __istream_type& get(__streambuf_type& __sb, char_type __delim); /** * @brief Extraction into another streambuf. * @param __sb A streambuf in which to store data. * @return *this * * Returns @c get(__sb,widen('\\n')). */ __istream_type& get(__streambuf_type& __sb) { return this->get(__sb, this->widen('\n')); } /** * @brief String extraction. * @param __s A character array in which to store the data. * @param __n Maximum number of characters to extract. * @param __delim A "stop" character. * @return *this * * Extracts and stores characters into @a __s until one of the * following happens. Note that these criteria are required to be * tested in the order listed here, to allow an input line to exactly * fill the @a __s array without setting failbit. * * -# the input sequence reaches end-of-file, in which case eofbit * is set in the stream error state * -# the next character equals @c __delim, in which case the character * is extracted (and therefore counted in @c gcount()) but not stored * -# @c __n-1 characters are stored, in which case failbit is set * in the stream error state * * If no characters are extracted, failbit is set. (An empty line of * input should therefore not cause failbit to be set.) * * In any case, a null character is stored in the next location in * the array. */ __istream_type& getline(char_type* __s, streamsize __n, char_type __delim); /** * @brief String extraction. * @param __s A character array in which to store the data. * @param __n Maximum number of characters to extract. * @return *this * * Returns @c getline(__s,__n,widen('\\n')). */ __istream_type& getline(char_type* __s, streamsize __n) { return this->getline(__s, __n, this->widen('\n')); } /** * @brief Discarding characters * @param __n Number of characters to discard. * @param __delim A "stop" character. * @return *this * * Extracts characters and throws them away until one of the * following happens: * - if @a __n @c != @c std::numeric_limits::max(), @a __n * characters are extracted * - the input sequence reaches end-of-file * - the next character equals @a __delim (in this case, the character * is extracted); note that this condition will never occur if * @a __delim equals @c traits::eof(). * * NB: Provide three overloads, instead of the single function * (with defaults) mandated by the Standard: this leads to a * better performing implementation, while still conforming to * the Standard. */ __istream_type& ignore(streamsize __n, int_type __delim); __istream_type& ignore(streamsize __n); __istream_type& ignore(); /** * @brief Looking ahead in the stream * @return The next character, or eof(). * * If, after constructing the sentry object, @c good() is false, * returns @c traits::eof(). Otherwise reads but does not extract * the next input character. */ int_type peek(); /** * @brief Extraction without delimiters. * @param __s A character array. * @param __n Maximum number of characters to store. * @return *this * * If the stream state is @c good(), extracts characters and stores * them into @a __s until one of the following happens: * - @a __n characters are stored * - the input sequence reaches end-of-file, in which case the error * state is set to @c failbit|eofbit. * * @note This function is not overloaded on signed char and * unsigned char. */ __istream_type& read(char_type* __s, streamsize __n); /** * @brief Extraction until the buffer is exhausted, but no more. * @param __s A character array. * @param __n Maximum number of characters to store. * @return The number of characters extracted. * * Extracts characters and stores them into @a __s depending on the * number of characters remaining in the streambuf's buffer, * @c rdbuf()->in_avail(), called @c A here: * - if @c A @c == @c -1, sets eofbit and extracts no characters * - if @c A @c == @c 0, extracts no characters * - if @c A @c > @c 0, extracts @c min(A,n) * * The goal is to empty the current buffer, and to not request any * more from the external input sequence controlled by the streambuf. */ streamsize readsome(char_type* __s, streamsize __n); /** * @brief Unextracting a single character. * @param __c The character to push back into the input stream. * @return *this * * If @c rdbuf() is not null, calls @c rdbuf()->sputbackc(c). * * If @c rdbuf() is null or if @c sputbackc() fails, sets badbit in * the error state. * * @note This function first clears eofbit. Since no characters * are extracted, the next call to @c gcount() will return 0, * as required by DR 60. */ __istream_type& putback(char_type __c); /** * @brief Unextracting the previous character. * @return *this * * If @c rdbuf() is not null, calls @c rdbuf()->sungetc(c). * * If @c rdbuf() is null or if @c sungetc() fails, sets badbit in * the error state. * * @note This function first clears eofbit. Since no characters * are extracted, the next call to @c gcount() will return 0, * as required by DR 60. */ __istream_type& unget(); /** * @brief Synchronizing the stream buffer. * @return 0 on success, -1 on failure * * If @c rdbuf() is a null pointer, returns -1. * * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, * sets badbit and returns -1. * * Otherwise, returns 0. * * @note This function does not count the number of characters * extracted, if any, and therefore does not affect the next * call to @c gcount(). */ int sync(); /** * @brief Getting the current read position. * @return A file position object. * * If @c fail() is not false, returns @c pos_type(-1) to indicate * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,in). * * @note This function does not count the number of characters * extracted, if any, and therefore does not affect the next * call to @c gcount(). At variance with putback, unget and * seekg, eofbit is not cleared first. */ pos_type tellg(); /** * @brief Changing the current read position. * @param __pos A file position object. * @return *this * * If @c fail() is not true, calls @c rdbuf()->pubseekpos(__pos). If * that function fails, sets failbit. * * @note This function first clears eofbit. It does not count the * number of characters extracted, if any, and therefore does * not affect the next call to @c gcount(). */ __istream_type& seekg(pos_type); /** * @brief Changing the current read position. * @param __off A file offset object. * @param __dir The direction in which to seek. * @return *this * * If @c fail() is not true, calls @c rdbuf()->pubseekoff(__off,__dir). * If that function fails, sets failbit. * * @note This function first clears eofbit. It does not count the * number of characters extracted, if any, and therefore does * not affect the next call to @c gcount(). */ __istream_type& seekg(off_type, ios_base::seekdir); //@} protected: basic_istream() : _M_gcount(streamsize(0)) { this->init(0); } #if __cplusplus >= 201103L basic_istream(const basic_istream&) = delete; basic_istream(basic_istream&& __rhs) : __ios_type(), _M_gcount(__rhs._M_gcount) { __ios_type::move(__rhs); __rhs._M_gcount = 0; } // 27.7.3.3 Assign/swap basic_istream& operator=(const basic_istream&) = delete; basic_istream& operator=(basic_istream&& __rhs) { swap(__rhs); return *this; } void swap(basic_istream& __rhs) { __ios_type::swap(__rhs); std::swap(_M_gcount, __rhs._M_gcount); } #endif template __istream_type& _M_extract(_ValueT& __v); }; /// Explicit specialization declarations, defined in src/istream.cc. template<> basic_istream& basic_istream:: getline(char_type* __s, streamsize __n, char_type __delim); template<> basic_istream& basic_istream:: ignore(streamsize __n); template<> basic_istream& basic_istream:: ignore(streamsize __n, int_type __delim); #ifdef _GLIBCXX_USE_WCHAR_T template<> basic_istream& basic_istream:: getline(char_type* __s, streamsize __n, char_type __delim); template<> basic_istream& basic_istream:: ignore(streamsize __n); template<> basic_istream& basic_istream:: ignore(streamsize __n, int_type __delim); #endif /** * @brief Performs setup work for input streams. * * Objects of this class are created before all of the standard * extractors are run. It is responsible for exception-safe * prefix and suffix operations, although only prefix actions * are currently required by the standard. */ template class basic_istream<_CharT, _Traits>::sentry { // Data Members. bool _M_ok; public: /// Easy access to dependent types. typedef _Traits traits_type; typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::__ctype_type __ctype_type; typedef typename _Traits::int_type __int_type; /** * @brief The constructor performs all the work. * @param __is The input stream to guard. * @param __noskipws Whether to consume whitespace or not. * * If the stream state is good (@a __is.good() is true), then the * following actions are performed, otherwise the sentry state * is false (not okay) and failbit is set in the * stream state. * * The sentry's preparatory actions are: * * -# if the stream is tied to an output stream, @c is.tie()->flush() * is called to synchronize the output sequence * -# if @a __noskipws is false, and @c ios_base::skipws is set in * @c is.flags(), the sentry extracts and discards whitespace * characters from the stream. The currently imbued locale is * used to determine whether each character is whitespace. * * If the stream state is still good, then the sentry state becomes * true (@a okay). */ explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); /** * @brief Quick status checking. * @return The sentry state. * * For ease of use, sentries may be converted to booleans. The * return value is that of the sentry state (true == okay). */ #if __cplusplus >= 201103L explicit #endif operator bool() const { return _M_ok; } }; //@{ /** * @brief Character extractors * @param __in An input stream. * @param __c A character reference. * @return in * * Behaves like one of the formatted arithmetic extractors described in * std::basic_istream. After constructing a sentry object with good * status, this function extracts a character (if one is available) and * stores it in @a __c. Otherwise, sets failbit in the input stream. */ template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); template inline basic_istream& operator>>(basic_istream& __in, unsigned char& __c) { return (__in >> reinterpret_cast(__c)); } template inline basic_istream& operator>>(basic_istream& __in, signed char& __c) { return (__in >> reinterpret_cast(__c)); } //@} //@{ /** * @brief Character string extractors * @param __in An input stream. * @param __s A pointer to a character array. * @return __in * * Behaves like one of the formatted arithmetic extractors described in * std::basic_istream. After constructing a sentry object with good * status, this function extracts up to @c n characters and stores them * into the array starting at @a __s. @c n is defined as: * * - if @c width() is greater than zero, @c n is width() otherwise * - @c n is the number of elements of the largest array of * * - @c char_type that can store a terminating @c eos. * - [27.6.1.2.3]/6 * * Characters are extracted and stored until one of the following happens: * - @c n-1 characters are stored * - EOF is reached * - the next character is whitespace according to the current locale * - the next character is a null byte (i.e., @c charT() ) * * @c width(0) is then called for the input stream. * * If no characters are extracted, sets failbit. */ template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); // Explicit specialization declaration, defined in src/istream.cc. template<> basic_istream& operator>>(basic_istream& __in, char* __s); template inline basic_istream& operator>>(basic_istream& __in, unsigned char* __s) { return (__in >> reinterpret_cast(__s)); } template inline basic_istream& operator>>(basic_istream& __in, signed char* __s) { return (__in >> reinterpret_cast(__s)); } //@} /** * @brief Template class basic_iostream * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class multiply inherits from the input and output stream classes * simply to provide a single interface. */ template class basic_iostream : public basic_istream<_CharT, _Traits>, public basic_ostream<_CharT, _Traits> { public: // _GLIBCXX_RESOLVE_LIB_DEFECTS // 271. basic_iostream missing typedefs // Types (inherited): typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; // Non-standard Types: typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_ostream<_CharT, _Traits> __ostream_type; /** * @brief Constructor does nothing. * * Both of the parent classes are initialized with the same * streambuf pointer passed to this constructor. */ explicit basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) : __istream_type(__sb), __ostream_type(__sb) { } /** * @brief Destructor does nothing. */ virtual ~basic_iostream() { } protected: basic_iostream() : __istream_type(), __ostream_type() { } #if __cplusplus >= 201103L basic_iostream(const basic_iostream&) = delete; basic_iostream(basic_iostream&& __rhs) : __istream_type(std::move(__rhs)), __ostream_type(*this) { } // 27.7.3.3 Assign/swap basic_iostream& operator=(const basic_iostream&) = delete; basic_iostream& operator=(basic_iostream&& __rhs) { swap(__rhs); return *this; } void swap(basic_iostream& __rhs) { __istream_type::swap(__rhs); } #endif }; /** * @brief Quick and easy way to eat whitespace * * This manipulator extracts whitespace characters, stopping when the * next character is non-whitespace, or when the input sequence is empty. * If the sequence is empty, @c eofbit is set in the stream, but not * @c failbit. * * The current locale is used to distinguish whitespace characters. * * Example: * @code * MyClass mc; * * std::cin >> std::ws >> mc; * @endcode * will skip leading whitespace before calling operator>> on cin and your * object. Note that the same effect can be achieved by creating a * std::basic_istream::sentry inside your definition of operator>>. */ template basic_istream<_CharT, _Traits>& ws(basic_istream<_CharT, _Traits>& __is); #if __cplusplus >= 201103L template basic_istream<_Ch, _Up>& __is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*); template struct __is_convertible_to_basic_istream_impl { using __istream_type = void; }; template using __do_is_convertible_to_basic_istream_impl = decltype(__is_convertible_to_basic_istream_test (declval::type*>())); template struct __is_convertible_to_basic_istream_impl <_Tp, __void_t<__do_is_convertible_to_basic_istream_impl<_Tp>>> { using __istream_type = __do_is_convertible_to_basic_istream_impl<_Tp>; }; template struct __is_convertible_to_basic_istream : __is_convertible_to_basic_istream_impl<_Tp> { public: using type = __not_::__istream_type>>; constexpr static bool value = type::value; }; template struct __is_extractable : false_type {}; template struct __is_extractable<_Istream, _Tp, __void_t() >> declval<_Tp>())>> : true_type {}; template using __rvalue_istream_type = typename __is_convertible_to_basic_istream< _Istream>::__istream_type; // [27.7.1.6] Rvalue stream extraction // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2328. Rvalue stream extraction should use perfect forwarding /** * @brief Generic extractor for rvalue stream * @param __is An input stream. * @param __x A reference to the extraction target. * @return is * * This is just a forwarding function to allow extraction from * rvalue streams since they won't bind to the extractor functions * that take an lvalue reference. */ template inline typename enable_if<__and_<__not_>, __is_convertible_to_basic_istream<_Istream>, __is_extractable< __rvalue_istream_type<_Istream>, _Tp&&>>::value, __rvalue_istream_type<_Istream>>::type operator>>(_Istream&& __is, _Tp&& __x) { __rvalue_istream_type<_Istream> __ret_is = __is; __ret_is >> std::forward<_Tp>(__x); return __ret_is; } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_ISTREAM */ PKgd1]ik̔8/stringnu[// Components for manipulating sequences of characters -*- C++ -*- // Copyright (C) 1997-2018 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/string * This is a Standard C++ Library header. */ // // ISO C++ 14882: 21 Strings library // #ifndef _GLIBCXX_STRING #define _GLIBCXX_STRING 1 #pragma GCC system_header #include #include #include // NB: In turn includes stl_algobase.h #include #include #include // For operators >>, <<, and getline. #include #include #include #include #include // For less #include #include #include #include #include #endif /* _GLIBCXX_STRING */ PKgd1]^ 8/cerrnonu[// The -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 cerrno * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c errno.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 19.3 Error numbers // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CERRNO #define _GLIBCXX_CERRNO 1 // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef errno #define errno errno #endif #endif PKgd1]fHW W 8/stacknu[// -*- C++ -*- // Copyright (C) 2001-2018 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,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 include/stack * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_STACK #define _GLIBCXX_STACK 1 #pragma GCC system_header #include #include #endif /* _GLIBCXX_STACK */ PKgd1]ǜg/aa8/newnu[// The -*- C++ -*- dynamic memory management header. // Copyright (C) 1994-2018 Free Software Foundation, Inc. // This file is part of GCC. // // GCC 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. // // GCC 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 new * This is a Standard C++ Library header. * * The header @c new defines several functions to manage dynamic memory and * handling memory allocation errors; see * http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more. */ #ifndef _NEW #define _NEW #pragma GCC system_header #include #include #pragma GCC visibility push(default) extern "C++" { namespace std { /** * @brief Exception possibly thrown by @c new. * @ingroup exceptions * * @c bad_alloc (or classes derived from it) is used to report allocation * errors from the throwing forms of @c new. */ class bad_alloc : public exception { public: bad_alloc() throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_alloc() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; #if __cplusplus >= 201103L class bad_array_new_length : public bad_alloc { public: bad_array_new_length() throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_array_new_length() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; #endif #if __cpp_aligned_new enum class align_val_t: size_t {}; #endif struct nothrow_t { #if __cplusplus >= 201103L explicit nothrow_t() = default; #endif }; extern const nothrow_t nothrow; /** If you write your own error handler to be called by @c new, it must * be of this type. */ typedef void (*new_handler)(); /// Takes a replacement handler as the argument, returns the /// previous handler. new_handler set_new_handler(new_handler) throw(); #if __cplusplus >= 201103L /// Return the current new handler. new_handler get_new_handler() noexcept; #endif } // namespace std //@{ /** These are replaceable signatures: * - normal single new and delete (no arguments, throw @c bad_alloc on error) * - normal array new and delete (same) * - @c nothrow single new and delete (take a @c nothrow argument, return * @c NULL on error) * - @c nothrow array new and delete (same) * * Placement new and delete signatures (take a memory address argument, * does nothing) may not be replaced by a user's program. */ void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc) __attribute__((__externally_visible__)); void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc) __attribute__((__externally_visible__)); void operator delete(void*) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_sized_deallocation void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::size_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #endif void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_aligned_new void* operator new(std::size_t, std::align_val_t) __attribute__((__externally_visible__)); void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void* operator new[](std::size_t, std::align_val_t) __attribute__((__externally_visible__)); void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_sized_deallocation void operator delete(void*, std::size_t, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::size_t, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #endif // __cpp_sized_deallocation #endif // __cpp_aligned_new // Default placement versions of operator new. inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT { return __p; } inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT { return __p; } // Default placement versions of operator delete. inline void operator delete (void*, void*) _GLIBCXX_USE_NOEXCEPT { } inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { } //@} } // extern "C++" #if __cplusplus >= 201703L #if __GNUC__ >= 7 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 #elif defined __has_builtin // For non-GNU compilers: # if __has_builtin(__builtin_launder) # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 # endif #endif #ifdef _GLIBCXX_HAVE_BUILTIN_LAUNDER namespace std { #define __cpp_lib_launder 201606 /// Pointer optimization barrier [ptr.launder] template [[nodiscard]] constexpr _Tp* launder(_Tp* __p) noexcept { return __builtin_launder(__p); } // The program is ill-formed if T is a function type or // (possibly cv-qualified) void. template void launder(_Ret (*)(_Args...) _GLIBCXX_NOEXCEPT_QUAL) = delete; template void launder(_Ret (*)(_Args......) _GLIBCXX_NOEXCEPT_QUAL) = delete; void launder(void*) = delete; void launder(const void*) = delete; void launder(volatile void*) = delete; void launder(const volatile void*) = delete; } #endif // _GLIBCXX_HAVE_BUILTIN_LAUNDER #undef _GLIBCXX_HAVE_BUILTIN_LAUNDER #endif // C++17 #pragma GCC visibility pop #endif PKgd1]Фê8/randomnu[// -*- C++ -*- // Copyright (C) 2007-2018 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/random * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_RANDOM #define _GLIBCXX_RANDOM 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 #include // For uint_fast32_t, uint_fast64_t, uint_least32_t #include #include #include #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_RANDOM PKgd1]+C+C8/backward/hash_setnu[// Hashing set implementation -*- C++ -*- // Copyright (C) 2001-2018 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 * 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. * * * 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. * */ /** @file backward/hash_set * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_SET #define _BACKWARD_HASH_SET 1 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH #include "backward_warning.h" #endif #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::equal_to; using std::allocator; using std::pair; using std::_Identity; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_set { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_set() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_set(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_set(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator==(const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } pair insert(const value_type& __obj) { pair __p = _M_ht.insert_unique(__obj); return pair(__p.first, __p.second); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } pair insert_noresize(const value_type& __obj) { pair __p = _M_ht.insert_unique_noresize(__obj); return pair(__p.first, __p.second); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_multiset { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_multiset() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multiset(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_multiset(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } template friend bool operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) { return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that it will work for hash_set // and hash_multiset. template class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]qL̺8/backward/hashtable.hnu[// Hashtable implementation used by containers -*- C++ -*- // Copyright (C) 2001-2018 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. * * * 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. * */ /** @file backward/hashtable.h * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASHTABLE_H #define _BACKWARD_HASHTABLE_H 1 // Hashtable class, used to implement the hashed associative containers // hash_set, hash_map, hash_multiset, and hash_multimap. #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; using std::forward_iterator_tag; using std::input_iterator_tag; using std::_Construct; using std::_Destroy; using std::distance; using std::vector; using std::pair; using std::__iterator_category; template struct _Hashtable_node { _Hashtable_node* _M_next; _Val _M_val; }; template > class hashtable; template struct _Hashtable_iterator; template struct _Hashtable_const_iterator; template struct _Hashtable_iterator { typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> _Hashtable; typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef _Val& reference; typedef _Val* pointer; _Node* _M_cur; _Hashtable* _M_ht; _Hashtable_iterator(_Node* __n, _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) { } _Hashtable_iterator() { } reference operator*() const { return _M_cur->_M_val; } pointer operator->() const { return &(operator*()); } iterator& operator++(); iterator operator++(int); bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; } bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; } }; template struct _Hashtable_const_iterator { typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> _Hashtable; typedef _Hashtable_iterator<_Val,_Key,_HashFcn, _ExtractKey,_EqualKey,_Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef const _Val& reference; typedef const _Val* pointer; const _Node* _M_cur; const _Hashtable* _M_ht; _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) { } _Hashtable_const_iterator() { } _Hashtable_const_iterator(const iterator& __it) : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { } reference operator*() const { return _M_cur->_M_val; } pointer operator->() const { return &(operator*()); } const_iterator& operator++(); const_iterator operator++(int); bool operator==(const const_iterator& __it) const { return _M_cur == __it._M_cur; } bool operator!=(const const_iterator& __it) const { return _M_cur != __it._M_cur; } }; // Note: assumes long is at least 32 bits. enum { _S_num_primes = 29 }; template struct _Hashtable_prime_list { static const _PrimeType __stl_prime_list[_S_num_primes]; static const _PrimeType* _S_get_prime_list(); }; template const _PrimeType _Hashtable_prime_list<_PrimeType>::__stl_prime_list[_S_num_primes] = { 5ul, 53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul }; template inline const _PrimeType* _Hashtable_prime_list<_PrimeType>::_S_get_prime_list() { return __stl_prime_list; } inline unsigned long __stl_next_prime(unsigned long __n) { const unsigned long* __first = _Hashtable_prime_list::_S_get_prime_list(); const unsigned long* __last = __first + (int)_S_num_primes; const unsigned long* pos = std::lower_bound(__first, __last, __n); return pos == __last ? *(__last - 1) : *pos; } // Forward declaration of operator==. template class hashtable; template bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); // Hashtables handle allocators a bit differently than other // containers do. If we're using standard-conforming allocators, then // a hashtable unconditionally has a member variable to hold its // allocator, even if it so happens that all instances of the // allocator type are identical. This is because, for hashtables, // this extra storage is negligible. Additionally, a base class // wouldn't serve any other purposes; it wouldn't, for example, // simplify the exception-handling code. template class hashtable { public: typedef _Key key_type; typedef _Val value_type; typedef _HashFcn hasher; typedef _EqualKey key_equal; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; hasher hash_funct() const { return _M_hash; } key_equal key_eq() const { return _M_equals; } private: typedef _Hashtable_node<_Val> _Node; public: typedef typename _Alloc::template rebind::other allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } private: typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; _Node_Alloc _M_node_allocator; _Node* _M_get_node() { return _M_node_allocator.allocate(1); } void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } private: hasher _M_hash; key_equal _M_equals; _ExtractKey _M_get_key; _Vector_type _M_buckets; size_type _M_num_elements; public: typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; friend struct _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; friend struct _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; public: hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const _ExtractKey& __ext, const allocator_type& __a = allocator_type()) : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) { _M_initialize_buckets(__n); } hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const allocator_type& __a = allocator_type()) : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) { _M_initialize_buckets(__n); } hashtable(const hashtable& __ht) : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash), _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), _M_buckets(__ht.get_allocator()), _M_num_elements(0) { _M_copy_from(__ht); } hashtable& operator= (const hashtable& __ht) { if (&__ht != this) { clear(); _M_hash = __ht._M_hash; _M_equals = __ht._M_equals; _M_get_key = __ht._M_get_key; _M_copy_from(__ht); } return *this; } ~hashtable() { clear(); } size_type size() const { return _M_num_elements; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } void swap(hashtable& __ht) { std::swap(_M_hash, __ht._M_hash); std::swap(_M_equals, __ht._M_equals); std::swap(_M_get_key, __ht._M_get_key); _M_buckets.swap(__ht._M_buckets); std::swap(_M_num_elements, __ht._M_num_elements); } iterator begin() { for (size_type __n = 0; __n < _M_buckets.size(); ++__n) if (_M_buckets[__n]) return iterator(_M_buckets[__n], this); return end(); } iterator end() { return iterator(0, this); } const_iterator begin() const { for (size_type __n = 0; __n < _M_buckets.size(); ++__n) if (_M_buckets[__n]) return const_iterator(_M_buckets[__n], this); return end(); } const_iterator end() const { return const_iterator(0, this); } template friend bool operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); public: size_type bucket_count() const { return _M_buckets.size(); } size_type max_bucket_count() const { return _Hashtable_prime_list:: _S_get_prime_list()[(int)_S_num_primes - 1]; } size_type elems_in_bucket(size_type __bucket) const { size_type __result = 0; for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) __result += 1; return __result; } pair insert_unique(const value_type& __obj) { resize(_M_num_elements + 1); return insert_unique_noresize(__obj); } iterator insert_equal(const value_type& __obj) { resize(_M_num_elements + 1); return insert_equal_noresize(__obj); } pair insert_unique_noresize(const value_type& __obj); iterator insert_equal_noresize(const value_type& __obj); template void insert_unique(_InputIterator __f, _InputIterator __l) { insert_unique(__f, __l, __iterator_category(__f)); } template void insert_equal(_InputIterator __f, _InputIterator __l) { insert_equal(__f, __l, __iterator_category(__f)); } template void insert_unique(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_unique(*__f); } template void insert_equal(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_equal(*__f); } template void insert_unique(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = distance(__f, __l); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } template void insert_equal(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = distance(__f, __l); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } reference find_or_insert(const value_type& __obj); iterator find(const key_type& __key) { size_type __n = _M_bkt_num_key(__key); _Node* __first; for (__first = _M_buckets[__n]; __first && !_M_equals(_M_get_key(__first->_M_val), __key); __first = __first->_M_next) { } return iterator(__first, this); } const_iterator find(const key_type& __key) const { size_type __n = _M_bkt_num_key(__key); const _Node* __first; for (__first = _M_buckets[__n]; __first && !_M_equals(_M_get_key(__first->_M_val), __key); __first = __first->_M_next) { } return const_iterator(__first, this); } size_type count(const key_type& __key) const { const size_type __n = _M_bkt_num_key(__key); size_type __result = 0; for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), __key)) ++__result; return __result; } pair equal_range(const key_type& __key); pair equal_range(const key_type& __key) const; size_type erase(const key_type& __key); void erase(const iterator& __it); void erase(iterator __first, iterator __last); void erase(const const_iterator& __it); void erase(const_iterator __first, const_iterator __last); void resize(size_type __num_elements_hint); void clear(); private: size_type _M_next_size(size_type __n) const { return __stl_next_prime(__n); } void _M_initialize_buckets(size_type __n) { const size_type __n_buckets = _M_next_size(__n); _M_buckets.reserve(__n_buckets); _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); _M_num_elements = 0; } size_type _M_bkt_num_key(const key_type& __key) const { return _M_bkt_num_key(__key, _M_buckets.size()); } size_type _M_bkt_num(const value_type& __obj) const { return _M_bkt_num_key(_M_get_key(__obj)); } size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { return _M_hash(__key) % __n; } size_type _M_bkt_num(const value_type& __obj, size_t __n) const { return _M_bkt_num_key(_M_get_key(__obj), __n); } _Node* _M_new_node(const value_type& __obj) { _Node* __n = _M_get_node(); __n->_M_next = 0; __try { this->get_allocator().construct(&__n->_M_val, __obj); return __n; } __catch(...) { _M_put_node(__n); __throw_exception_again; } } void _M_delete_node(_Node* __n) { this->get_allocator().destroy(&__n->_M_val); _M_put_node(__n); } void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); void _M_erase_bucket(const size_type __n, _Node* __last); void _M_copy_from(const hashtable& __ht); }; template _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++() { const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } template inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++(int) { iterator __tmp = *this; ++*this; return __tmp; } template _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++() { const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } template inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++(int) { const_iterator __tmp = *this; ++*this; return __tmp; } template bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) { typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) return false; for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) { _Node* __cur1 = __ht1._M_buckets[__n]; _Node* __cur2 = __ht2._M_buckets[__n]; // Check same length of lists for (; __cur1 && __cur2; __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) { } if (__cur1 || __cur2) return false; // Now check one's elements are in the other for (__cur1 = __ht1._M_buckets[__n] ; __cur1; __cur1 = __cur1->_M_next) { bool _found__cur1 = false; for (__cur2 = __ht2._M_buckets[__n]; __cur2; __cur2 = __cur2->_M_next) { if (__cur1->_M_val == __cur2->_M_val) { _found__cur1 = true; break; } } if (!_found__cur1) return false; } } return true; } template inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) { return !(__ht1 == __ht2); } template inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { __ht1.swap(__ht2); } template pair::iterator, bool> hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: insert_unique_noresize(const value_type& __obj) { const size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return pair(iterator(__cur, this), false); _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return pair(iterator(__tmp, this), true); } template typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: insert_equal_noresize(const value_type& __obj) { const size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __cur->_M_next; __cur->_M_next = __tmp; ++_M_num_elements; return iterator(__tmp, this); } _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return iterator(__tmp, this); } template typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: find_or_insert(const value_type& __obj) { resize(_M_num_elements + 1); size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return __cur->_M_val; _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return __tmp->_M_val; } template pair::iterator, typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: equal_range(const key_type& __key) { typedef pair _Pii; const size_type __n = _M_bkt_num_key(__key); for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(iterator(__first, this), iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(iterator(__first, this), iterator(_M_buckets[__m], this)); return _Pii(iterator(__first, this), end()); } return _Pii(end(), end()); } template pair::const_iterator, typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: equal_range(const key_type& __key) const { typedef pair _Pii; const size_type __n = _M_bkt_num_key(__key); for (const _Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) { if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (const _Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(const_iterator(__first, this), const_iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(const_iterator(__first, this), const_iterator(_M_buckets[__m], this)); return _Pii(const_iterator(__first, this), end()); } } return _Pii(end(), end()); } template typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const key_type& __key) { const size_type __n = _M_bkt_num_key(__key); _Node* __first = _M_buckets[__n]; _Node* __saved_slot = 0; size_type __erased = 0; if (__first) { _Node* __cur = __first; _Node* __next = __cur->_M_next; while (__next) { if (_M_equals(_M_get_key(__next->_M_val), __key)) { if (&_M_get_key(__next->_M_val) != &__key) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; ++__erased; --_M_num_elements; } else { __saved_slot = __cur; __cur = __next; __next = __cur->_M_next; } } else { __cur = __next; __next = __cur->_M_next; } } bool __delete_first = _M_equals(_M_get_key(__first->_M_val), __key); if (__saved_slot) { __next = __saved_slot->_M_next; __saved_slot->_M_next = __next->_M_next; _M_delete_node(__next); ++__erased; --_M_num_elements; } if (__delete_first) { _M_buckets[__n] = __first->_M_next; _M_delete_node(__first); ++__erased; --_M_num_elements; } } return __erased; } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const iterator& __it) { _Node* __p = __it._M_cur; if (__p) { const size_type __n = _M_bkt_num(__p->_M_val); _Node* __cur = _M_buckets[__n]; if (__cur == __p) { _M_buckets[__n] = __cur->_M_next; _M_delete_node(__cur); --_M_num_elements; } else { _Node* __next = __cur->_M_next; while (__next) { if (__next == __p) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); --_M_num_elements; break; } else { __cur = __next; __next = __cur->_M_next; } } } } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(iterator __first, iterator __last) { size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); if (__first._M_cur == __last._M_cur) return; else if (__f_bucket == __l_bucket) _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { _M_erase_bucket(__f_bucket, __first._M_cur, 0); for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) _M_erase_bucket(__n, 0); if (__l_bucket != _M_buckets.size()) _M_erase_bucket(__l_bucket, __last._M_cur); } } template inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const_iterator __first, const_iterator __last) { erase(iterator(const_cast<_Node*>(__first._M_cur), const_cast(__first._M_ht)), iterator(const_cast<_Node*>(__last._M_cur), const_cast(__last._M_ht))); } template inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const const_iterator& __it) { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast(__it._M_ht))); } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: resize(size_type __num_elements_hint) { const size_type __old_n = _M_buckets.size(); if (__num_elements_hint > __old_n) { const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); __try { for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; while (__first) { size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); _M_buckets[__bucket] = __first->_M_next; __first->_M_next = __tmp[__new_bucket]; __tmp[__new_bucket] = __first; __first = _M_buckets[__bucket]; } } _M_buckets.swap(__tmp); } __catch(...) { for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { while (__tmp[__bucket]) { _Node* __next = __tmp[__bucket]->_M_next; _M_delete_node(__tmp[__bucket]); __tmp[__bucket] = __next; } } __throw_exception_again; } } } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) { _Node* __cur = _M_buckets[__n]; if (__cur == __first) _M_erase_bucket(__n, __last); else { _Node* __next; for (__next = __cur->_M_next; __next != __first; __cur = __next, __next = __cur->_M_next) ; while (__next != __last) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; --_M_num_elements; } } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: _M_erase_bucket(const size_type __n, _Node* __last) { _Node* __cur = _M_buckets[__n]; while (__cur != __last) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; _M_buckets[__n] = __cur; --_M_num_elements; } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: clear() { if (_M_num_elements == 0) return; for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { _Node* __cur = _M_buckets[__i]; while (__cur != 0) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; } _M_buckets[__i] = 0; } _M_num_elements = 0; } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: _M_copy_from(const hashtable& __ht) { _M_buckets.clear(); _M_buckets.reserve(__ht._M_buckets.size()); _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); __try { for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { const _Node* __cur = __ht._M_buckets[__i]; if (__cur) { _Node* __local_copy = _M_new_node(__cur->_M_val); _M_buckets[__i] = __local_copy; for (_Node* __next = __cur->_M_next; __next; __cur = __next, __next = __cur->_M_next) { __local_copy->_M_next = _M_new_node(__next->_M_val); __local_copy = __local_copy->_M_next; } } } _M_num_elements = __ht._M_num_elements; } __catch(...) { clear(); __throw_exception_again; } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]&A 8/backward/backward_warning.hnu[// Copyright (C) 2001-2018 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 backward/backward_warning.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _BACKWARD_BACKWARD_WARNING_H #define _BACKWARD_BACKWARD_WARNING_H 1 #ifdef __DEPRECATED #warning \ This file includes at least one deprecated or antiquated header which \ may be removed without further notice at a future date. Please use a \ non-deprecated interface with equivalent functionality instead. For a \ listing of replacement headers and interfaces, consult the file \ backward_warning.h. To disable this warning use -Wno-deprecated. /* A list of valid replacements is as follows: Use: Instead of: , basic_stringbuf , strstreambuf , basic_istringstream , istrstream , basic_ostringstream , ostrstream , basic_stringstream , strstream , unordered_set , hash_set , unordered_multiset , hash_multiset , unordered_map , hash_map , unordered_multimap , hash_multimap , bind , binder1st , bind , binder2nd , bind , bind1st , bind , bind2nd , unique_ptr , auto_ptr */ #endif #endif PKgd1]4*4*8/backward/auto_ptr.hnu[// auto_ptr implementation -*- C++ -*- // Copyright (C) 2007-2018 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 backward/auto_ptr.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _BACKWARD_AUTO_PTR_H #define _BACKWARD_AUTO_PTR_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * A wrapper class to provide auto_ptr with reference semantics. * For example, an auto_ptr can be assigned (or constructed from) * the result of a function which returns an auto_ptr by value. * * All the auto_ptr_ref stuff should happen behind the scenes. */ template struct auto_ptr_ref { _Tp1* _M_ptr; explicit auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { } } _GLIBCXX_DEPRECATED; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /** * @brief A simple smart pointer providing strict ownership semantics. * * The Standard says: *
   *  An @c auto_ptr owns the object it holds a pointer to.  Copying
   *  an @c auto_ptr copies the pointer and transfers ownership to the
   *  destination.  If more than one @c auto_ptr owns the same object
   *  at the same time the behavior of the program is undefined.
   *
   *  The uses of @c auto_ptr include providing temporary
   *  exception-safety for dynamically allocated memory, passing
   *  ownership of dynamically allocated memory to a function, and
   *  returning dynamically allocated memory from a function.  @c
   *  auto_ptr does not meet the CopyConstructible and Assignable
   *  requirements for Standard Library container elements and thus
   *  instantiating a Standard Library container with an @c auto_ptr
   *  results in undefined behavior.
   *  
* Quoted from [20.4.5]/3. * * Good examples of what can and cannot be done with auto_ptr can * be found in the libstdc++ testsuite. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * 127. auto_ptr<> conversion issues * These resolutions have all been incorporated. */ template class auto_ptr { private: _Tp* _M_ptr; public: /// The pointed-to type. typedef _Tp element_type; /** * @brief An %auto_ptr is usually constructed from a raw pointer. * @param __p A pointer (defaults to NULL). * * This object now @e owns the object pointed to by @a __p. */ explicit auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } /** * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param __a Another %auto_ptr of the same type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. */ auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } /** * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param __a Another %auto_ptr of a different but related type. * * A pointer-to-Tp1 must be convertible to a * pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. */ template auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } /** * @brief %auto_ptr assignment operator. * @param __a Another %auto_ptr of the same type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. The object that this one @e * used to own and track has been deleted. */ auto_ptr& operator=(auto_ptr& __a) throw() { reset(__a.release()); return *this; } /** * @brief %auto_ptr assignment operator. * @param __a Another %auto_ptr of a different but related type. * * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. The object that this one @e * used to own and track has been deleted. */ template auto_ptr& operator=(auto_ptr<_Tp1>& __a) throw() { reset(__a.release()); return *this; } /** * When the %auto_ptr goes out of scope, the object it owns is * deleted. If it no longer owns anything (i.e., @c get() is * @c NULL), then this has no effect. * * The C++ standard says there is supposed to be an empty throw * specification here, but omitting it is standard conforming. Its * presence can be detected only if _Tp::~_Tp() throws, but this is * prohibited. [17.4.3.6]/2 */ ~auto_ptr() { delete _M_ptr; } /** * @brief Smart pointer dereferencing. * * If this %auto_ptr no longer owns anything, then this * operation will crash. (For a smart pointer, no longer owns * anything is the same as being a null pointer, and you know * what happens when you dereference one of those...) */ element_type& operator*() const throw() { __glibcxx_assert(_M_ptr != 0); return *_M_ptr; } /** * @brief Smart pointer dereferencing. * * This returns the pointer itself, which the language then will * automatically cause to be dereferenced. */ element_type* operator->() const throw() { __glibcxx_assert(_M_ptr != 0); return _M_ptr; } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for * situations such as passing to a function which only accepts * a raw pointer. * * @note This %auto_ptr still owns the memory. */ element_type* get() const throw() { return _M_ptr; } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for * situations such as passing to a function which only accepts * a raw pointer. * * @note This %auto_ptr no longer owns the memory. When this object * goes out of scope, nothing will happen. */ element_type* release() throw() { element_type* __tmp = _M_ptr; _M_ptr = 0; return __tmp; } /** * @brief Forcibly deletes the managed object. * @param __p A pointer (defaults to NULL). * * This object now @e owns the object pointed to by @a __p. The * previous object has been deleted. */ void reset(element_type* __p = 0) throw() { if (__p != _M_ptr) { delete _M_ptr; _M_ptr = __p; } } /** * @brief Automatic conversions * * These operations are supposed to convert an %auto_ptr into and from * an auto_ptr_ref automatically as needed. This would allow * constructs such as * @code * auto_ptr func_returning_auto_ptr(.....); * ... * auto_ptr ptr = func_returning_auto_ptr(.....); * @endcode * * But it doesn't work, and won't be fixed. For further details see * http://cplusplus.github.io/LWG/lwg-closed.html#463 */ auto_ptr(auto_ptr_ref __ref) throw() : _M_ptr(__ref._M_ptr) { } auto_ptr& operator=(auto_ptr_ref __ref) throw() { if (__ref._M_ptr != this->get()) { delete _M_ptr; _M_ptr = __ref._M_ptr; } return *this; } template operator auto_ptr_ref<_Tp1>() throw() { return auto_ptr_ref<_Tp1>(this->release()); } template operator auto_ptr<_Tp1>() throw() { return auto_ptr<_Tp1>(this->release()); } } _GLIBCXX_DEPRECATED; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 541. shared_ptr template assignment and void template<> class auto_ptr { public: typedef void element_type; } _GLIBCXX_DEPRECATED; #if __cplusplus >= 201103L template<_Lock_policy _Lp> template inline __shared_count<_Lp>::__shared_count(std::auto_ptr<_Tp>&& __r) : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get())) { __r.release(); } template template inline __shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Tp1>&& __r) : _M_ptr(__r.get()), _M_refcount() { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) static_assert( sizeof(_Tp1) > 0, "incomplete type" ); _Tp1* __tmp = __r.get(); _M_refcount = __shared_count<_Lp>(std::move(__r)); _M_enable_shared_from_this_with(__tmp); } template template inline shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r) : __shared_ptr<_Tp>(std::move(__r)) { } template template inline unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept : _M_t(__u.release(), deleter_type()) { } #endif #pragma GCC diagnostic pop _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _BACKWARD_AUTO_PTR_H */ PKgd1]Ioξ8/backward/binders.hnu[// Functor implementations -*- C++ -*- // Copyright (C) 2001-2018 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 backward/binders.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _BACKWARD_BINDERS_H #define _BACKWARD_BINDERS_H 1 // Suppress deprecated warning for this file. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // 20.3.6 binders /** @defgroup binders Binder Classes * @ingroup functors * * Binders turn functions/functors with two arguments into functors * with a single argument, storing an argument to be applied later. * For example, a variable @c B of type @c binder1st is constructed * from a functor @c f and an argument @c x. Later, B's @c * operator() is called with a single argument @c y. The return * value is the value of @c f(x,y). @c B can be @a called with * various arguments (y1, y2, ...) and will in turn call @c * f(x,y1), @c f(x,y2), ... * * The function @c bind1st is provided to save some typing. It takes the * function and an argument as parameters, and returns an instance of * @c binder1st. * * The type @c binder2nd and its creator function @c bind2nd do the same * thing, but the stored argument is passed as the second parameter instead * of the first, e.g., @c bind2nd(std::minus(),1.3) will create a * functor whose @c operator() accepts a floating-point number, subtracts * 1.3 from it, and returns the result. (If @c bind1st had been used, * the functor would perform 1.3 - x instead. * * Creator-wrapper functions like @c bind1st are intended to be used in * calling algorithms. Their return values will be temporary objects. * (The goal is to not require you to type names like * @c std::binder1st> for declaring a variable to hold the * return value from @c bind1st(std::plus(),5). * * These become more useful when combined with the composition functions. * * These functions are deprecated in C++11 and can be replaced by * @c std::bind (or @c std::tr1::bind) which is more powerful and flexible, * supporting functions with any number of arguments. Uses of @c bind1st * can be replaced by @c std::bind(f, x, std::placeholders::_1) and * @c bind2nd by @c std::bind(f, std::placeholders::_1, x). * @{ */ /// One of the @link binders binder functors@endlink. template class binder1st : public unary_function { protected: _Operation op; typename _Operation::first_argument_type value; public: binder1st(const _Operation& __x, const typename _Operation::first_argument_type& __y) : op(__x), value(__y) { } typename _Operation::result_type operator()(const typename _Operation::second_argument_type& __x) const { return op(value, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements typename _Operation::result_type operator()(typename _Operation::second_argument_type& __x) const { return op(value, __x); } } _GLIBCXX_DEPRECATED; /// One of the @link binders binder functors@endlink. template inline binder1st<_Operation> bind1st(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::first_argument_type _Arg1_type; return binder1st<_Operation>(__fn, _Arg1_type(__x)); } /// One of the @link binders binder functors@endlink. template class binder2nd : public unary_function { protected: _Operation op; typename _Operation::second_argument_type value; public: binder2nd(const _Operation& __x, const typename _Operation::second_argument_type& __y) : op(__x), value(__y) { } typename _Operation::result_type operator()(const typename _Operation::first_argument_type& __x) const { return op(__x, value); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements typename _Operation::result_type operator()(typename _Operation::first_argument_type& __x) const { return op(__x, value); } } _GLIBCXX_DEPRECATED; /// One of the @link binders binder functors@endlink. template inline binder2nd<_Operation> bind2nd(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::second_argument_type _Arg2_type; return binder2nd<_Operation>(__fn, _Arg2_type(__x)); } /** @} */ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #pragma GCC diagnostic pop #endif /* _BACKWARD_BINDERS_H */ PKgd1]T8/backward/strstreamnu[// Backward-compat support -*- C++ -*- // Copyright (C) 2001-2018 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) 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. */ // WARNING: The classes defined in this header are DEPRECATED. This // header is defined in section D.7.1 of the C++ standard, and it // MAY BE REMOVED in a future standard revision. One should use the // header instead. /** @file strstream * This is a Standard C++ Library header. */ #ifndef _BACKWARD_STRSTREAM #define _BACKWARD_STRSTREAM #include "backward_warning.h" #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Class strstreambuf, a streambuf class that manages an array of char. // Note that this class is not a template. class strstreambuf : public basic_streambuf > { public: // Types. typedef char_traits _Traits; typedef basic_streambuf _Base; public: // Constructor, destructor explicit strstreambuf(streamsize __initial_capacity = 0); strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); strstreambuf(char* __get, streamsize __n, char* __put = 0) throw (); strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0) throw (); strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0) throw (); strstreambuf(const char* __get, streamsize __n) throw (); strstreambuf(const signed char* __get, streamsize __n) throw (); strstreambuf(const unsigned char* __get, streamsize __n) throw (); virtual ~strstreambuf(); public: void freeze(bool = true) throw (); char* str() throw (); _GLIBCXX_PURE int pcount() const throw (); protected: virtual int_type overflow(int_type __c = _Traits::eof()); virtual int_type pbackfail(int_type __c = _Traits::eof()); virtual int_type underflow(); virtual _Base* setbuf(char* __buf, streamsize __n); virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir, ios_base::openmode __mode = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); private: strstreambuf& operator=(const strstreambuf&); strstreambuf(const strstreambuf&); // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. char* _M_alloc(size_t); void _M_free(char*); // Helper function used in constructors. void _M_setup(char* __get, char* __put, streamsize __n) throw (); private: // Data members. void* (*_M_alloc_fun)(size_t); void (*_M_free_fun)(void*); bool _M_dynamic : 1; bool _M_frozen : 1; bool _M_constant : 1; }; // Class istrstream, an istream that manages a strstreambuf. class istrstream : public basic_istream { public: explicit istrstream(char*); explicit istrstream(const char*); istrstream(char* , streamsize); istrstream(const char*, streamsize); virtual ~istrstream(); _GLIBCXX_CONST strstreambuf* rdbuf() const throw (); char* str() throw (); private: strstreambuf _M_buf; }; // Class ostrstream class ostrstream : public basic_ostream { public: ostrstream(); ostrstream(char*, int, ios_base::openmode = ios_base::out); virtual ~ostrstream(); _GLIBCXX_CONST strstreambuf* rdbuf() const throw (); void freeze(bool = true) throw(); char* str() throw (); _GLIBCXX_PURE int pcount() const throw (); private: strstreambuf _M_buf; }; // Class strstream class strstream : public basic_iostream { public: typedef char char_type; typedef char_traits::int_type int_type; typedef char_traits::pos_type pos_type; typedef char_traits::off_type off_type; strstream(); strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out); virtual ~strstream(); _GLIBCXX_CONST strstreambuf* rdbuf() const throw (); void freeze(bool = true) throw (); _GLIBCXX_PURE int pcount() const throw (); char* str() throw (); private: strstreambuf _M_buf; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]oEoE8/backward/hash_mapnu[// Hashing map implementation -*- C++ -*- // Copyright (C) 2001-2018 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 * 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. * * * 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. * */ /** @file backward/hash_map * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_MAP #define _BACKWARD_HASH_MAP 1 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH #include "backward_warning.h" #endif #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::equal_to; using std::allocator; using std::pair; using std::_Select1st; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > class hash_map { private: typedef hashtable,_Key, _HashFn, _Select1st >, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Ht::pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_map(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_map(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_map(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, const hash_map<_K1, _T1, _HF, _EqK, _Al>&); iterator begin() { return _M_ht.begin(); } iterator end() { return _M_ht.end(); } const_iterator begin() const { return _M_ht.begin(); } const_iterator end() const { return _M_ht.end(); } pair insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } pair insert_noresize(const value_type& __obj) { return _M_ht.insert_unique_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } _Tp& operator[](const key_type& __key) { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } template inline bool operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { return !(__hm1 == __hm2); } template inline void swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { __hm1.swap(__hm2); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > class hash_multimap { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) __glibcxx_class_requires(_Tp, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) private: typedef hashtable, _Key, _HashFn, _Select1st >, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Ht::pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multimap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multimap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_multimap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); iterator begin() { return _M_ht.begin(); } iterator end() { return _M_ht.end(); } const_iterator begin() const { return _M_ht.begin(); } const_iterator end() const { return _M_ht.end(); } iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) { return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } template inline bool operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) { return !(__hm1 == __hm2); } template inline void swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { __hm1.swap(__hm2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that it will work for hash_map // and hash_multimap. template class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { protected: typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { protected: typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]4q$8/backward/hash_fun.hnu[// 'struct hash' from SGI -*- C++ -*- // Copyright (C) 2001-2018 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-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. * * * 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. * */ /** @file backward/hash_fun.h * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_FUN_H #define _BACKWARD_HASH_FUN_H 1 #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; template struct hash { }; inline size_t __stl_hash_string(const char* __s) { unsigned long __h = 0; for ( ; *__s; ++__s) __h = 5 * __h + *__s; return size_t(__h); } template<> struct hash { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; template<> struct hash { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; template<> struct hash { size_t operator()(char __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned char __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned char __x) const { return __x; } }; template<> struct hash { size_t operator()(short __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned short __x) const { return __x; } }; template<> struct hash { size_t operator()(int __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned int __x) const { return __x; } }; template<> struct hash { size_t operator()(long __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned long __x) const { return __x; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]Ctj--8/system_errornu[// -*- C++ -*- // Copyright (C) 2007-2018 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/system_error * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SYSTEM_ERROR #define _GLIBCXX_SYSTEM_ERROR 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION class error_code; class error_condition; class system_error; /// is_error_code_enum template struct is_error_code_enum : public false_type { }; /// is_error_condition_enum template struct is_error_condition_enum : public false_type { }; template<> struct is_error_condition_enum : public true_type { }; #if __cplusplus > 201402L template inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; template inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; #endif // C++17 inline namespace _V2 { /// error_category class error_category { public: constexpr error_category() noexcept = default; virtual ~error_category(); error_category(const error_category&) = delete; error_category& operator=(const error_category&) = delete; virtual const char* name() const noexcept = 0; // We need two different virtual functions here, one returning a // COW string and one returning an SSO string. Their positions in the // vtable must be consistent for dynamic dispatch to work, but which one // the name "message()" finds depends on which ABI the caller is using. #if _GLIBCXX_USE_CXX11_ABI private: _GLIBCXX_DEFAULT_ABI_TAG virtual __cow_string _M_message(int) const; public: _GLIBCXX_DEFAULT_ABI_TAG virtual string message(int) const = 0; #else virtual string message(int) const = 0; private: virtual __sso_string _M_message(int) const; #endif public: virtual error_condition default_error_condition(int __i) const noexcept; virtual bool equivalent(int __i, const error_condition& __cond) const noexcept; virtual bool equivalent(const error_code& __code, int __i) const noexcept; bool operator<(const error_category& __other) const noexcept { return less()(this, &__other); } bool operator==(const error_category& __other) const noexcept { return this == &__other; } bool operator!=(const error_category& __other) const noexcept { return this != &__other; } }; // DR 890. _GLIBCXX_CONST const error_category& system_category() noexcept; _GLIBCXX_CONST const error_category& generic_category() noexcept; } // end inline namespace error_code make_error_code(errc) noexcept; template struct hash; /// error_code // Implementation-specific error identification struct error_code { error_code() noexcept : _M_value(0), _M_cat(&system_category()) { } error_code(int __v, const error_category& __cat) noexcept : _M_value(__v), _M_cat(&__cat) { } template::value>::type> error_code(_ErrorCodeEnum __e) noexcept { *this = make_error_code(__e); } void assign(int __v, const error_category& __cat) noexcept { _M_value = __v; _M_cat = &__cat; } void clear() noexcept { assign(0, system_category()); } // DR 804. template typename enable_if::value, error_code&>::type operator=(_ErrorCodeEnum __e) noexcept { return *this = make_error_code(__e); } int value() const noexcept { return _M_value; } const error_category& category() const noexcept { return *_M_cat; } error_condition default_error_condition() const noexcept; _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } explicit operator bool() const noexcept { return _M_value != 0; } // DR 804. private: friend class hash; int _M_value; const error_category* _M_cat; }; // 19.4.2.6 non-member functions inline error_code make_error_code(errc __e) noexcept { return error_code(static_cast(__e), generic_category()); } inline bool operator<(const error_code& __lhs, const error_code& __rhs) noexcept { return (__lhs.category() < __rhs.category() || (__lhs.category() == __rhs.category() && __lhs.value() < __rhs.value())); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) { return (__os << __e.category().name() << ':' << __e.value()); } error_condition make_error_condition(errc) noexcept; /// error_condition // Portable error identification struct error_condition { error_condition() noexcept : _M_value(0), _M_cat(&generic_category()) { } error_condition(int __v, const error_category& __cat) noexcept : _M_value(__v), _M_cat(&__cat) { } template::value>::type> error_condition(_ErrorConditionEnum __e) noexcept { *this = make_error_condition(__e); } void assign(int __v, const error_category& __cat) noexcept { _M_value = __v; _M_cat = &__cat; } // DR 804. template typename enable_if::value, error_condition&>::type operator=(_ErrorConditionEnum __e) noexcept { return *this = make_error_condition(__e); } void clear() noexcept { assign(0, generic_category()); } // 19.4.3.4 observers int value() const noexcept { return _M_value; } const error_category& category() const noexcept { return *_M_cat; } _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } explicit operator bool() const noexcept { return _M_value != 0; } // DR 804. private: int _M_value; const error_category* _M_cat; }; // 19.4.3.6 non-member functions inline error_condition make_error_condition(errc __e) noexcept { return error_condition(static_cast(__e), generic_category()); } inline bool operator<(const error_condition& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category() < __rhs.category() || (__lhs.category() == __rhs.category() && __lhs.value() < __rhs.value())); } // 19.4.4 Comparison operators inline bool operator==(const error_code& __lhs, const error_code& __rhs) noexcept { return (__lhs.category() == __rhs.category() && __lhs.value() == __rhs.value()); } inline bool operator==(const error_code& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category().equivalent(__lhs.value(), __rhs) || __rhs.category().equivalent(__lhs, __rhs.value())); } inline bool operator==(const error_condition& __lhs, const error_code& __rhs) noexcept { return (__rhs.category().equivalent(__rhs.value(), __lhs) || __lhs.category().equivalent(__rhs, __lhs.value())); } inline bool operator==(const error_condition& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category() == __rhs.category() && __lhs.value() == __rhs.value()); } inline bool operator!=(const error_code& __lhs, const error_code& __rhs) noexcept { return !(__lhs == __rhs); } inline bool operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept { return !(__lhs == __rhs); } inline bool operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept { return !(__lhs == __rhs); } inline bool operator!=(const error_condition& __lhs, const error_condition& __rhs) noexcept { return !(__lhs == __rhs); } /** * @brief Thrown to indicate error code of underlying system. * * @ingroup exceptions */ class system_error : public std::runtime_error { private: error_code _M_code; public: system_error(error_code __ec = error_code()) : runtime_error(__ec.message()), _M_code(__ec) { } system_error(error_code __ec, const string& __what) : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } system_error(error_code __ec, const char* __what) : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } system_error(int __v, const error_category& __ecat, const char* __what) : system_error(error_code(__v, __ecat), __what) { } system_error(int __v, const error_category& __ecat) : runtime_error(error_code(__v, __ecat).message()), _M_code(__v, __ecat) { } system_error(int __v, const error_category& __ecat, const string& __what) : runtime_error(__what + ": " + error_code(__v, __ecat).message()), _M_code(__v, __ecat) { } virtual ~system_error() noexcept; const error_code& code() const noexcept { return _M_code; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifndef _GLIBCXX_COMPATIBILITY_CXX0X // DR 1182. /// std::hash specialization for error_code. template<> struct hash : public __hash_base { size_t operator()(const error_code& __e) const noexcept { const size_t __tmp = std::_Hash_impl::hash(__e._M_value); return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); } }; #endif // _GLIBCXX_COMPATIBILITY_CXX0X #if __cplusplus > 201402L // DR 2686. /// std::hash specialization for error_condition. template<> struct hash : public __hash_base { size_t operator()(const error_condition& __e) const noexcept { const size_t __tmp = std::_Hash_impl::hash(__e.value()); return std::_Hash_impl::__hash_combine(__e.category(), __tmp); } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_SYSTEM_ERROR PKgd1]Z; 8/setnu[// -*- C++ -*- // Copyright (C) 2001-2018 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,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 include/set * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SET #define _GLIBCXX_SET 1 #pragma GCC system_header #include #include #include #include #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif /* _GLIBCXX_SET */ PKgd1]888/unordered_mapnu[// -*- C++ -*- // Copyright (C) 2007-2018 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. */ #ifndef _GLIBCXX_UNORDERED_MAP #define _GLIBCXX_UNORDERED_MAP 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include // equal_to, _Identity, _Select1st #include #include #include #include #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif // C++11 #endif // _GLIBCXX_UNORDERED_MAP PKgd1]F 8/queuenu[// -*- C++ -*- // Copyright (C) 2001-2018 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,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 include/queue * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_QUEUE #define _GLIBCXX_QUEUE 1 #pragma GCC system_header #include #include #include #include #include #endif /* _GLIBCXX_QUEUE */ PKgd1]@KK8/shared_mutexnu[// -*- C++ -*- // Copyright (C) 2013-2018 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/shared_mutex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SHARED_MUTEX #define _GLIBCXX_SHARED_MUTEX 1 #pragma GCC system_header #if __cplusplus >= 201402L #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @ingroup mutexes * @{ */ #ifdef _GLIBCXX_USE_C99_STDINT_TR1 #ifdef _GLIBCXX_HAS_GTHREADS #if __cplusplus >= 201703L #define __cpp_lib_shared_mutex 201505 class shared_mutex; #endif #define __cpp_lib_shared_timed_mutex 201402 class shared_timed_mutex; #if _GLIBCXX_USE_PTHREAD_RWLOCK_T /// A shared mutex type implemented using pthread_rwlock_t. class __shared_mutex_pthread { friend class shared_timed_mutex; #ifdef PTHREAD_RWLOCK_INITIALIZER pthread_rwlock_t _M_rwlock = PTHREAD_RWLOCK_INITIALIZER; public: __shared_mutex_pthread() = default; ~__shared_mutex_pthread() = default; #else pthread_rwlock_t _M_rwlock; public: __shared_mutex_pthread() { int __ret = pthread_rwlock_init(&_M_rwlock, NULL); if (__ret == ENOMEM) __throw_bad_alloc(); else if (__ret == EAGAIN) __throw_system_error(int(errc::resource_unavailable_try_again)); else if (__ret == EPERM) __throw_system_error(int(errc::operation_not_permitted)); // Errors not handled: EBUSY, EINVAL __glibcxx_assert(__ret == 0); } ~__shared_mutex_pthread() { int __ret __attribute((__unused__)) = pthread_rwlock_destroy(&_M_rwlock); // Errors not handled: EBUSY, EINVAL __glibcxx_assert(__ret == 0); } #endif __shared_mutex_pthread(const __shared_mutex_pthread&) = delete; __shared_mutex_pthread& operator=(const __shared_mutex_pthread&) = delete; void lock() { int __ret = pthread_rwlock_wrlock(&_M_rwlock); if (__ret == EDEADLK) __throw_system_error(int(errc::resource_deadlock_would_occur)); // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); } bool try_lock() { int __ret = pthread_rwlock_trywrlock(&_M_rwlock); if (__ret == EBUSY) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } void unlock() { int __ret __attribute((__unused__)) = pthread_rwlock_unlock(&_M_rwlock); // Errors not handled: EPERM, EBUSY, EINVAL __glibcxx_assert(__ret == 0); } // Shared ownership void lock_shared() { int __ret; // We retry if we exceeded the maximum number of read locks supported by // the POSIX implementation; this can result in busy-waiting, but this // is okay based on the current specification of forward progress // guarantees by the standard. do __ret = pthread_rwlock_rdlock(&_M_rwlock); while (__ret == EAGAIN); if (__ret == EDEADLK) __throw_system_error(int(errc::resource_deadlock_would_occur)); // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); } bool try_lock_shared() { int __ret = pthread_rwlock_tryrdlock(&_M_rwlock); // If the maximum number of read locks has been exceeded, we just fail // to acquire the lock. Unlike for lock(), we are not allowed to throw // an exception. if (__ret == EBUSY || __ret == EAGAIN) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } void unlock_shared() { unlock(); } void* native_handle() { return &_M_rwlock; } }; #endif #if ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK) /// A shared mutex type implemented using std::condition_variable. class __shared_mutex_cv { friend class shared_timed_mutex; // Based on Howard Hinnant's reference implementation from N2406. // The high bit of _M_state is the write-entered flag which is set to // indicate a writer has taken the lock or is queuing to take the lock. // The remaining bits are the count of reader locks. // // To take a reader lock, block on gate1 while the write-entered flag is // set or the maximum number of reader locks is held, then increment the // reader lock count. // To release, decrement the count, then if the write-entered flag is set // and the count is zero then signal gate2 to wake a queued writer, // otherwise if the maximum number of reader locks was held signal gate1 // to wake a reader. // // To take a writer lock, block on gate1 while the write-entered flag is // set, then set the write-entered flag to start queueing, then block on // gate2 while the number of reader locks is non-zero. // To release, unset the write-entered flag and signal gate1 to wake all // blocked readers and writers. // // This means that when no reader locks are held readers and writers get // equal priority. When one or more reader locks is held a writer gets // priority and no more reader locks can be taken while the writer is // queued. // Only locked when accessing _M_state or waiting on condition variables. mutex _M_mut; // Used to block while write-entered is set or reader count at maximum. condition_variable _M_gate1; // Used to block queued writers while reader count is non-zero. condition_variable _M_gate2; // The write-entered flag and reader count. unsigned _M_state; static constexpr unsigned _S_write_entered = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1); static constexpr unsigned _S_max_readers = ~_S_write_entered; // Test whether the write-entered flag is set. _M_mut must be locked. bool _M_write_entered() const { return _M_state & _S_write_entered; } // The number of reader locks currently held. _M_mut must be locked. unsigned _M_readers() const { return _M_state & _S_max_readers; } public: __shared_mutex_cv() : _M_state(0) {} ~__shared_mutex_cv() { __glibcxx_assert( _M_state == 0 ); } __shared_mutex_cv(const __shared_mutex_cv&) = delete; __shared_mutex_cv& operator=(const __shared_mutex_cv&) = delete; // Exclusive ownership void lock() { unique_lock __lk(_M_mut); // Wait until we can set the write-entered flag. _M_gate1.wait(__lk, [=]{ return !_M_write_entered(); }); _M_state |= _S_write_entered; // Then wait until there are no more readers. _M_gate2.wait(__lk, [=]{ return _M_readers() == 0; }); } bool try_lock() { unique_lock __lk(_M_mut, try_to_lock); if (__lk.owns_lock() && _M_state == 0) { _M_state = _S_write_entered; return true; } return false; } void unlock() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_write_entered() ); _M_state = 0; // call notify_all() while mutex is held so that another thread can't // lock and unlock the mutex then destroy *this before we make the call. _M_gate1.notify_all(); } // Shared ownership void lock_shared() { unique_lock __lk(_M_mut); _M_gate1.wait(__lk, [=]{ return _M_state < _S_max_readers; }); ++_M_state; } bool try_lock_shared() { unique_lock __lk(_M_mut, try_to_lock); if (!__lk.owns_lock()) return false; if (_M_state < _S_max_readers) { ++_M_state; return true; } return false; } void unlock_shared() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_readers() > 0 ); auto __prev = _M_state--; if (_M_write_entered()) { // Wake the queued writer if there are no more readers. if (_M_readers() == 0) _M_gate2.notify_one(); // No need to notify gate1 because we give priority to the queued // writer, and that writer will eventually notify gate1 after it // clears the write-entered flag. } else { // Wake any thread that was blocked on reader overflow. if (__prev == _S_max_readers) _M_gate1.notify_one(); } } }; #endif #if __cplusplus > 201402L /// The standard shared mutex type. class shared_mutex { public: shared_mutex() = default; ~shared_mutex() = default; shared_mutex(const shared_mutex&) = delete; shared_mutex& operator=(const shared_mutex&) = delete; // Exclusive ownership void lock() { _M_impl.lock(); } bool try_lock() { return _M_impl.try_lock(); } void unlock() { _M_impl.unlock(); } // Shared ownership void lock_shared() { _M_impl.lock_shared(); } bool try_lock_shared() { return _M_impl.try_lock_shared(); } void unlock_shared() { _M_impl.unlock_shared(); } #if _GLIBCXX_USE_PTHREAD_RWLOCK_T typedef void* native_handle_type; native_handle_type native_handle() { return _M_impl.native_handle(); } private: __shared_mutex_pthread _M_impl; #else private: __shared_mutex_cv _M_impl; #endif }; #endif // C++17 #if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK using __shared_timed_mutex_base = __shared_mutex_pthread; #else using __shared_timed_mutex_base = __shared_mutex_cv; #endif /// The standard shared timed mutex type. class shared_timed_mutex : private __shared_timed_mutex_base { using _Base = __shared_timed_mutex_base; // Must use the same clock as condition_variable for __shared_mutex_cv. typedef chrono::system_clock __clock_t; public: shared_timed_mutex() = default; ~shared_timed_mutex() = default; shared_timed_mutex(const shared_timed_mutex&) = delete; shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; // Exclusive ownership void lock() { _Base::lock(); } bool try_lock() { return _Base::try_lock(); } void unlock() { _Base::unlock(); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_until(__clock_t::now() + __rel_time); } // Shared ownership void lock_shared() { _Base::lock_shared(); } bool try_lock_shared() { return _Base::try_lock_shared(); } void unlock_shared() { _Base::unlock_shared(); } template bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_shared_until(__clock_t::now() + __rel_time); } #if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK // Exclusive ownership template bool try_lock_until(const chrono::time_point<__clock_t, _Duration>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; int __ret = pthread_rwlock_timedwrlock(&_M_rwlock, &__ts); // On self-deadlock, we just fail to acquire the lock. Technically, // the program violated the precondition. if (__ret == ETIMEDOUT || __ret == EDEADLK) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __abs_time - __c_entry; const auto __s_atime = __s_entry + __delta; return try_lock_until(__s_atime); } // Shared ownership template bool try_lock_shared_until(const chrono::time_point<__clock_t, _Duration>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; int __ret; // Unlike for lock(), we are not allowed to throw an exception so if // the maximum number of read locks has been exceeded, or we would // deadlock, we just try to acquire the lock again (and will time out // eventually). // In cases where we would exceed the maximum number of read locks // throughout the whole time until the timeout, we will fail to // acquire the lock even if it would be logically free; however, this // is allowed by the standard, and we made a "strong effort" // (see C++14 30.4.1.4p26). // For cases where the implementation detects a deadlock we // intentionally block and timeout so that an early return isn't // mistaken for a spurious failure, which might help users realise // there is a deadlock. do __ret = pthread_rwlock_timedrdlock(&_M_rwlock, &__ts); while (__ret == EAGAIN || __ret == EDEADLK); if (__ret == ETIMEDOUT) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } template bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __abs_time - __c_entry; const auto __s_atime = __s_entry + __delta; return try_lock_shared_until(__s_atime); } #else // ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK) // Exclusive ownership template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { unique_lock __lk(_M_mut); if (!_M_gate1.wait_until(__lk, __abs_time, [=]{ return !_M_write_entered(); })) { return false; } _M_state |= _S_write_entered; if (!_M_gate2.wait_until(__lk, __abs_time, [=]{ return _M_readers() == 0; })) { _M_state ^= _S_write_entered; // Wake all threads blocked while the write-entered flag was set. _M_gate1.notify_all(); return false; } return true; } // Shared ownership template bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { unique_lock __lk(_M_mut); if (!_M_gate1.wait_until(__lk, __abs_time, [=]{ return _M_state < _S_max_readers; })) { return false; } ++_M_state; return true; } #endif // _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK }; #endif // _GLIBCXX_HAS_GTHREADS /// shared_lock template class shared_lock { public: typedef _Mutex mutex_type; // Shared locking shared_lock() noexcept : _M_pm(nullptr), _M_owns(false) { } explicit shared_lock(mutex_type& __m) : _M_pm(std::__addressof(__m)), _M_owns(true) { __m.lock_shared(); } shared_lock(mutex_type& __m, defer_lock_t) noexcept : _M_pm(std::__addressof(__m)), _M_owns(false) { } shared_lock(mutex_type& __m, try_to_lock_t) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared()) { } shared_lock(mutex_type& __m, adopt_lock_t) : _M_pm(std::__addressof(__m)), _M_owns(true) { } template shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared_until(__abs_time)) { } template shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared_for(__rel_time)) { } ~shared_lock() { if (_M_owns) _M_pm->unlock_shared(); } shared_lock(shared_lock const&) = delete; shared_lock& operator=(shared_lock const&) = delete; shared_lock(shared_lock&& __sl) noexcept : shared_lock() { swap(__sl); } shared_lock& operator=(shared_lock&& __sl) noexcept { shared_lock(std::move(__sl)).swap(*this); return *this; } void lock() { _M_lockable(); _M_pm->lock_shared(); _M_owns = true; } bool try_lock() { _M_lockable(); return _M_owns = _M_pm->try_lock_shared(); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { _M_lockable(); return _M_owns = _M_pm->try_lock_shared_for(__rel_time); } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { _M_lockable(); return _M_owns = _M_pm->try_lock_shared_until(__abs_time); } void unlock() { if (!_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); _M_pm->unlock_shared(); _M_owns = false; } // Setters void swap(shared_lock& __u) noexcept { std::swap(_M_pm, __u._M_pm); std::swap(_M_owns, __u._M_owns); } mutex_type* release() noexcept { _M_owns = false; return std::exchange(_M_pm, nullptr); } // Getters bool owns_lock() const noexcept { return _M_owns; } explicit operator bool() const noexcept { return _M_owns; } mutex_type* mutex() const noexcept { return _M_pm; } private: void _M_lockable() const { if (_M_pm == nullptr) __throw_system_error(int(errc::operation_not_permitted)); if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); } mutex_type* _M_pm; bool _M_owns; }; /// Swap specialization for shared_lock template void swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept { __x.swap(__y); } #endif // _GLIBCXX_USE_C99_STDINT_TR1 // @} group mutexes _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++14 #endif // _GLIBCXX_SHARED_MUTEX PKgd1]G} 8/algorithmnu[// -*- C++ -*- // Copyright (C) 2001-2018 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,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 include/algorithm * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ALGORITHM #define _GLIBCXX_ALGORITHM 1 #pragma GCC system_header #include // UK-300. #include #include #ifdef _GLIBCXX_PARALLEL # include #endif #endif /* _GLIBCXX_ALGORITHM */ PKgd1]3mm8/cwcharnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cwchar * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c wchar.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 21.4 // #pragma GCC system_header #include #if _GLIBCXX_HAVE_WCHAR_H #include #endif #ifndef _GLIBCXX_CWCHAR #define _GLIBCXX_CWCHAR 1 // Need to do a bit of trickery here with mbstate_t as char_traits // assumes it is in wchar.h, regardless of wchar_t specializations. #ifndef _GLIBCXX_HAVE_MBSTATE_T extern "C" { typedef struct { int __fill[6]; } mbstate_t; } #endif namespace std { using ::mbstate_t; } // namespace std // Get rid of those macros defined in in lieu of real functions. #undef btowc #undef fgetwc #undef fgetws #undef fputwc #undef fputws #undef fwide #undef fwprintf #undef fwscanf #undef getwc #undef getwchar #undef mbrlen #undef mbrtowc #undef mbsinit #undef mbsrtowcs #undef putwc #undef putwchar #undef swprintf #undef swscanf #undef ungetwc #undef vfwprintf #if _GLIBCXX_HAVE_VFWSCANF # undef vfwscanf #endif #undef vswprintf #if _GLIBCXX_HAVE_VSWSCANF # undef vswscanf #endif #undef vwprintf #if _GLIBCXX_HAVE_VWSCANF # undef vwscanf #endif #undef wcrtomb #undef wcscat #undef wcschr #undef wcscmp #undef wcscoll #undef wcscpy #undef wcscspn #undef wcsftime #undef wcslen #undef wcsncat #undef wcsncmp #undef wcsncpy #undef wcspbrk #undef wcsrchr #undef wcsrtombs #undef wcsspn #undef wcsstr #undef wcstod #if _GLIBCXX_HAVE_WCSTOF # undef wcstof #endif #undef wcstok #undef wcstol #undef wcstoul #undef wcsxfrm #undef wctob #undef wmemchr #undef wmemcmp #undef wmemcpy #undef wmemmove #undef wmemset #undef wprintf #undef wscanf #if _GLIBCXX_USE_WCHAR_T namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::wint_t; using ::btowc; using ::fgetwc; using ::fgetws; using ::fputwc; using ::fputws; using ::fwide; using ::fwprintf; using ::fwscanf; using ::getwc; using ::getwchar; using ::mbrlen; using ::mbrtowc; using ::mbsinit; using ::mbsrtowcs; using ::putwc; using ::putwchar; #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF using ::swprintf; #endif using ::swscanf; using ::ungetwc; using ::vfwprintf; #if _GLIBCXX_HAVE_VFWSCANF using ::vfwscanf; #endif #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF using ::vswprintf; #endif #if _GLIBCXX_HAVE_VSWSCANF using ::vswscanf; #endif using ::vwprintf; #if _GLIBCXX_HAVE_VWSCANF using ::vwscanf; #endif using ::wcrtomb; using ::wcscat; using ::wcscmp; using ::wcscoll; using ::wcscpy; using ::wcscspn; using ::wcsftime; using ::wcslen; using ::wcsncat; using ::wcsncmp; using ::wcsncpy; using ::wcsrtombs; using ::wcsspn; using ::wcstod; #if _GLIBCXX_HAVE_WCSTOF using ::wcstof; #endif using ::wcstok; using ::wcstol; using ::wcstoul; using ::wcsxfrm; using ::wctob; using ::wmemcmp; using ::wmemcpy; using ::wmemmove; using ::wmemset; using ::wprintf; using ::wscanf; using ::wcschr; using ::wcspbrk; using ::wcsrchr; using ::wcsstr; using ::wmemchr; #ifndef __CORRECT_ISO_CPP_WCHAR_H_PROTO inline wchar_t* wcschr(wchar_t* __p, wchar_t __c) { return wcschr(const_cast(__p), __c); } inline wchar_t* wcspbrk(wchar_t* __s1, const wchar_t* __s2) { return wcspbrk(const_cast(__s1), __s2); } inline wchar_t* wcsrchr(wchar_t* __p, wchar_t __c) { return wcsrchr(const_cast(__p), __c); } inline wchar_t* wcsstr(wchar_t* __s1, const wchar_t* __s2) { return wcsstr(const_cast(__s1), __s2); } inline wchar_t* wmemchr(wchar_t* __p, wchar_t __c, size_t __n) { return wmemchr(const_cast(__p), __c, __n); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99_WCHAR #undef wcstold #undef wcstoll #undef wcstoull namespace __gnu_cxx { #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" long double (wcstold)(const wchar_t * __restrict, wchar_t ** __restrict) throw (); #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::wcstold; #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (wcstoll)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw (); extern "C" unsigned long long int (wcstoull)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw (); #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::wcstoll; using ::wcstoull; #endif } // namespace __gnu_cxx namespace std { using ::__gnu_cxx::wcstold; using ::__gnu_cxx::wcstoll; using ::__gnu_cxx::wcstoull; } // namespace #endif #endif //_GLIBCXX_USE_WCHAR_T #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_WCHAR_T namespace std { #if _GLIBCXX_HAVE_WCSTOF using std::wcstof; #endif #if _GLIBCXX_HAVE_VFWSCANF using std::vfwscanf; #endif #if _GLIBCXX_HAVE_VSWSCANF using std::vswscanf; #endif #if _GLIBCXX_HAVE_VWSCANF using std::vwscanf; #endif #if _GLIBCXX_USE_C99_WCHAR using std::wcstold; using std::wcstoll; using std::wcstoull; #endif } // namespace #endif // _GLIBCXX_USE_WCHAR_T #endif // C++11 #endif PKgd1]l 8/codecvtnu[// -*- C++ -*- // Copyright (C) 2015-2018 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 // . // ISO C++ 14882: 22.5 Standard code conversion facets /** @file include/codecvt * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CODECVT #define _GLIBCXX_CODECVT 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION enum codecvt_mode { consume_header = 4, generate_header = 2, little_endian = 1 }; template class codecvt_utf8 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf8(size_t __refs = 0); ~codecvt_utf8(); }; template class codecvt_utf16 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf16(size_t __refs = 0); ~codecvt_utf16(); }; template class codecvt_utf8_utf16 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf8_utf16(size_t __refs = 0); ~codecvt_utf8_utf16(); }; #define _GLIBCXX_CODECVT_SPECIALIZATION2(_NAME, _ELEM) \ template<> \ class _NAME<_ELEM> \ : public codecvt<_ELEM, char, mbstate_t> \ { \ public: \ typedef _ELEM intern_type; \ typedef char extern_type; \ typedef mbstate_t state_type; \ \ protected: \ _NAME(unsigned long __maxcode, codecvt_mode __mode, size_t __refs) \ : codecvt(__refs), _M_maxcode(__maxcode), _M_mode(__mode) { } \ \ virtual \ ~_NAME(); \ \ virtual result \ do_out(state_type& __state, const intern_type* __from, \ const intern_type* __from_end, const intern_type*& __from_next, \ extern_type* __to, extern_type* __to_end, \ extern_type*& __to_next) const; \ \ virtual result \ do_unshift(state_type& __state, \ extern_type* __to, extern_type* __to_end, \ extern_type*& __to_next) const; \ \ virtual result \ do_in(state_type& __state, \ const extern_type* __from, const extern_type* __from_end, \ const extern_type*& __from_next, \ intern_type* __to, intern_type* __to_end, \ intern_type*& __to_next) const; \ \ virtual \ int do_encoding() const throw(); \ \ virtual \ bool do_always_noconv() const throw(); \ \ virtual \ int do_length(state_type&, const extern_type* __from, \ const extern_type* __end, size_t __max) const; \ \ virtual int \ do_max_length() const throw(); \ \ private: \ unsigned long _M_maxcode; \ codecvt_mode _M_mode; \ } #define _GLIBCXX_CODECVT_SPECIALIZATION(_NAME, _ELEM) \ _GLIBCXX_CODECVT_SPECIALIZATION2(__ ## _NAME ## _base, _ELEM); \ template \ class _NAME<_ELEM, _Maxcode, _Mode> \ : public __ ## _NAME ## _base<_ELEM> \ { \ public: \ explicit \ _NAME(size_t __refs = 0) \ : __ ## _NAME ## _base<_ELEM>(std::min(_Maxcode, 0x10fffful), \ _Mode, __refs) \ { } \ } template class __codecvt_utf8_base; template class __codecvt_utf16_base; template class __codecvt_utf8_utf16_base; _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, char32_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, char32_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, char32_t); #ifdef _GLIBCXX_USE_WCHAR_T _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, wchar_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, wchar_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, wchar_t); #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif #endif /* _GLIBCXX_CODECVT */ PKgd1]"hh 8/sstreamnu[// String based streams -*- C++ -*- // Copyright (C) 1997-2018 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/sstream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.7 String-based streams // #ifndef _GLIBCXX_SSTREAM #define _GLIBCXX_SSTREAM 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 // [27.7.1] template class basic_stringbuf /** * @brief The actual work of input and output (for std::string). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class associates either or both of its input and output sequences * with a sequence of characters, which can be initialized from, or made * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) * * For this class, open modes (of type @c ios_base::openmode) have * @c in set if the input sequence can be read, and @c out set if the * output sequence can be written. */ template class basic_stringbuf : public basic_streambuf<_CharT, _Traits> { struct __xfer_bufptrs; public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef basic_streambuf __streambuf_type; typedef basic_string __string_type; typedef typename __string_type::size_type __size_type; protected: /// Place to stash in || out || in | out settings for current stringbuf. ios_base::openmode _M_mode; // Data Members: __string_type _M_string; public: // Constructors: /** * @brief Starts with an empty string buffer. * @param __mode Whether the buffer can read, or write, or both. * * The default constructor initializes the parent class using its * own default ctor. */ explicit basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) : __streambuf_type(), _M_mode(__mode), _M_string() { } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __mode Whether the buffer can read, or write, or both. * * This constructor initializes the parent class using its * own default ctor. */ explicit basic_stringbuf(const __string_type& __str, ios_base::openmode __mode = ios_base::in | ios_base::out) : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size(), __str.get_allocator()) { _M_stringbuf_init(__mode); } #if __cplusplus >= 201103L basic_stringbuf(const basic_stringbuf&) = delete; basic_stringbuf(basic_stringbuf&& __rhs) : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } // 27.8.2.2 Assign and swap: basic_stringbuf& operator=(const basic_stringbuf&) = delete; basic_stringbuf& operator=(basic_stringbuf&& __rhs) { __xfer_bufptrs __st{__rhs, this}; const __streambuf_type& __base = __rhs; __streambuf_type::operator=(__base); this->pubimbue(__rhs.getloc()); _M_mode = __rhs._M_mode; _M_string = std::move(__rhs._M_string); __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); return *this; } void swap(basic_stringbuf& __rhs) { __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; __xfer_bufptrs __r_st{__rhs, this}; __streambuf_type& __base = __rhs; __streambuf_type::swap(__base); __rhs.pubimbue(this->pubimbue(__rhs.getloc())); std::swap(_M_mode, __rhs._M_mode); std::swap(_M_string, __rhs._M_string); } #endif // Get and set: /** * @brief Copying out the string buffer. * @return A copy of one of the underlying sequences. * * If the buffer is only created in input mode, the underlying * character sequence is equal to the input sequence; otherwise, it * is equal to the output sequence. [27.7.1.2]/1 */ __string_type str() const { __string_type __ret(_M_string.get_allocator()); if (this->pptr()) { // The current egptr() may not be the actual string end. if (this->pptr() > this->egptr()) __ret.assign(this->pbase(), this->pptr()); else __ret.assign(this->pbase(), this->egptr()); } else __ret = _M_string; return __ret; } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Deallocates any previous stored sequence, then copies @a s to * use as a new one. */ void str(const __string_type& __s) { // Cannot use _M_string = __s, since v3 strings are COW // (not always true now but assign() always works). _M_string.assign(__s.data(), __s.size()); _M_stringbuf_init(_M_mode); } protected: // Common initialization code goes here. void _M_stringbuf_init(ios_base::openmode __mode) { _M_mode = __mode; __size_type __len = 0; if (_M_mode & (ios_base::ate | ios_base::app)) __len = _M_string.size(); _M_sync(const_cast(_M_string.data()), 0, __len); } virtual streamsize showmanyc() { streamsize __ret = -1; if (_M_mode & ios_base::in) { _M_update_egptr(); __ret = this->egptr() - this->gptr(); } return __ret; } virtual int_type underflow(); virtual int_type pbackfail(int_type __c = traits_type::eof()); virtual int_type overflow(int_type __c = traits_type::eof()); /** * @brief Manipulates the buffer. * @param __s Pointer to a buffer area. * @param __n Size of @a __s. * @return @c this * * If no buffer has already been created, and both @a __s and @a __n are * non-zero, then @c __s is used as a buffer; see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more. */ virtual __streambuf_type* setbuf(char_type* __s, streamsize __n) { if (__s && __n >= 0) { // This is implementation-defined behavior, and assumes // that an external char_type array of length __n exists // and has been pre-allocated. If this is not the case, // things will quickly blow up. // Step 1: Destroy the current internal array. _M_string.clear(); // Step 2: Use the external array. _M_sync(__s, __n, 0); } return this; } virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type __sp, ios_base::openmode __mode = ios_base::in | ios_base::out); // Internal function for correctly updating the internal buffer // for a particular _M_string, due to initialization or re-sizing // of an existing _M_string. void _M_sync(char_type* __base, __size_type __i, __size_type __o); // Internal function for correctly updating egptr() to the actual // string end. void _M_update_egptr() { const bool __testin = _M_mode & ios_base::in; if (this->pptr() && this->pptr() > this->egptr()) { if (__testin) this->setg(this->eback(), this->gptr(), this->pptr()); else this->setg(this->pptr(), this->pptr(), this->pptr()); } } // Works around the issue with pbump, part of the protected // interface of basic_streambuf, taking just an int. void _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); private: #if __cplusplus >= 201103L #if _GLIBCXX_USE_CXX11_ABI // This type captures the state of the gptr / pptr pointers as offsets // so they can be restored in another object after moving the string. struct __xfer_bufptrs { __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} { const _CharT* const __str = __from._M_string.data(); const _CharT* __end = nullptr; if (__from.eback()) { _M_goff[0] = __from.eback() - __str; _M_goff[1] = __from.gptr() - __str; _M_goff[2] = __from.egptr() - __str; __end = __from.egptr(); } if (__from.pbase()) { _M_poff[0] = __from.pbase() - __str; _M_poff[1] = __from.pptr() - __from.pbase(); _M_poff[2] = __from.epptr() - __str; if (__from.pptr() > __end) __end = __from.pptr(); } // Set _M_string length to the greater of the get and put areas. if (__end) { // The const_cast avoids changing this constructor's signature, // because it is exported from the dynamic library. auto& __mut_from = const_cast(__from); __mut_from._M_string._M_length(__end - __str); } } ~__xfer_bufptrs() { char_type* __str = const_cast(_M_to->_M_string.data()); if (_M_goff[0] != -1) _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); if (_M_poff[0] != -1) _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); } basic_stringbuf* _M_to; off_type _M_goff[3]; off_type _M_poff[3]; }; #else // This type does nothing when using Copy-On-Write strings. struct __xfer_bufptrs { __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } }; #endif // The move constructor initializes an __xfer_bufptrs temporary then // delegates to this constructor to performs moves during its lifetime. basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) : __streambuf_type(static_cast(__rhs)), _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) { } #endif }; // [27.7.2] Template class basic_istringstream /** * @brief Controlling input for std::string. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class supports reading from objects of type std::basic_string, * using the inherited functions from std::basic_istream. To control * the associated sequence, an instance of std::basic_stringbuf is used, * which this page refers to as @c sb. */ template class basic_istringstream : public basic_istream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; typedef basic_istream __istream_type; private: __stringbuf_type _M_stringbuf; public: // Constructors: /** * @brief Default constructor starts with an empty string buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::in is automatically included in @a __mode. * * Initializes @c sb using @c __mode|in, and passes @c &sb to the base * class initializer. Does not allocate any buffer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_istringstream(ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_stringbuf(__mode | ios_base::in) { this->init(&_M_stringbuf); } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::in is automatically included in @a mode. * * Initializes @c sb using @a str and @c mode|in, and passes @c &sb * to the base class initializer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_istringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) { this->init(&_M_stringbuf); } /** * @brief The destructor does nothing. * * The buffer is deallocated by the stringbuf object, not the * formatting stream. */ ~basic_istringstream() { } #if __cplusplus >= 201103L basic_istringstream(const basic_istringstream&) = delete; basic_istringstream(basic_istringstream&& __rhs) : __istream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) { __istream_type::set_rdbuf(&_M_stringbuf); } // 27.8.3.2 Assign and swap: basic_istringstream& operator=(const basic_istringstream&) = delete; basic_istringstream& operator=(basic_istringstream&& __rhs) { __istream_type::operator=(std::move(__rhs)); _M_stringbuf = std::move(__rhs._M_stringbuf); return *this; } void swap(basic_istringstream& __rhs) { __istream_type::swap(__rhs); _M_stringbuf.swap(__rhs._M_stringbuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_stringbuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __stringbuf_type* rdbuf() const { return const_cast<__stringbuf_type*>(&_M_stringbuf); } /** * @brief Copying out the string buffer. * @return @c rdbuf()->str() */ __string_type str() const { return _M_stringbuf.str(); } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Calls @c rdbuf()->str(s). */ void str(const __string_type& __s) { _M_stringbuf.str(__s); } }; // [27.7.3] Template class basic_ostringstream /** * @brief Controlling output for std::string. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class supports writing to objects of type std::basic_string, * using the inherited functions from std::basic_ostream. To control * the associated sequence, an instance of std::basic_stringbuf is used, * which this page refers to as @c sb. */ template class basic_ostringstream : public basic_ostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; typedef basic_ostream __ostream_type; private: __stringbuf_type _M_stringbuf; public: // Constructors/destructor: /** * @brief Default constructor starts with an empty string buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::out is automatically included in @a mode. * * Initializes @c sb using @c mode|out, and passes @c &sb to the base * class initializer. Does not allocate any buffer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_ostringstream(ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_stringbuf(__mode | ios_base::out) { this->init(&_M_stringbuf); } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::out is automatically included in @a mode. * * Initializes @c sb using @a str and @c mode|out, and passes @c &sb * to the base class initializer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_ostringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) { this->init(&_M_stringbuf); } /** * @brief The destructor does nothing. * * The buffer is deallocated by the stringbuf object, not the * formatting stream. */ ~basic_ostringstream() { } #if __cplusplus >= 201103L basic_ostringstream(const basic_ostringstream&) = delete; basic_ostringstream(basic_ostringstream&& __rhs) : __ostream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) { __ostream_type::set_rdbuf(&_M_stringbuf); } // 27.8.3.2 Assign and swap: basic_ostringstream& operator=(const basic_ostringstream&) = delete; basic_ostringstream& operator=(basic_ostringstream&& __rhs) { __ostream_type::operator=(std::move(__rhs)); _M_stringbuf = std::move(__rhs._M_stringbuf); return *this; } void swap(basic_ostringstream& __rhs) { __ostream_type::swap(__rhs); _M_stringbuf.swap(__rhs._M_stringbuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_stringbuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __stringbuf_type* rdbuf() const { return const_cast<__stringbuf_type*>(&_M_stringbuf); } /** * @brief Copying out the string buffer. * @return @c rdbuf()->str() */ __string_type str() const { return _M_stringbuf.str(); } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Calls @c rdbuf()->str(s). */ void str(const __string_type& __s) { _M_stringbuf.str(__s); } }; // [27.7.4] Template class basic_stringstream /** * @brief Controlling input and output for std::string. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class supports reading from and writing to objects of type * std::basic_string, using the inherited functions from * std::basic_iostream. To control the associated sequence, an instance * of std::basic_stringbuf is used, which this page refers to as @c sb. */ template class basic_stringstream : public basic_iostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard Types: typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; typedef basic_iostream __iostream_type; private: __stringbuf_type _M_stringbuf; public: // Constructors/destructors /** * @brief Default constructor starts with an empty string buffer. * @param __m Whether the buffer can read, or write, or both. * * Initializes @c sb using the mode from @c __m, and passes @c * &sb to the base class initializer. Does not allocate any * buffer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) : __iostream_type(), _M_stringbuf(__m) { this->init(&_M_stringbuf); } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __m Whether the buffer can read, or write, or both. * * Initializes @c sb using @a __str and @c __m, and passes @c &sb * to the base class initializer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_stringstream(const __string_type& __str, ios_base::openmode __m = ios_base::out | ios_base::in) : __iostream_type(), _M_stringbuf(__str, __m) { this->init(&_M_stringbuf); } /** * @brief The destructor does nothing. * * The buffer is deallocated by the stringbuf object, not the * formatting stream. */ ~basic_stringstream() { } #if __cplusplus >= 201103L basic_stringstream(const basic_stringstream&) = delete; basic_stringstream(basic_stringstream&& __rhs) : __iostream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) { __iostream_type::set_rdbuf(&_M_stringbuf); } // 27.8.3.2 Assign and swap: basic_stringstream& operator=(const basic_stringstream&) = delete; basic_stringstream& operator=(basic_stringstream&& __rhs) { __iostream_type::operator=(std::move(__rhs)); _M_stringbuf = std::move(__rhs._M_stringbuf); return *this; } void swap(basic_stringstream& __rhs) { __iostream_type::swap(__rhs); _M_stringbuf.swap(__rhs._M_stringbuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_stringbuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __stringbuf_type* rdbuf() const { return const_cast<__stringbuf_type*>(&_M_stringbuf); } /** * @brief Copying out the string buffer. * @return @c rdbuf()->str() */ __string_type str() const { return _M_stringbuf.str(); } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Calls @c rdbuf()->str(s). */ void str(const __string_type& __s) { _M_stringbuf.str(__s); } }; #if __cplusplus >= 201103L /// Swap specialization for stringbufs. template inline void swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, basic_stringbuf<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } /// Swap specialization for istringstreams. template inline void swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, basic_istringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } /// Swap specialization for ostringstreams. template inline void swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, basic_ostringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } /// Swap specialization for stringstreams. template inline void swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, basic_stringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } #endif _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_SSTREAM */ PKgd1]_"0DD8/decimal/decimalnu[// -*- C++ -*- // Copyright (C) 2009-2018 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 decimal/decimal * This is a Standard C++ Library header. */ // ISO/IEC TR 24733 // Written by Janis Johnson #ifndef _GLIBCXX_DECIMAL #define _GLIBCXX_DECIMAL 1 #pragma GCC system_header #include #ifndef _GLIBCXX_USE_DECIMAL_FLOAT #error This file requires compiler and library support for ISO/IEC TR 24733 \ that is currently not available. #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup decimal Decimal Floating-Point Arithmetic * @ingroup numerics * * Classes and functions for decimal floating-point arithmetic. * @{ */ /** @namespace std::decimal * @brief ISO/IEC TR 24733 Decimal floating-point arithmetic. */ namespace decimal { class decimal32; class decimal64; class decimal128; // 3.2.5 Initialization from coefficient and exponent. static decimal32 make_decimal32(long long __coeff, int __exp); static decimal32 make_decimal32(unsigned long long __coeff, int __exp); static decimal64 make_decimal64(long long __coeff, int __exp); static decimal64 make_decimal64(unsigned long long __coeff, int __exp); static decimal128 make_decimal128(long long __coeff, int __exp); static decimal128 make_decimal128(unsigned long long __coeff, int __exp); /// Non-conforming extension: Conversion to integral type. long long decimal32_to_long_long(decimal32 __d); long long decimal64_to_long_long(decimal64 __d); long long decimal128_to_long_long(decimal128 __d); long long decimal_to_long_long(decimal32 __d); long long decimal_to_long_long(decimal64 __d); long long decimal_to_long_long(decimal128 __d); // 3.2.6 Conversion to generic floating-point type. float decimal32_to_float(decimal32 __d); float decimal64_to_float(decimal64 __d); float decimal128_to_float(decimal128 __d); float decimal_to_float(decimal32 __d); float decimal_to_float(decimal64 __d); float decimal_to_float(decimal128 __d); double decimal32_to_double(decimal32 __d); double decimal64_to_double(decimal64 __d); double decimal128_to_double(decimal128 __d); double decimal_to_double(decimal32 __d); double decimal_to_double(decimal64 __d); double decimal_to_double(decimal128 __d); long double decimal32_to_long_double(decimal32 __d); long double decimal64_to_long_double(decimal64 __d); long double decimal128_to_long_double(decimal128 __d); long double decimal_to_long_double(decimal32 __d); long double decimal_to_long_double(decimal64 __d); long double decimal_to_long_double(decimal128 __d); // 3.2.7 Unary arithmetic operators. decimal32 operator+(decimal32 __rhs); decimal64 operator+(decimal64 __rhs); decimal128 operator+(decimal128 __rhs); decimal32 operator-(decimal32 __rhs); decimal64 operator-(decimal64 __rhs); decimal128 operator-(decimal128 __rhs); // 3.2.8 Binary arithmetic operators. #define _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(_Op, _T1, _T2, _T3) \ _T1 operator _Op(_T2 __lhs, _T3 __rhs); #define _DECLARE_DECIMAL_BINARY_OP_WITH_INT(_Op, _Tp) \ _Tp operator _Op(_Tp __lhs, int __rhs); \ _Tp operator _Op(_Tp __lhs, unsigned int __rhs); \ _Tp operator _Op(_Tp __lhs, long __rhs); \ _Tp operator _Op(_Tp __lhs, unsigned long __rhs); \ _Tp operator _Op(_Tp __lhs, long long __rhs); \ _Tp operator _Op(_Tp __lhs, unsigned long long __rhs); \ _Tp operator _Op(int __lhs, _Tp __rhs); \ _Tp operator _Op(unsigned int __lhs, _Tp __rhs); \ _Tp operator _Op(long __lhs, _Tp __rhs); \ _Tp operator _Op(unsigned long __lhs, _Tp __rhs); \ _Tp operator _Op(long long __lhs, _Tp __rhs); \ _Tp operator _Op(unsigned long long __lhs, _Tp __rhs); _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal128) #undef _DECLARE_DECIMAL_BINARY_OP_WITH_DEC #undef _DECLARE_DECIMAL_BINARY_OP_WITH_INT // 3.2.9 Comparison operators. #define _DECLARE_DECIMAL_COMPARISON(_Op, _Tp) \ bool operator _Op(_Tp __lhs, decimal32 __rhs); \ bool operator _Op(_Tp __lhs, decimal64 __rhs); \ bool operator _Op(_Tp __lhs, decimal128 __rhs); \ bool operator _Op(_Tp __lhs, int __rhs); \ bool operator _Op(_Tp __lhs, unsigned int __rhs); \ bool operator _Op(_Tp __lhs, long __rhs); \ bool operator _Op(_Tp __lhs, unsigned long __rhs); \ bool operator _Op(_Tp __lhs, long long __rhs); \ bool operator _Op(_Tp __lhs, unsigned long long __rhs); \ bool operator _Op(int __lhs, _Tp __rhs); \ bool operator _Op(unsigned int __lhs, _Tp __rhs); \ bool operator _Op(long __lhs, _Tp __rhs); \ bool operator _Op(unsigned long __lhs, _Tp __rhs); \ bool operator _Op(long long __lhs, _Tp __rhs); \ bool operator _Op(unsigned long long __lhs, _Tp __rhs); _DECLARE_DECIMAL_COMPARISON(==, decimal32) _DECLARE_DECIMAL_COMPARISON(==, decimal64) _DECLARE_DECIMAL_COMPARISON(==, decimal128) _DECLARE_DECIMAL_COMPARISON(!=, decimal32) _DECLARE_DECIMAL_COMPARISON(!=, decimal64) _DECLARE_DECIMAL_COMPARISON(!=, decimal128) _DECLARE_DECIMAL_COMPARISON(<, decimal32) _DECLARE_DECIMAL_COMPARISON(<, decimal64) _DECLARE_DECIMAL_COMPARISON(<, decimal128) _DECLARE_DECIMAL_COMPARISON(>=, decimal32) _DECLARE_DECIMAL_COMPARISON(>=, decimal64) _DECLARE_DECIMAL_COMPARISON(>=, decimal128) _DECLARE_DECIMAL_COMPARISON(>, decimal32) _DECLARE_DECIMAL_COMPARISON(>, decimal64) _DECLARE_DECIMAL_COMPARISON(>, decimal128) _DECLARE_DECIMAL_COMPARISON(>=, decimal32) _DECLARE_DECIMAL_COMPARISON(>=, decimal64) _DECLARE_DECIMAL_COMPARISON(>=, decimal128) #undef _DECLARE_DECIMAL_COMPARISON /// 3.2.2 Class decimal32. class decimal32 { public: typedef float __decfloat32 __attribute__((mode(SD))); // 3.2.2.2 Construct/copy/destroy. decimal32() : __val(0.e-101DF) {} // 3.2.2.3 Conversion from floating-point type. explicit decimal32(decimal64 __d64); explicit decimal32(decimal128 __d128); explicit decimal32(float __r) : __val(__r) {} explicit decimal32(double __r) : __val(__r) {} explicit decimal32(long double __r) : __val(__r) {} // 3.2.2.4 Conversion from integral type. decimal32(int __z) : __val(__z) {} decimal32(unsigned int __z) : __val(__z) {} decimal32(long __z) : __val(__z) {} decimal32(unsigned long __z) : __val(__z) {} decimal32(long long __z) : __val(__z) {} decimal32(unsigned long long __z) : __val(__z) {} /// Conforming extension: Conversion from scalar decimal type. decimal32(__decfloat32 __z) : __val(__z) {} #if __cplusplus >= 201103L // 3.2.2.5 Conversion to integral type. // Note: explicit per n3407. explicit operator long long() const { return (long long)__val; } #endif // 3.2.2.6 Increment and decrement operators. decimal32& operator++() { __val += 1; return *this; } decimal32 operator++(int) { decimal32 __tmp = *this; __val += 1; return __tmp; } decimal32& operator--() { __val -= 1; return *this; } decimal32 operator--(int) { decimal32 __tmp = *this; __val -= 1; return __tmp; } // 3.2.2.7 Compound assignment. #define _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(_Op) \ decimal32& operator _Op(decimal32 __rhs); \ decimal32& operator _Op(decimal64 __rhs); \ decimal32& operator _Op(decimal128 __rhs); \ decimal32& operator _Op(int __rhs); \ decimal32& operator _Op(unsigned int __rhs); \ decimal32& operator _Op(long __rhs); \ decimal32& operator _Op(unsigned long __rhs); \ decimal32& operator _Op(long long __rhs); \ decimal32& operator _Op(unsigned long long __rhs); _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(+=) _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(-=) _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(*=) _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(/=) #undef _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT private: __decfloat32 __val; public: __decfloat32 __getval(void) { return __val; } void __setval(__decfloat32 __x) { __val = __x; } }; /// 3.2.3 Class decimal64. class decimal64 { public: typedef float __decfloat64 __attribute__((mode(DD))); // 3.2.3.2 Construct/copy/destroy. decimal64() : __val(0.e-398dd) {} // 3.2.3.3 Conversion from floating-point type. decimal64(decimal32 d32); explicit decimal64(decimal128 d128); explicit decimal64(float __r) : __val(__r) {} explicit decimal64(double __r) : __val(__r) {} explicit decimal64(long double __r) : __val(__r) {} // 3.2.3.4 Conversion from integral type. decimal64(int __z) : __val(__z) {} decimal64(unsigned int __z) : __val(__z) {} decimal64(long __z) : __val(__z) {} decimal64(unsigned long __z) : __val(__z) {} decimal64(long long __z) : __val(__z) {} decimal64(unsigned long long __z) : __val(__z) {} /// Conforming extension: Conversion from scalar decimal type. decimal64(__decfloat64 __z) : __val(__z) {} #if __cplusplus >= 201103L // 3.2.3.5 Conversion to integral type. // Note: explicit per n3407. explicit operator long long() const { return (long long)__val; } #endif // 3.2.3.6 Increment and decrement operators. decimal64& operator++() { __val += 1; return *this; } decimal64 operator++(int) { decimal64 __tmp = *this; __val += 1; return __tmp; } decimal64& operator--() { __val -= 1; return *this; } decimal64 operator--(int) { decimal64 __tmp = *this; __val -= 1; return __tmp; } // 3.2.3.7 Compound assignment. #define _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(_Op) \ decimal64& operator _Op(decimal32 __rhs); \ decimal64& operator _Op(decimal64 __rhs); \ decimal64& operator _Op(decimal128 __rhs); \ decimal64& operator _Op(int __rhs); \ decimal64& operator _Op(unsigned int __rhs); \ decimal64& operator _Op(long __rhs); \ decimal64& operator _Op(unsigned long __rhs); \ decimal64& operator _Op(long long __rhs); \ decimal64& operator _Op(unsigned long long __rhs); _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(+=) _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(-=) _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(*=) _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(/=) #undef _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT private: __decfloat64 __val; public: __decfloat64 __getval(void) { return __val; } void __setval(__decfloat64 __x) { __val = __x; } }; /// 3.2.4 Class decimal128. class decimal128 { public: typedef float __decfloat128 __attribute__((mode(TD))); // 3.2.4.2 Construct/copy/destroy. decimal128() : __val(0.e-6176DL) {} // 3.2.4.3 Conversion from floating-point type. decimal128(decimal32 d32); decimal128(decimal64 d64); explicit decimal128(float __r) : __val(__r) {} explicit decimal128(double __r) : __val(__r) {} explicit decimal128(long double __r) : __val(__r) {} // 3.2.4.4 Conversion from integral type. decimal128(int __z) : __val(__z) {} decimal128(unsigned int __z) : __val(__z) {} decimal128(long __z) : __val(__z) {} decimal128(unsigned long __z) : __val(__z) {} decimal128(long long __z) : __val(__z) {} decimal128(unsigned long long __z) : __val(__z) {} /// Conforming extension: Conversion from scalar decimal type. decimal128(__decfloat128 __z) : __val(__z) {} #if __cplusplus >= 201103L // 3.2.4.5 Conversion to integral type. // Note: explicit per n3407. explicit operator long long() const { return (long long)__val; } #endif // 3.2.4.6 Increment and decrement operators. decimal128& operator++() { __val += 1; return *this; } decimal128 operator++(int) { decimal128 __tmp = *this; __val += 1; return __tmp; } decimal128& operator--() { __val -= 1; return *this; } decimal128 operator--(int) { decimal128 __tmp = *this; __val -= 1; return __tmp; } // 3.2.4.7 Compound assignment. #define _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(_Op) \ decimal128& operator _Op(decimal32 __rhs); \ decimal128& operator _Op(decimal64 __rhs); \ decimal128& operator _Op(decimal128 __rhs); \ decimal128& operator _Op(int __rhs); \ decimal128& operator _Op(unsigned int __rhs); \ decimal128& operator _Op(long __rhs); \ decimal128& operator _Op(unsigned long __rhs); \ decimal128& operator _Op(long long __rhs); \ decimal128& operator _Op(unsigned long long __rhs); _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(+=) _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(-=) _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(*=) _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(/=) #undef _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT private: __decfloat128 __val; public: __decfloat128 __getval(void) { return __val; } void __setval(__decfloat128 __x) { __val = __x; } }; #define _GLIBCXX_USE_DECIMAL_ 1 } // namespace decimal // @} group decimal _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include #endif /* _GLIBCXX_DECIMAL */ PKgd1]\ogBgB8/decimal/decimal.hnu[// decimal classes -*- C++ -*- // Copyright (C) 2009-2018 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 decimal/decimal.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{decimal} */ // ISO/IEC TR 24733 // Written by Janis Johnson #ifndef _GLIBCXX_DECIMAL_IMPL #define _GLIBCXX_DECIMAL_IMPL 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace decimal { // ISO/IEC TR 24733 3.2.[234].1 Construct/copy/destroy. inline decimal32::decimal32(decimal64 __r) : __val(__r.__getval()) {} inline decimal32::decimal32(decimal128 __r) : __val(__r.__getval()) {} inline decimal64::decimal64(decimal32 __r) : __val(__r.__getval()) {} inline decimal64::decimal64(decimal128 __r) : __val(__r.__getval()) {} inline decimal128::decimal128(decimal32 __r) : __val(__r.__getval()) {} inline decimal128::decimal128(decimal64 __r) : __val(__r.__getval()) {} // ISO/IEC TR 24733 3.2.[234].6 Compound assignment. #define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, _T2) \ inline _T1& _T1::operator _Op1(_T2 __rhs) \ { \ __setval(__getval() _Op2 __rhs.__getval()); \ return *this; \ } #define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, _T2) \ inline _T1& _T1::operator _Op1(_T2 __rhs) \ { \ __setval(__getval() _Op2 __rhs); \ return *this; \ } #define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(_Op1, _Op2, _T1) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, decimal32) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, decimal64) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, decimal128) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, int) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, unsigned int) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, long) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, unsigned long)\ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, long long) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, unsigned long long) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal128) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal128) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal128) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal128) #undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC #undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT #undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS // Extension: Conversion to integral type. inline long long decimal32_to_long_long(decimal32 __d) { return (long long)__d.__getval(); } inline long long decimal64_to_long_long(decimal64 __d) { return (long long)__d.__getval(); } inline long long decimal128_to_long_long(decimal128 __d) { return (long long)__d.__getval(); } inline long long decimal_to_long_long(decimal32 __d) { return (long long)__d.__getval(); } inline long long decimal_to_long_long(decimal64 __d) { return (long long)__d.__getval(); } inline long long decimal_to_long_long(decimal128 __d) { return (long long)__d.__getval(); } // ISO/IEC TR 24733 3.2.5 Initialization from coefficient and exponent. static decimal32 make_decimal32(long long __coeff, int __exponent) { decimal32 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DF; __exponent = -__exponent; } else __multiplier = 1.E1DF; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal32 make_decimal32(unsigned long long __coeff, int __exponent) { decimal32 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DF; __exponent = -__exponent; } else __multiplier = 1.E1DF; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal64 make_decimal64(long long __coeff, int __exponent) { decimal64 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DD; __exponent = -__exponent; } else __multiplier = 1.E1DD; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal64 make_decimal64(unsigned long long __coeff, int __exponent) { decimal64 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DD; __exponent = -__exponent; } else __multiplier = 1.E1DD; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal128 make_decimal128(long long __coeff, int __exponent) { decimal128 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DL; __exponent = -__exponent; } else __multiplier = 1.E1DL; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal128 make_decimal128(unsigned long long __coeff, int __exponent) { decimal128 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DL; __exponent = -__exponent; } else __multiplier = 1.E1DL; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } // ISO/IEC TR 24733 3.2.6 Conversion to generic floating-point type. inline float decimal32_to_float(decimal32 __d) { return (float)__d.__getval(); } inline float decimal64_to_float(decimal64 __d) { return (float)__d.__getval(); } inline float decimal128_to_float(decimal128 __d) { return (float)__d.__getval(); } inline float decimal_to_float(decimal32 __d) { return (float)__d.__getval(); } inline float decimal_to_float(decimal64 __d) { return (float)__d.__getval(); } inline float decimal_to_float(decimal128 __d) { return (float)__d.__getval(); } inline double decimal32_to_double(decimal32 __d) { return (double)__d.__getval(); } inline double decimal64_to_double(decimal64 __d) { return (double)__d.__getval(); } inline double decimal128_to_double(decimal128 __d) { return (double)__d.__getval(); } inline double decimal_to_double(decimal32 __d) { return (double)__d.__getval(); } inline double decimal_to_double(decimal64 __d) { return (double)__d.__getval(); } inline double decimal_to_double(decimal128 __d) { return (double)__d.__getval(); } inline long double decimal32_to_long_double(decimal32 __d) { return (long double)__d.__getval(); } inline long double decimal64_to_long_double(decimal64 __d) { return (long double)__d.__getval(); } inline long double decimal128_to_long_double(decimal128 __d) { return (long double)__d.__getval(); } inline long double decimal_to_long_double(decimal32 __d) { return (long double)__d.__getval(); } inline long double decimal_to_long_double(decimal64 __d) { return (long double)__d.__getval(); } inline long double decimal_to_long_double(decimal128 __d) { return (long double)__d.__getval(); } // ISO/IEC TR 24733 3.2.7 Unary arithmetic operators. #define _DEFINE_DECIMAL_UNARY_OP(_Op, _Tp) \ inline _Tp operator _Op(_Tp __rhs) \ { \ _Tp __tmp; \ __tmp.__setval(_Op __rhs.__getval()); \ return __tmp; \ } _DEFINE_DECIMAL_UNARY_OP(+, decimal32) _DEFINE_DECIMAL_UNARY_OP(+, decimal64) _DEFINE_DECIMAL_UNARY_OP(+, decimal128) _DEFINE_DECIMAL_UNARY_OP(-, decimal32) _DEFINE_DECIMAL_UNARY_OP(-, decimal64) _DEFINE_DECIMAL_UNARY_OP(-, decimal128) #undef _DEFINE_DECIMAL_UNARY_OP // ISO/IEC TR 24733 3.2.8 Binary arithmetic operators. #define _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(_Op, _T1, _T2, _T3) \ inline _T1 operator _Op(_T2 __lhs, _T3 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs.__getval() _Op __rhs.__getval()); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_BOTH(_Op, _T1, _T2, _T3) \ inline _T1 operator _Op(_T2 __lhs, _T3 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs.__getval() _Op __rhs.__getval()); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, _T2) \ inline _T1 operator _Op(_T1 __lhs, _T2 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs.__getval() _Op __rhs); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, _T2) \ inline _T1 operator _Op(_T2 __lhs, _T1 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs _Op __rhs.__getval()); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_WITH_INT(_Op, _T1) \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, int); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, unsigned int); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, long); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, unsigned long); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, long long); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, unsigned long long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, int); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, unsigned int); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, unsigned long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, long long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, unsigned long long); \ _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal128) #undef _DEFINE_DECIMAL_BINARY_OP_WITH_DEC #undef _DEFINE_DECIMAL_BINARY_OP_BOTH #undef _DEFINE_DECIMAL_BINARY_OP_LHS #undef _DEFINE_DECIMAL_BINARY_OP_RHS #undef _DEFINE_DECIMAL_BINARY_OP_WITH_INT // ISO/IEC TR 24733 3.2.9 Comparison operators. #define _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _T1, _T2) \ inline bool operator _Op(_T1 __lhs, _T2 __rhs) \ { return __lhs.__getval() _Op __rhs.__getval(); } #define _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _T1, _T2) \ inline bool operator _Op(_T1 __lhs, _T2 __rhs) \ { return __lhs.__getval() _Op __rhs; } #define _DEFINE_DECIMAL_COMPARISON_RHS(_Op, _T1, _T2) \ inline bool operator _Op(_T1 __lhs, _T2 __rhs) \ { return __lhs _Op __rhs.__getval(); } #define _DEFINE_DECIMAL_COMPARISONS(_Op, _Tp) \ _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal32) \ _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal64) \ _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal128) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, int) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned int) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, long) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned long) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, long long) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned long long) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, int, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned int, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, long, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned long, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, long long, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned long long, _Tp) _DEFINE_DECIMAL_COMPARISONS(==, decimal32) _DEFINE_DECIMAL_COMPARISONS(==, decimal64) _DEFINE_DECIMAL_COMPARISONS(==, decimal128) _DEFINE_DECIMAL_COMPARISONS(!=, decimal32) _DEFINE_DECIMAL_COMPARISONS(!=, decimal64) _DEFINE_DECIMAL_COMPARISONS(!=, decimal128) _DEFINE_DECIMAL_COMPARISONS(<, decimal32) _DEFINE_DECIMAL_COMPARISONS(<, decimal64) _DEFINE_DECIMAL_COMPARISONS(<, decimal128) _DEFINE_DECIMAL_COMPARISONS(<=, decimal32) _DEFINE_DECIMAL_COMPARISONS(<=, decimal64) _DEFINE_DECIMAL_COMPARISONS(<=, decimal128) _DEFINE_DECIMAL_COMPARISONS(>, decimal32) _DEFINE_DECIMAL_COMPARISONS(>, decimal64) _DEFINE_DECIMAL_COMPARISONS(>, decimal128) _DEFINE_DECIMAL_COMPARISONS(>=, decimal32) _DEFINE_DECIMAL_COMPARISONS(>=, decimal64) _DEFINE_DECIMAL_COMPARISONS(>=, decimal128) #undef _DEFINE_DECIMAL_COMPARISON_BOTH #undef _DEFINE_DECIMAL_COMPARISON_LHS #undef _DEFINE_DECIMAL_COMPARISON_RHS #undef _DEFINE_DECIMAL_COMPARISONS } // namespace decimal _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _GLIBCXX_DECIMAL_IMPL */ PKgd1]+8/tr2/bool_setnu[// TR2 -*- C++ -*- // Copyright (C) 2009-2018 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 tr2/bool_set * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_BOOL_SET #define _GLIBCXX_TR2_BOOL_SET 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * bool_set * * See N2136, Bool_set: multi-valued logic * by Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion. * * The implicit conversion to bool is slippery! I may use the new * explicit conversion. This has been specialized in the language * so that in contexts requiring a bool the conversion happens * implicitly. Thus most objections should be eliminated. */ class bool_set { public: /// Default constructor. constexpr bool_set() : _M_b(_S_false) { } /// Constructor from bool. constexpr bool_set(bool __t) : _M_b(_Bool_set_val(__t)) { } // I'm not sure about this. bool contains(bool_set __b) const { return this->is_singleton() && this->equals(__b); } /// Return true if states are equal. bool equals(bool_set __b) const { return __b._M_b == _M_b; } /// Return true if this is empty. bool is_emptyset() const { return _M_b == _S_empty; } /// Return true if this is indeterminate. bool is_indeterminate() const { return _M_b == _S_indet; } /// Return true if this is false or true (normal boolean). bool is_singleton() const { return _M_b == _S_false || _M_b == _S_true_; } /// Conversion to bool. //explicit operator bool() const { if (! is_singleton()) throw std::bad_cast(); return _M_b; } /// static bool_set indeterminate() { bool_set __b; __b._M_b = _S_indet; return __b; } /// static bool_set emptyset() { bool_set __b; __b._M_b = _S_empty; return __b; } friend bool_set operator!(bool_set __b) { return __b._M_not(); } friend bool_set operator^(bool_set __s, bool_set __t) { return __s._M_xor(__t); } friend bool_set operator|(bool_set __s, bool_set __t) { return __s._M_or(__t); } friend bool_set operator&(bool_set __s, bool_set __t) { return __s._M_and(__t); } friend bool_set operator==(bool_set __s, bool_set __t) { return __s._M_eq(__t); } // These overloads replace the facet additions in the paper! template friend std::basic_ostream& operator<<(std::basic_ostream& __out, bool_set __b) { int __a = __b._M_b; __out << __a; } template friend std::basic_istream& operator>>(std::basic_istream& __in, bool_set& __b) { long __c; __in >> __c; if (__c >= _S_false && __c < _S_empty) __b._M_b = static_cast<_Bool_set_val>(__c); } private: /// enum _Bool_set_val: unsigned char { _S_false = 0, _S_true_ = 1, _S_indet = 2, _S_empty = 3 }; /// Bool set state. _Bool_set_val _M_b; /// bool_set(_Bool_set_val __c) : _M_b(__c) { } /// bool_set _M_not() const { return _S_not[this->_M_b]; } /// bool_set _M_xor(bool_set __b) const { return _S_xor[this->_M_b][__b._M_b]; } /// bool_set _M_or(bool_set __b) const { return _S_or[this->_M_b][__b._M_b]; } /// bool_set _M_and(bool_set __b) const { return _S_and[this->_M_b][__b._M_b]; } /// bool_set _M_eq(bool_set __b) const { return _S_eq[this->_M_b][__b._M_b]; } /// static _Bool_set_val _S_not[4]; /// static _Bool_set_val _S_xor[4][4]; /// static _Bool_set_val _S_or[4][4]; /// static _Bool_set_val _S_and[4][4]; /// static _Bool_set_val _S_eq[4][4]; }; // 20.2.3.2 bool_set values inline bool contains(bool_set __s, bool_set __t) { return __s.contains(__t); } inline bool equals(bool_set __s, bool_set __t) { return __s.equals(__t); } inline bool is_emptyset(bool_set __b) { return __b.is_emptyset(); } inline bool is_indeterminate(bool_set __b) { return __b.is_indeterminate(); } inline bool is_singleton(bool_set __b) { return __b.is_singleton(); } inline bool certainly(bool_set __b) { return ! __b.contains(false); } inline bool possibly(bool_set __b) { return __b.contains(true); } // 20.2.3.3 bool_set set operations inline bool_set set_union(bool __s, bool_set __t) { return bool_set(__s) | __t; } inline bool_set set_union(bool_set __s, bool __t) { return __s | bool_set(__t); } inline bool_set set_union(bool_set __s, bool_set __t) { return __s | __t; } inline bool_set set_intersection(bool __s, bool_set __t) { return bool_set(__s) & __t; } inline bool_set set_intersection(bool_set __s, bool __t) { return __s & bool_set(__t); } inline bool_set set_intersection(bool_set __s, bool_set __t) { return __s & __t; } inline bool_set set_complement(bool_set __b) { return ! __b; } // 20.2.3.4 bool_set logical operators inline bool_set operator^(bool __s, bool_set __t) { return bool_set(__s) ^ __t; } inline bool_set operator^(bool_set __s, bool __t) { return __s ^ bool_set(__t); } inline bool_set operator|(bool __s, bool_set __t) { return bool_set(__s) | __t; } inline bool_set operator|(bool_set __s, bool __t) { return __s | bool_set(__t); } inline bool_set operator&(bool __s, bool_set __t) { return bool_set(__s) & __t; } inline bool_set operator&(bool_set __s, bool __t) { return __s & bool_set(__t); } // 20.2.3.5 bool_set relational operators inline bool_set operator==(bool __s, bool_set __t) { return bool_set(__s) == __t; } inline bool_set operator==(bool_set __s, bool __t) { return __s == bool_set(__t); } inline bool_set operator!=(bool __s, bool_set __t) { return ! (__s == __t); } inline bool_set operator!=(bool_set __s, bool __t) { return ! (__s == __t); } inline bool_set operator!=(bool_set __s, bool_set __t) { return ! (__s == __t); } } _GLIBCXX_END_NAMESPACE_VERSION } #include #endif // _GLIBCXX_TR2_BOOL_SET PKgd1]s8/tr2/dynamic_bitsetnu[// TR2 -*- C++ -*- // Copyright (C) 2009-2018 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 tr2/dynamic_bitset * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_DYNAMIC_BITSET #define _GLIBCXX_TR2_DYNAMIC_BITSET 1 #pragma GCC system_header #include #include #include #include #include #include // For fill #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * @defgroup dynamic_bitset Dynamic Bitset. * @ingroup extensions * * @{ */ /** * Base class, general case. * * See documentation for dynamic_bitset. */ template> struct __dynamic_bitset_base { static_assert(std::is_unsigned<_WordT>::value, "template argument " "_WordT not an unsigned integral type"); typedef _WordT block_type; typedef _Alloc allocator_type; typedef size_t size_type; static const size_type _S_bits_per_block = __CHAR_BIT__ * sizeof(block_type); static const size_type npos = static_cast(-1); /// 0 is the least significant word. std::vector _M_w; explicit __dynamic_bitset_base(const allocator_type& __alloc) : _M_w(__alloc) { } __dynamic_bitset_base() = default; __dynamic_bitset_base(const __dynamic_bitset_base&) = default; __dynamic_bitset_base(__dynamic_bitset_base&& __b) = default; __dynamic_bitset_base& operator=(const __dynamic_bitset_base&) = default; __dynamic_bitset_base& operator=(__dynamic_bitset_base&&) = default; ~__dynamic_bitset_base() = default; explicit __dynamic_bitset_base(size_type __nbits, unsigned long long __val = 0ULL, const allocator_type& __alloc = allocator_type()) : _M_w(__nbits / _S_bits_per_block + (__nbits % _S_bits_per_block > 0), block_type(0), __alloc) { if (__nbits < std::numeric_limits::digits) __val &= ~(-1ULL << __nbits); if (__val == 0) return; if _GLIBCXX17_CONSTEXPR (sizeof(__val) == sizeof(block_type)) _M_w[0] = __val; else { const size_t __n = std::min(_M_w.size(), sizeof(__val) / sizeof(block_type)); for (size_t __i = 0; __val && __i < __n; ++__i) { _M_w[__i] = static_cast(__val); __val >>= _S_bits_per_block; } } } void _M_swap(__dynamic_bitset_base& __b) noexcept { this->_M_w.swap(__b._M_w); } void _M_clear() noexcept { this->_M_w.clear(); } void _M_resize(size_t __nbits, bool __value) { size_t __sz = __nbits / _S_bits_per_block; if (__nbits % _S_bits_per_block > 0) ++__sz; if (__sz != this->_M_w.size()) { block_type __val = 0; if (__value) __val = std::numeric_limits::max(); this->_M_w.resize(__sz, __val); } } allocator_type _M_get_allocator() const noexcept { return this->_M_w.get_allocator(); } static size_type _S_whichword(size_type __pos) noexcept { return __pos / _S_bits_per_block; } static size_type _S_whichbyte(size_type __pos) noexcept { return (__pos % _S_bits_per_block) / __CHAR_BIT__; } static size_type _S_whichbit(size_type __pos) noexcept { return __pos % _S_bits_per_block; } static block_type _S_maskbit(size_type __pos) noexcept { return (static_cast(1)) << _S_whichbit(__pos); } block_type& _M_getword(size_type __pos) noexcept { return this->_M_w[_S_whichword(__pos)]; } block_type _M_getword(size_type __pos) const noexcept { return this->_M_w[_S_whichword(__pos)]; } block_type& _M_hiword() noexcept { return this->_M_w[_M_w.size() - 1]; } block_type _M_hiword() const noexcept { return this->_M_w[_M_w.size() - 1]; } void _M_do_and(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] &= __x._M_w[__i]; else return; } void _M_do_or(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] |= __x._M_w[__i]; else return; } void _M_do_xor(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] ^= __x._M_w[__i]; else return; } void _M_do_dif(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] &= ~__x._M_w[__i]; else return; } void _M_do_left_shift(size_t __shift); void _M_do_right_shift(size_t __shift); void _M_do_flip() noexcept { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] = ~this->_M_w[__i]; } void _M_do_set() noexcept { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] = static_cast(-1); } void _M_do_reset() noexcept { std::fill(_M_w.begin(), _M_w.end(), static_cast(0)); } bool _M_is_equal(const __dynamic_bitset_base& __x) const noexcept { if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != __x._M_w[__i]) return false; return true; } else return false; } bool _M_is_less(const __dynamic_bitset_base& __x) const noexcept { if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = this->_M_w.size(); __i > 0; --__i) { if (this->_M_w[__i-1] < __x._M_w[__i-1]) return true; else if (this->_M_w[__i-1] > __x._M_w[__i-1]) return false; } return false; } else return false; } size_t _M_are_all_aux() const noexcept { for (size_t __i = 0; __i < this->_M_w.size() - 1; ++__i) if (_M_w[__i] != static_cast(-1)) return 0; return ((this->_M_w.size() - 1) * _S_bits_per_block + __builtin_popcountll(this->_M_hiword())); } bool _M_is_any() const noexcept { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != static_cast(0)) return true; return false; } bool _M_is_subset_of(const __dynamic_bitset_base& __b) noexcept { if (__b._M_w.size() == this->_M_w.size()) { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i])) return false; return true; } else return false; } bool _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const noexcept { if (this->is_subset_of(__b)) { if (*this == __b) return false; else return true; } else return false; } size_t _M_do_count() const noexcept { size_t __result = 0; for (size_t __i = 0; __i < this->_M_w.size(); ++__i) __result += __builtin_popcountll(this->_M_w[__i]); return __result; } size_type _M_size() const noexcept { return this->_M_w.size(); } unsigned long _M_do_to_ulong() const; unsigned long long _M_do_to_ullong() const; // find first "on" bit size_type _M_do_find_first(size_t __not_found) const; // find the next "on" bit that follows "prev" size_type _M_do_find_next(size_t __prev, size_t __not_found) const; // do append of block void _M_do_append_block(block_type __block, size_type __pos) { size_t __offset = __pos % _S_bits_per_block; if (__offset == 0) this->_M_w.push_back(__block); else { this->_M_hiword() |= (__block << __offset); this->_M_w.push_back(__block >> (_S_bits_per_block - __offset)); } } }; /** * @brief The %dynamic_bitset class represents a sequence of bits. * * See N2050, * Proposal to Add a Dynamically Sizeable Bitset to the Standard Library. * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2050.pdf * * In the general unoptimized case, storage is allocated in * word-sized blocks. Let B be the number of bits in a word, then * (Nb+(B-1))/B words will be used for storage. B - Nb%B bits are * unused. (They are the high-order bits in the highest word.) It * is a class invariant that those unused bits are always zero. * * If you think of %dynamic_bitset as "a simple array of bits," be * aware that your mental picture is reversed: a %dynamic_bitset * behaves the same way as bits in integers do, with the bit at * index 0 in the "least significant / right-hand" position, and * the bit at index Nb-1 in the "most significant / left-hand" * position. Thus, unlike other containers, a %dynamic_bitset's * index "counts from right to left," to put it very loosely. * * This behavior is preserved when translating to and from strings. * For example, the first line of the following program probably * prints "b('a') is 0001100001" on a modern ASCII system. * * @code * #include * #include * #include * * using namespace std; * * int main() * { * long a = 'a'; * dynamic_bitset<> b(a); * * cout << "b('a') is " << b << endl; * * ostringstream s; * s << b; * string str = s.str(); * cout << "index 3 in the string is " << str[3] << " but\n" * << "index 3 in the bitset is " << b[3] << endl; * } * @endcode * * Most of the actual code isn't contained in %dynamic_bitset<> * itself, but in the base class __dynamic_bitset_base. The base * class works with whole words, not with individual bits. This * allows us to specialize __dynamic_bitset_base for the important * special case where the %dynamic_bitset is only a single word. * * Extra confusion can result due to the fact that the storage for * __dynamic_bitset_base @e is a vector, and is indexed as such. This is * carefully encapsulated. */ template> class dynamic_bitset : private __dynamic_bitset_base<_WordT, _Alloc> { static_assert(std::is_unsigned<_WordT>::value, "template argument " "_WordT not an unsigned integral type"); public: typedef __dynamic_bitset_base<_WordT, _Alloc> _Base; typedef _WordT block_type; typedef _Alloc allocator_type; typedef size_t size_type; static const size_type bits_per_block = __CHAR_BIT__ * sizeof(block_type); // Use this: constexpr size_type std::numeric_limits::max(). static const size_type npos = static_cast(-1); private: // Clear the unused bits in the uppermost word. void _M_do_sanitize() { size_type __shift = this->_M_Nb % bits_per_block; if (__shift > 0) this->_M_hiword() &= block_type(~(block_type(-1) << __shift)); } // Set the unused bits in the uppermost word. void _M_do_fill() { size_type __shift = this->_M_Nb % bits_per_block; if (__shift > 0) this->_M_hiword() |= block_type(block_type(-1) << __shift); } /** * These versions of single-bit set, reset, flip, and test * do no range checking. */ dynamic_bitset& _M_unchecked_set(size_type __pos) noexcept { this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); return *this; } dynamic_bitset& _M_unchecked_set(size_type __pos, int __val) noexcept { if (__val) this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); else this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } dynamic_bitset& _M_unchecked_reset(size_type __pos) noexcept { this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } dynamic_bitset& _M_unchecked_flip(size_type __pos) noexcept { this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); return *this; } bool _M_unchecked_test(size_type __pos) const noexcept { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) != static_cast<_WordT>(0)); } size_type _M_Nb = 0; public: /** * This encapsulates the concept of a single bit. An instance * of this class is a proxy for an actual bit; this way the * individual bit operations are done as faster word-size * bitwise instructions. * * Most users will never need to use this class directly; * conversions to and from bool are automatic and should be * transparent. Overloaded operators help to preserve the * illusion. * * (On a typical system, this "bit %reference" is 64 times the * size of an actual bit. Ha.) */ class reference { friend class dynamic_bitset; block_type *_M_wp; size_type _M_bpos; public: reference(dynamic_bitset& __b, size_type __pos) noexcept { this->_M_wp = &__b._M_getword(__pos); this->_M_bpos = _Base::_S_whichbit(__pos); } // For b[i] = __x; reference& operator=(bool __x) noexcept { if (__x) *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); else *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); return *this; } // For b[i] = b[__j]; reference& operator=(const reference& __j) noexcept { if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); else *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); return *this; } // Flips the bit bool operator~() const noexcept { return (*(_M_wp) & _Base::_S_maskbit(this->_M_bpos)) == 0; } // For __x = b[i]; operator bool() const noexcept { return (*(this->_M_wp) & _Base::_S_maskbit(this->_M_bpos)) != 0; } // For b[i].flip(); reference& flip() noexcept { *this->_M_wp ^= _Base::_S_maskbit(this->_M_bpos); return *this; } }; friend class reference; typedef bool const_reference; // 23.3.5.1 constructors: /// All bits set to zero. dynamic_bitset() = default; /// All bits set to zero. explicit dynamic_bitset(const allocator_type& __alloc) : _Base(__alloc) { } /// Initial bits bitwise-copied from a single word (others set to zero). explicit dynamic_bitset(size_type __nbits, unsigned long long __val = 0ULL, const allocator_type& __alloc = allocator_type()) : _Base(__nbits, __val, __alloc), _M_Nb(__nbits) { } dynamic_bitset(initializer_list __il, const allocator_type& __alloc = allocator_type()) : _Base(__alloc) { this->append(__il); } /** * @brief Use a subset of a string. * @param __str A string of '0' and '1' characters. * @param __pos Index of the first character in @p __str to use. * @param __n The number of characters to copy. * @param __zero The character to use for unset bits. * @param __one The character to use for set bits. * @param __alloc An allocator. * @throw std::out_of_range If @p __pos is bigger the size of @p __str. * @throw std::invalid_argument If a character appears in the string * which is neither '0' nor '1'. */ template explicit dynamic_bitset(const std::basic_string<_CharT, _Traits, _Alloc1>& __str, typename basic_string<_CharT,_Traits,_Alloc1>::size_type __pos = 0, typename basic_string<_CharT,_Traits,_Alloc1>::size_type __n = std::basic_string<_CharT, _Traits, _Alloc1>::npos, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'), const allocator_type& __alloc = allocator_type()) : _Base(__alloc) { if (__pos > __str.size()) __throw_out_of_range(__N("dynamic_bitset::bitset initial position " "not valid")); // Watch for npos. this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n); this->resize(this->_M_Nb); this->_M_copy_from_string(__str, __pos, __n); } /** * @brief Construct from a string. * @param __str A string of '0' and '1' characters. * @param __alloc An allocator. * @throw std::invalid_argument If a character appears in the string * which is neither '0' nor '1'. */ explicit dynamic_bitset(const char* __str, const allocator_type& __alloc = allocator_type()) : _Base(__builtin_strlen(__str), 0ULL, __alloc), _M_Nb(__builtin_strlen(__str)) { this->_M_copy_from_ptr(__str, _M_Nb, 0, _M_Nb); } /// Copy constructor. dynamic_bitset(const dynamic_bitset&) = default; /// Move constructor. dynamic_bitset(dynamic_bitset&& __b) noexcept : _Base(std::move(__b)), _M_Nb(__b._M_Nb) { __b.clear(); } /// Swap with another bitset. void swap(dynamic_bitset& __b) noexcept { this->_M_swap(__b); std::swap(this->_M_Nb, __b._M_Nb); } /// Copy assignment operator. dynamic_bitset& operator=(const dynamic_bitset&) = default; /// Move assignment operator. dynamic_bitset& operator=(dynamic_bitset&& __b) noexcept(std::is_nothrow_move_assignable<_Base>::value) { static_cast<_Base&>(*this) = static_cast<_Base&&>(__b); _M_Nb = __b._M_Nb; if _GLIBCXX17_CONSTEXPR (std::is_nothrow_move_assignable<_Base>::value) __b._M_Nb = 0; else if (get_allocator() == __b.get_allocator()) __b._M_Nb = 0; return *this; } /** * @brief Return the allocator for the bitset. */ allocator_type get_allocator() const noexcept { return this->_M_get_allocator(); } /** * @brief Resize the bitset. */ void resize(size_type __nbits, bool __value = false) { if (__value) this->_M_do_fill(); this->_M_resize(__nbits, __value); this->_M_Nb = __nbits; this->_M_do_sanitize(); } /** * @brief Clear the bitset. */ void clear() { this->_M_clear(); this->_M_Nb = 0; } /** * @brief Push a bit onto the high end of the bitset. */ void push_back(bool __bit) { if (size_t __offset = this->size() % bits_per_block == 0) this->_M_do_append_block(block_type(0), this->_M_Nb); ++this->_M_Nb; this->_M_unchecked_set(this->_M_Nb, __bit); } // XXX why is there no pop_back() member in the proposal? /** * @brief Append a block. */ void append(block_type __block) { this->_M_do_append_block(__block, this->_M_Nb); this->_M_Nb += bits_per_block; } /** * @brief */ void append(initializer_list __il) { this->append(__il.begin(), __il.end()); } /** * @brief Append an iterator range of blocks. */ template void append(_BlockInputIterator __first, _BlockInputIterator __last) { for (; __first != __last; ++__first) this->append(*__first); } // 23.3.5.2 dynamic_bitset operations: //@{ /** * @brief Operations on dynamic_bitsets. * @param __rhs A same-sized dynamic_bitset. * * These should be self-explanatory. */ dynamic_bitset& operator&=(const dynamic_bitset& __rhs) { this->_M_do_and(__rhs); return *this; } dynamic_bitset& operator&=(dynamic_bitset&& __rhs) { this->_M_do_and(std::move(__rhs)); return *this; } dynamic_bitset& operator|=(const dynamic_bitset& __rhs) { this->_M_do_or(__rhs); return *this; } dynamic_bitset& operator^=(const dynamic_bitset& __rhs) { this->_M_do_xor(__rhs); return *this; } dynamic_bitset& operator-=(const dynamic_bitset& __rhs) { this->_M_do_dif(__rhs); return *this; } //@} //@{ /** * @brief Operations on dynamic_bitsets. * @param __pos The number of places to shift. * * These should be self-explanatory. */ dynamic_bitset& operator<<=(size_type __pos) { if (__builtin_expect(__pos < this->_M_Nb, 1)) { this->_M_do_left_shift(__pos); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } dynamic_bitset& operator>>=(size_type __pos) { if (__builtin_expect(__pos < this->_M_Nb, 1)) { this->_M_do_right_shift(__pos); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } //@} // Set, reset, and flip. /** * @brief Sets every bit to true. */ dynamic_bitset& set() { this->_M_do_set(); this->_M_do_sanitize(); return *this; } /** * @brief Sets a given bit to a particular value. * @param __pos The index of the bit. * @param __val Either true or false, defaults to true. * @throw std::out_of_range If @a __pos is bigger the size of the %set. */ dynamic_bitset& set(size_type __pos, bool __val = true) { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::set")); return this->_M_unchecked_set(__pos, __val); } /** * @brief Sets every bit to false. */ dynamic_bitset& reset() { this->_M_do_reset(); return *this; } /** * @brief Sets a given bit to false. * @param __pos The index of the bit. * @throw std::out_of_range If @a __pos is bigger the size of the %set. * * Same as writing @c set(__pos, false). */ dynamic_bitset& reset(size_type __pos) { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::reset")); return this->_M_unchecked_reset(__pos); } /** * @brief Toggles every bit to its opposite value. */ dynamic_bitset& flip() { this->_M_do_flip(); this->_M_do_sanitize(); return *this; } /** * @brief Toggles a given bit to its opposite value. * @param __pos The index of the bit. * @throw std::out_of_range If @a __pos is bigger the size of the %set. */ dynamic_bitset& flip(size_type __pos) { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::flip")); return this->_M_unchecked_flip(__pos); } /// See the no-argument flip(). dynamic_bitset operator~() const { return dynamic_bitset<_WordT, _Alloc>(*this).flip(); } //@{ /** * @brief Array-indexing support. * @param __pos Index into the %dynamic_bitset. * @return A bool for a 'const %dynamic_bitset'. For non-const * bitsets, an instance of the reference proxy class. * @note These operators do no range checking and throw no * exceptions, as required by DR 11 to the standard. */ reference operator[](size_type __pos) { return reference(*this,__pos); } const_reference operator[](size_type __pos) const { return _M_unchecked_test(__pos); } //@} /** * @brief Returns a numerical interpretation of the %dynamic_bitset. * @return The integral equivalent of the bits. * @throw std::overflow_error If there are too many bits to be * represented in an @c unsigned @c long. */ unsigned long to_ulong() const { return this->_M_do_to_ulong(); } /** * @brief Returns a numerical interpretation of the %dynamic_bitset. * @return The integral equivalent of the bits. * @throw std::overflow_error If there are too many bits to be * represented in an @c unsigned @c long. */ unsigned long long to_ullong() const { return this->_M_do_to_ullong(); } /** * @brief Returns a character interpretation of the %dynamic_bitset. * @return The string equivalent of the bits. * * Note the ordering of the bits: decreasing character positions * correspond to increasing bit positions (see the main class notes for * an example). */ template, typename _Alloc1 = std::allocator<_CharT>> std::basic_string<_CharT, _Traits, _Alloc1> to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const { std::basic_string<_CharT, _Traits, _Alloc1> __result; _M_copy_to_string(__result, __zero, __one); return __result; } // Helper functions for string operations. template, typename _CharT = typename _Traits::char_type> void _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); template void _M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc1>& __str, size_t __pos, size_t __n, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) { _M_copy_from_ptr<_Traits>(__str.data(), __str.size(), __pos, __n, __zero, __one); } template void _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const; /// Returns the number of bits which are set. size_type count() const noexcept { return this->_M_do_count(); } /// Returns the total number of bits. size_type size() const noexcept { return this->_M_Nb; } /// Returns the total number of blocks. size_type num_blocks() const noexcept { return this->_M_size(); } /// Returns true if the dynamic_bitset is empty. bool empty() const noexcept { return (this->_M_Nb == 0); } /// Returns the maximum size of a dynamic_bitset object having the same /// type as *this. /// The real answer is max() * bits_per_block but is likely to overflow. constexpr size_type max_size() noexcept { return std::numeric_limits::max(); } /** * @brief Tests the value of a bit. * @param __pos The index of a bit. * @return The value at @a __pos. * @throw std::out_of_range If @a __pos is bigger the size of the %set. */ bool test(size_type __pos) const { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::test")); return _M_unchecked_test(__pos); } /** * @brief Tests whether all the bits are on. * @return True if all the bits are set. */ bool all() const { return this->_M_are_all_aux() == _M_Nb; } /** * @brief Tests whether any of the bits are on. * @return True if at least one bit is set. */ bool any() const { return this->_M_is_any(); } /** * @brief Tests whether any of the bits are on. * @return True if none of the bits are set. */ bool none() const { return !this->_M_is_any(); } //@{ /// Self-explanatory. dynamic_bitset operator<<(size_type __pos) const { return dynamic_bitset(*this) <<= __pos; } dynamic_bitset operator>>(size_type __pos) const { return dynamic_bitset(*this) >>= __pos; } //@} /** * @brief Finds the index of the first "on" bit. * @return The index of the first bit set, or size() if not found. * @sa find_next */ size_type find_first() const { return this->_M_do_find_first(this->_M_Nb); } /** * @brief Finds the index of the next "on" bit after prev. * @return The index of the next bit set, or size() if not found. * @param __prev Where to start searching. * @sa find_first */ size_type find_next(size_t __prev) const { return this->_M_do_find_next(__prev, this->_M_Nb); } bool is_subset_of(const dynamic_bitset& __b) const { return this->_M_is_subset_of(__b); } bool is_proper_subset_of(const dynamic_bitset& __b) const { return this->_M_is_proper_subset_of(__b); } friend bool operator==(const dynamic_bitset& __lhs, const dynamic_bitset& __rhs) noexcept { return __lhs._M_Nb == __rhs._M_Nb && __lhs._M_is_equal(__rhs); } friend bool operator<(const dynamic_bitset& __lhs, const dynamic_bitset& __rhs) noexcept { return __lhs._M_is_less(__rhs) || __lhs._M_Nb < __rhs._M_Nb; } }; template template inline void dynamic_bitset<_WordT, _Alloc>:: _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, _CharT __zero, _CharT __one) const { __str.assign(_M_Nb, __zero); for (size_t __i = _M_Nb; __i > 0; --__i) if (_M_unchecked_test(__i - 1)) _Traits::assign(__str[_M_Nb - __i], __one); } //@{ /// These comparisons for equality/inequality are, well, @e bitwise. template inline bool operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs > __rhs); } template inline bool operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return __rhs < __lhs; } template inline bool operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs < __rhs); } //@} // 23.3.5.3 bitset operations: //@{ /** * @brief Global bitwise operations on bitsets. * @param __x A bitset. * @param __y A bitset of the same size as @a __x. * @return A new bitset. * * These should be self-explanatory. */ template inline dynamic_bitset<_WordT, _Alloc> operator&(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result &= __y; return __result; } template inline dynamic_bitset<_WordT, _Alloc> operator|(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result |= __y; return __result; } template inline dynamic_bitset<_WordT, _Alloc> operator^(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result ^= __y; return __result; } template inline dynamic_bitset<_WordT, _Alloc> operator-(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result -= __y; return __result; } //@} /// Stream output operator for dynamic_bitset. template inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const dynamic_bitset<_WordT, _Alloc>& __x) { std::basic_string<_CharT, _Traits> __tmp; const ctype<_CharT>& __ct = use_facet>(__os.getloc()); __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); return __os << __tmp; } /** * @} */ } // tr2 _GLIBCXX_END_NAMESPACE_VERSION } // std #include #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */ PKgd1]kD  8/tr2/bool_set.tccnu[// TR2 support files -*- C++ -*- // Copyright (C) 2009-2018 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 tr2/bool_set.tcc * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_BOOL_SET_TCC #define _GLIBCXX_TR2_BOOL_SET_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { bool_set::_Bool_set_val bool_set::_S_not[4] = { _S_true_, _S_false, _S_indet, _S_empty }; bool_set::_Bool_set_val bool_set::_S_xor[4][4] = { { _S_false, _S_true_, _S_indet, _S_empty }, { _S_true_, _S_false, _S_indet, _S_empty }, { _S_indet, _S_indet, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; bool_set::_Bool_set_val bool_set::_S_or[4][4] = { { _S_false, _S_true_, _S_indet, _S_empty }, { _S_true_, _S_true_, _S_true_, _S_empty }, { _S_indet, _S_true_, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; bool_set::_Bool_set_val bool_set::_S_and[4][4] = { { _S_false, _S_false, _S_false, _S_empty }, { _S_false, _S_true_, _S_indet, _S_empty }, { _S_false, _S_indet, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; bool_set::_Bool_set_val bool_set::_S_eq[4][4] = { { _S_true_, _S_false, _S_indet, _S_empty }, { _S_false, _S_true_, _S_indet, _S_empty }, { _S_indet, _S_indet, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; } _GLIBCXX_END_NAMESPACE_VERSION } // I object to these things. // The stuff in locale facets are for basic types. // I think we could hack operator<< and operator>>. /** * @brief Numeric parsing. * * Parses the input stream into the bool @a v. It does so by calling * num_get::do_get(). * * If ios_base::boolalpha is set, attempts to read * ctype::truename() or ctype::falsename(). Sets * @a v to true or false if successful. Sets err to * ios_base::failbit if reading the string fails. Sets err to * ios_base::eofbit if the stream is emptied. * * If ios_base::boolalpha is not set, proceeds as with reading a long, * except if the value is 1, sets @a v to true, if the value is 0, sets * @a v to false, and otherwise set err to ios_base::failbit. * * @param in Start of input stream. * @param end End of input stream. * @param io Source of locale and flags. * @param err Error flags to set. * @param v Value to format and insert. * @return Iterator after reading. iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { return this->do_get(__in, __end, __io, __err, __v); } */ /* template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool_set& __v) const { if (!(__io.flags() & ios_base::boolalpha)) { // Parse bool values as long. // NB: We can't just call do_get(long) here, as it might // refer to a derived class. long __l = -1; __beg = _M_extract_int(__beg, __end, __io, __err, __l); if (__c >= _S_false && __c < _S_empty) __b._M_b = static_cast<_Bool_set_val>(__c); else { // What should we do here? __v = true; __err = ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; } } else { // Parse bool values as alphanumeric. typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); bool __testf = true; bool __testt = true; bool __donef = __lc->_M_falsename_size == 0; bool __donet = __lc->_M_truename_size == 0; bool __testeof = false; size_t __n = 0; while (!__donef || !__donet) { if (__beg == __end) { __testeof = true; break; } const char_type __c = *__beg; if (!__donef) __testf = __c == __lc->_M_falsename[__n]; if (!__testf && __donet) break; if (!__donet) __testt = __c == __lc->_M_truename[__n]; if (!__testt && __donef) break; if (!__testt && !__testf) break; ++__n; ++__beg; __donef = !__testf || __n >= __lc->_M_falsename_size; __donet = !__testt || __n >= __lc->_M_truename_size; } if (__testf && __n == __lc->_M_falsename_size && __n) { __v = false; if (__testt && __n == __lc->_M_truename_size) __err = ios_base::failbit; else __err = __testeof ? ios_base::eofbit : ios_base::goodbit; } else if (__testt && __n == __lc->_M_truename_size && __n) { __v = true; __err = __testeof ? ios_base::eofbit : ios_base::goodbit; } else { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 23. Num_get overflow result. __v = false; __err = ios_base::failbit; if (__testeof) __err |= ios_base::eofbit; } } return __beg; } */ /** * @brief Numeric formatting. * * Formats the boolean @a v and inserts it into a stream. It does so * by calling num_put::do_put(). * * If ios_base::boolalpha is set, writes ctype::truename() or * ctype::falsename(). Otherwise formats @a v as an int. * * @param s Stream to write to. * @param io Source of locale and flags. * @param fill Char_type to use for filling. * @param v Value to format and insert. * @return Iterator after writing. iter_type put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const { return this->do_put(__s, __f, __fill, __v); } */ /* template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, bool_set __v) const { const ios_base::fmtflags __flags = __io.flags(); if ((__flags & ios_base::boolalpha) == 0) { const long __l = __v; __s = _M_insert_int(__s, __io, __fill, __l); } else { typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __name = __v ? __lc->_M_truename : __lc->_M_falsename; int __len = __v ? __lc->_M_truename_size : __lc->_M_falsename_size; const streamsize __w = __io.width(); if (__w > static_cast(__len)) { const streamsize __plen = __w - __len; _CharT* __ps = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen)); char_traits<_CharT>::assign(__ps, __plen, __fill); __io.width(0); if ((__flags & ios_base::adjustfield) == ios_base::left) { __s = std::__write(__s, __name, __len); __s = std::__write(__s, __ps, __plen); } else { __s = std::__write(__s, __ps, __plen); __s = std::__write(__s, __name, __len); } return __s; } __io.width(0); __s = std::__write(__s, __name, __len); } return __s; } */ #endif // _GLIBCXX_TR2_BOOL_SET_TCC PKgd1]FRR 8/tr2/rationu[// TR2 -*- C++ -*- // Copyright (C) 2010-2018 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 tr2/ratio * This is a TR2 C++ Library header. */ #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { template (std::numeric_limits::digits)> struct __safe_lshift { static const intmax_t __value = 0; }; template struct __safe_lshift<_Pn, _Bit, true> { static const intmax_t __value = _Pn << _Bit; }; /// Add binary prefixes (IEC 60027-2 A.2 and ISO/IEC 80000). typedef ratio<__safe_lshift<1, 10>::__value, 1> kibi; typedef ratio<__safe_lshift<1, 20>::__value, 1> mebi; typedef ratio<__safe_lshift<1, 30>::__value, 1> gibi; typedef ratio<__safe_lshift<1, 40>::__value, 1> tebi; typedef ratio<__safe_lshift<1, 50>::__value, 1> pebi; typedef ratio<__safe_lshift<1, 60>::__value, 1> exbi; //typedef ratio<__safe_lshift<1, 70>::__value, 1> zebi; //typedef ratio<__safe_lshift<1, 80>::__value, 1> yobi; } _GLIBCXX_END_NAMESPACE_VERSION } PKgd1]V 8/tr2/type_traitsnu[// TR2 -*- C++ -*- // Copyright (C) 2011-2018 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 tr2/type_traits * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_TYPE_TRAITS #define _GLIBCXX_TR2_TYPE_TRAITS 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * @addtogroup metaprogramming * @{ */ /** * See N2965: Type traits and base classes * by Michael Spertus */ /** * Simple typelist. Compile-time list of types. */ template struct __reflection_typelist; /// Specialization for an empty typelist. template<> struct __reflection_typelist<> { typedef std::true_type empty; }; /// Partial specialization. template struct __reflection_typelist<_First, _Rest...> { typedef std::false_type empty; struct first { typedef _First type; }; struct rest { typedef __reflection_typelist<_Rest...> type; }; }; /// Sequence abstraction metafunctions for manipulating a typelist. /// Enumerate all the base classes of a class. Form of a typelist. template struct bases { typedef __reflection_typelist<__bases(_Tp)...> type; }; /// Enumerate all the direct base classes of a class. Form of a typelist. template struct direct_bases { typedef __reflection_typelist<__direct_bases(_Tp)...> type; }; /// @} group metaprogramming } _GLIBCXX_END_NAMESPACE_VERSION } #endif // _GLIBCXX_TR2_TYPE_TRAITS PKgd1]:B6""8/tr2/dynamic_bitset.tccnu[// TR2 -*- C++ -*- // Copyright (C) 2009-2018 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 tr2/dynamic_bitset.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{tr2/dynamic_bitset} */ #ifndef _GLIBCXX_TR2_DYNAMIC_BITSET_TCC #define _GLIBCXX_TR2_DYNAMIC_BITSET_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { // Definitions of non-inline functions from __dynamic_bitset_base. template void __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift) { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _S_bits_per_block; const size_t __offset = __shift % _S_bits_per_block; if (__offset == 0) for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n) this->_M_w[__n] = this->_M_w[__n - __wshift]; else { const size_t __sub_offset = _S_bits_per_block - __offset; for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n) this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset) | (this->_M_w[__n - __wshift - 1] >> __sub_offset)); this->_M_w[__wshift] = this->_M_w[0] << __offset; } //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift, //// static_cast<_WordT>(0)); } } template void __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift) { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _S_bits_per_block; const size_t __offset = __shift % _S_bits_per_block; const size_t __limit = this->_M_w.size() - __wshift - 1; if (__offset == 0) for (size_t __n = 0; __n <= __limit; ++__n) this->_M_w[__n] = this->_M_w[__n + __wshift]; else { const size_t __sub_offset = (_S_bits_per_block - __offset); for (size_t __n = 0; __n < __limit; ++__n) this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset) | (this->_M_w[__n + __wshift + 1] << __sub_offset)); this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset; } ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(), //// static_cast<_WordT>(0)); } } template unsigned long __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const { size_t __n = sizeof(unsigned long) / sizeof(block_type); for (size_t __i = __n; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i]) __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong")); unsigned long __res = 0UL; for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) __res += this->_M_w[__i] << (__i * _S_bits_per_block); return __res; } template unsigned long long __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const { size_t __n = sizeof(unsigned long long) / sizeof(block_type); for (size_t __i = __n; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i]) __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong")); unsigned long long __res = 0ULL; for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) __res += this->_M_w[__i] << (__i * _S_bits_per_block); return __res; } template size_t __dynamic_bitset_base<_WordT, _Alloc> ::_M_do_find_first(size_t __not_found) const { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) { _WordT __thisword = this->_M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _S_bits_per_block + __builtin_ctzll(__thisword)); } // not found, so return an indication of failure. return __not_found; } template size_t __dynamic_bitset_base<_WordT, _Alloc> ::_M_do_find_next(size_t __prev, size_t __not_found) const { // make bound inclusive ++__prev; // check out of bounds if (__prev >= this->_M_w.size() * _S_bits_per_block) return __not_found; // search first word size_t __i = _S_whichword(__prev); _WordT __thisword = this->_M_w[__i]; // mask off bits below bound __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); if (__thisword != static_cast<_WordT>(0)) return (__i * _S_bits_per_block + __builtin_ctzll(__thisword)); // check subsequent words for (++__i; __i < this->_M_w.size(); ++__i) { __thisword = this->_M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _S_bits_per_block + __builtin_ctzll(__thisword)); } // not found, so return an indication of failure. return __not_found; } // end _M_do_find_next // Definitions of non-inline member functions. template template void dynamic_bitset<_WordT, _Alloc>:: _M_copy_from_ptr(const _CharT* __str, size_t __len, size_t __pos, size_t __n, _CharT __zero, _CharT __one) { reset(); const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos)); for (size_t __i = __nbits; __i > 0; --__i) { const _CharT __c = __str[__pos + __nbits - __i]; if (_Traits::eq(__c, __zero)) ; else if (_Traits::eq(__c, __one)) _M_unchecked_set(__i - 1); else __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr")); } } /** * @brief Stream input operator for dynamic_bitset. * @ingroup dynamic_bitset * * Input will skip whitespace and only accept '0' and '1' characters. * The %dynamic_bitset will grow as necessary to hold the string of bits. */ template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, dynamic_bitset<_WordT, _Alloc>& __x) { typedef typename _Traits::char_type char_type; typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; std::basic_string<_CharT, _Traits> __tmp; __tmp.reserve(__x.size()); const char_type __zero = __is.widen('0'); const char_type __one = __is.widen('1'); typename __ios_base::iostate __state = __ios_base::goodbit; typename __istream_type::sentry __sentry(__is); if (__sentry) { __try { while (1) { static typename _Traits::int_type __eof = _Traits::eof(); typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); if (_Traits::eq_int_type(__c1, __eof)) { __state |= __ios_base::eofbit; break; } else { const char_type __c2 = _Traits::to_char_type(__c1); if (_Traits::eq(__c2, __zero)) __tmp.push_back(__zero); else if (_Traits::eq(__c2, __one)) __tmp.push_back(__one); else if (_Traits:: eq_int_type(__is.rdbuf()->sputbackc(__c2), __eof)) { __state |= __ios_base::failbit; break; } else break; } } } __catch(__cxxabiv1::__forced_unwind&) { __is._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { __is._M_setstate(__ios_base::badbit); } } __x.resize(__tmp.size()); if (__tmp.empty() && __x.size()) __state |= __ios_base::failbit; else __x._M_copy_from_string(__tmp, static_cast(0), __x.size(), __zero, __one); if (__state) __is.setstate(__state); return __is; } } // tr2 _GLIBCXX_END_NAMESPACE_VERSION } // std #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET_TCC */ PKgd1]tS00 8/utilitynu[// -*- C++ -*- // Copyright (C) 2001-2018 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,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 include/utility * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_UTILITY #define _GLIBCXX_UTILITY 1 #pragma GCC system_header /** * @defgroup utilities Utilities * * Components deemed generally useful. Includes pair, tuple, * forward/move helpers, ratio, function object, metaprogramming and * type traits, time, date, and memory functions. */ #include #include #include #if __cplusplus >= 201103L #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Finds the size of a given tuple type. template struct tuple_size; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2313. tuple_size should always derive from integral_constant // 2770. tuple_size specialization is not SFINAE compatible template::type, typename = typename enable_if::value>::type, size_t = tuple_size<_Tp>::value> using __enable_if_has_tuple_size = _Tp; template struct tuple_size> : public tuple_size<_Tp> { }; template struct tuple_size> : public tuple_size<_Tp> { }; template struct tuple_size> : public tuple_size<_Tp> { }; /// Gives the type of the ith element of a given tuple type. template struct tuple_element; // Duplicate of C++14's tuple_element_t for internal use in C++11 mode template using __tuple_element_t = typename tuple_element<__i, _Tp>::type; template struct tuple_element<__i, const _Tp> { typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type; }; template struct tuple_element<__i, volatile _Tp> { typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type; }; template struct tuple_element<__i, const volatile _Tp> { typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type; }; #if __cplusplus > 201103L #define __cpp_lib_tuple_element_t 201402 template using tuple_element_t = typename tuple_element<__i, _Tp>::type; #endif // Various functions which give std::pair a tuple-like interface. /// Partial specialization for std::pair template struct __is_tuple_like_impl> : true_type { }; /// Partial specialization for std::pair template struct tuple_size> : public integral_constant { }; /// Partial specialization for std::pair template struct tuple_element<0, std::pair<_Tp1, _Tp2>> { typedef _Tp1 type; }; /// Partial specialization for std::pair template struct tuple_element<1, std::pair<_Tp1, _Tp2>> { typedef _Tp2 type; }; template struct __pair_get; template<> struct __pair_get<0> { template static constexpr _Tp1& __get(std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } template static constexpr _Tp1&& __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward<_Tp1>(__pair.first); } template static constexpr const _Tp1& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } template static constexpr const _Tp1&& __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward(__pair.first); } }; template<> struct __pair_get<1> { template static constexpr _Tp2& __get(std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } template static constexpr _Tp2&& __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward<_Tp2>(__pair.second); } template static constexpr const _Tp2& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } template static constexpr const _Tp2&& __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward(__pair.second); } }; template constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& get(std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__get(__in); } template constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& get(std::pair<_Tp1, _Tp2>&& __in) noexcept { return __pair_get<_Int>::__move_get(std::move(__in)); } template constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& get(const std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__const_get(__in); } template constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& get(const std::pair<_Tp1, _Tp2>&& __in) noexcept { return __pair_get<_Int>::__const_move_get(std::move(__in)); } #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 template constexpr _Tp& get(pair<_Tp, _Up>& __p) noexcept { return __p.first; } template constexpr const _Tp& get(const pair<_Tp, _Up>& __p) noexcept { return __p.first; } template constexpr _Tp&& get(pair<_Tp, _Up>&& __p) noexcept { return std::move(__p.first); } template constexpr const _Tp&& get(const pair<_Tp, _Up>&& __p) noexcept { return std::move(__p.first); } template constexpr _Tp& get(pair<_Up, _Tp>& __p) noexcept { return __p.second; } template constexpr const _Tp& get(const pair<_Up, _Tp>& __p) noexcept { return __p.second; } template constexpr _Tp&& get(pair<_Up, _Tp>&& __p) noexcept { return std::move(__p.second); } template constexpr const _Tp&& get(const pair<_Up, _Tp>&& __p) noexcept { return std::move(__p.second); } #define __cpp_lib_exchange_function 201304 /// Assign @p __new_val to @p __obj and return its previous value. template inline _Tp exchange(_Tp& __obj, _Up&& __new_val) { return std::__exchange(__obj, std::forward<_Up>(__new_val)); } #endif // Stores a tuple of indices. Used by tuple and pair, and by bind() to // extract the elements in a tuple. template struct _Index_tuple { }; #ifdef __has_builtin # if __has_builtin(__make_integer_seq) # define _GLIBCXX_USE_MAKE_INTEGER_SEQ 1 # endif #endif // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. template struct _Build_index_tuple { #if _GLIBCXX_USE_MAKE_INTEGER_SEQ template using _IdxTuple = _Index_tuple<_Indices...>; using __type = __make_integer_seq<_IdxTuple, size_t, _Num>; #else using __type = _Index_tuple<__integer_pack(_Num)...>; #endif }; #if __cplusplus > 201103L #define __cpp_lib_integer_sequence 201304 /// Class template integer_sequence template struct integer_sequence { typedef _Tp value_type; static constexpr size_t size() noexcept { return sizeof...(_Idx); } }; /// Alias template make_integer_sequence template using make_integer_sequence #if _GLIBCXX_USE_MAKE_INTEGER_SEQ = __make_integer_seq; #else = integer_sequence<_Tp, __integer_pack(_Num)...>; #endif #undef _GLIBCXX_USE_MAKE_INTEGER_SEQ /// Alias template index_sequence template using index_sequence = integer_sequence; /// Alias template make_index_sequence template using make_index_sequence = make_integer_sequence; /// Alias template index_sequence_for template using index_sequence_for = make_index_sequence; #endif #if __cplusplus > 201402L struct in_place_t { explicit in_place_t() = default; }; inline constexpr in_place_t in_place{}; template struct in_place_type_t { explicit in_place_type_t() = default; }; template inline constexpr in_place_type_t<_Tp> in_place_type{}; template struct in_place_index_t { explicit in_place_index_t() = default; }; template inline constexpr in_place_index_t<_Idx> in_place_index{}; template struct __is_in_place_type_impl : false_type { }; template struct __is_in_place_type_impl> : true_type { }; template struct __is_in_place_type : public __is_in_place_type_impl<_Tp> { }; #define __cpp_lib_as_const 201510 template constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; } template void as_const(const _Tp&&) = delete; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif #endif /* _GLIBCXX_UTILITY */ PKgd1] 7Q7Q 8/string_viewnu[// Components for manipulating non-owning sequences of characters -*- C++ -*- // Copyright (C) 2013-2018 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 string_view * This is a Standard C++ Library header. */ // // N3762 basic_string_view library // #ifndef _GLIBCXX_STRING_VIEW #define _GLIBCXX_STRING_VIEW 1 #pragma GCC system_header #if __cplusplus >= 201703L #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_string_view 201603 /** * @class basic_string_view * @brief A non-owning reference to a string. * * @ingroup strings * @ingroup sequences * * @tparam _CharT Type of character * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * A basic_string_view looks like this: * * @code * _CharT* _M_str * size_t _M_len * @endcode */ template> class basic_string_view { public: // types using traits_type = _Traits; using value_type = _CharT; using pointer = const _CharT*; using const_pointer = const _CharT*; using reference = const _CharT&; using const_reference = const _CharT&; using const_iterator = const _CharT*; using iterator = const_iterator; using const_reverse_iterator = std::reverse_iterator; using reverse_iterator = const_reverse_iterator; using size_type = size_t; using difference_type = ptrdiff_t; static constexpr size_type npos = size_type(-1); // [string.view.cons], construct/copy constexpr basic_string_view() noexcept : _M_len{0}, _M_str{nullptr} { } constexpr basic_string_view(const basic_string_view&) noexcept = default; constexpr basic_string_view(const _CharT* __str) noexcept : _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, _M_str{__str} { } constexpr basic_string_view(const _CharT* __str, size_type __len) noexcept : _M_len{__len}, _M_str{__str} { } constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default; // [string.view.iterators], iterators constexpr const_iterator begin() const noexcept { return this->_M_str; } constexpr const_iterator end() const noexcept { return this->_M_str + this->_M_len; } constexpr const_iterator cbegin() const noexcept { return this->_M_str; } constexpr const_iterator cend() const noexcept { return this->_M_str + this->_M_len; } constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(this->end()); } constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(this->begin()); } constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->end()); } constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->begin()); } // [string.view.capacity], capacity constexpr size_type size() const noexcept { return this->_M_len; } constexpr size_type length() const noexcept { return _M_len; } constexpr size_type max_size() const noexcept { return (npos - sizeof(size_type) - sizeof(void*)) / sizeof(value_type) / 4; } [[nodiscard]] constexpr bool empty() const noexcept { return this->_M_len == 0; } // [string.view.access], element access constexpr const _CharT& operator[](size_type __pos) const noexcept { __glibcxx_assert(__pos < this->_M_len); return *(this->_M_str + __pos); } constexpr const _CharT& at(size_type __pos) const { if (__pos >= _M_len) __throw_out_of_range_fmt(__N("basic_string_view::at: __pos " "(which is %zu) >= this->size() " "(which is %zu)"), __pos, this->size()); return *(this->_M_str + __pos); } constexpr const _CharT& front() const noexcept { __glibcxx_assert(this->_M_len > 0); return *this->_M_str; } constexpr const _CharT& back() const noexcept { __glibcxx_assert(this->_M_len > 0); return *(this->_M_str + this->_M_len - 1); } constexpr const _CharT* data() const noexcept { return this->_M_str; } // [string.view.modifiers], modifiers: constexpr void remove_prefix(size_type __n) noexcept { __glibcxx_assert(this->_M_len >= __n); this->_M_str += __n; this->_M_len -= __n; } constexpr void remove_suffix(size_type __n) noexcept { this->_M_len -= __n; } constexpr void swap(basic_string_view& __sv) noexcept { auto __tmp = *this; *this = __sv; __sv = __tmp; } // [string.view.ops], string operations: size_type copy(_CharT* __str, size_type __n, size_type __pos = 0) const { __glibcxx_requires_string_len(__str, __n); __pos = _M_check(__pos, "basic_string_view::copy"); const size_type __rlen = std::min(__n, _M_len - __pos); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2777. basic_string_view::copy should use char_traits::copy traits_type::copy(__str, data() + __pos, __rlen); return __rlen; } constexpr basic_string_view substr(size_type __pos = 0, size_type __n = npos) const noexcept(false) { __pos = _M_check(__pos, "basic_string_view::substr"); const size_type __rlen = std::min(__n, _M_len - __pos); return basic_string_view{_M_str + __pos, __rlen}; } constexpr int compare(basic_string_view __str) const noexcept { const size_type __rlen = std::min(this->_M_len, __str._M_len); int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen); if (__ret == 0) __ret = _S_compare(this->_M_len, __str._M_len); return __ret; } constexpr int compare(size_type __pos1, size_type __n1, basic_string_view __str) const { return this->substr(__pos1, __n1).compare(__str); } constexpr int compare(size_type __pos1, size_type __n1, basic_string_view __str, size_type __pos2, size_type __n2) const { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); } constexpr int compare(const _CharT* __str) const noexcept { return this->compare(basic_string_view{__str}); } constexpr int compare(size_type __pos1, size_type __n1, const _CharT* __str) const { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } constexpr int compare(size_type __pos1, size_type __n1, const _CharT* __str, size_type __n2) const noexcept(false) { return this->substr(__pos1, __n1) .compare(basic_string_view(__str, __n2)); } constexpr size_type find(basic_string_view __str, size_type __pos = 0) const noexcept { return this->find(__str._M_str, __pos, __str._M_len); } constexpr size_type find(_CharT __c, size_type __pos = 0) const noexcept; constexpr size_type find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find(__str, __pos, traits_type::length(__str)); } constexpr size_type rfind(basic_string_view __str, size_type __pos = npos) const noexcept { return this->rfind(__str._M_str, __pos, __str._M_len); } constexpr size_type rfind(_CharT __c, size_type __pos = npos) const noexcept; constexpr size_type rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type rfind(const _CharT* __str, size_type __pos = npos) const noexcept { return this->rfind(__str, __pos, traits_type::length(__str)); } constexpr size_type find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept { return this->find_first_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_first_of(_CharT __c, size_type __pos = 0) const noexcept { return this->find(__c, __pos); } constexpr size_type find_first_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find_first_of(__str, __pos, traits_type::length(__str)); } constexpr size_type find_last_of(basic_string_view __str, size_type __pos = npos) const noexcept { return this->find_last_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_last_of(_CharT __c, size_type __pos=npos) const noexcept { return this->rfind(__c, __pos); } constexpr size_type find_last_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept { return this->find_last_of(__str, __pos, traits_type::length(__str)); } constexpr size_type find_first_not_of(basic_string_view __str, size_type __pos = 0) const noexcept { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; constexpr size_type find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find_first_not_of(__str, __pos, traits_type::length(__str)); } constexpr size_type find_last_not_of(basic_string_view __str, size_type __pos = npos) const noexcept { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; constexpr size_type find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_last_not_of(const _CharT* __str, size_type __pos = npos) const noexcept { return this->find_last_not_of(__str, __pos, traits_type::length(__str)); } constexpr size_type _M_check(size_type __pos, const char* __s) const noexcept(false) { if (__pos > this->size()) __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " "this->size() (which is %zu)"), __s, __pos, this->size()); return __pos; } // NB: _M_limit doesn't check for a bad __pos value. constexpr size_type _M_limit(size_type __pos, size_type __off) const noexcept { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; } private: static constexpr int _S_compare(size_type __n1, size_type __n2) noexcept { const difference_type __diff = __n1 - __n2; if (__diff > std::numeric_limits::max()) return std::numeric_limits::max(); if (__diff < std::numeric_limits::min()) return std::numeric_limits::min(); return static_cast(__diff); } size_t _M_len; const _CharT* _M_str; }; // [string.view.comparison], non-member basic_string_view comparison function namespace __detail { // Identity transform to create a non-deduced context, so that only one // argument participates in template argument deduction and the other // argument gets implicitly converted to the deduced type. See n3766.html. template using __idt = common_type_t<_Tp>; } template constexpr bool operator==(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.size() == __y.size() && __x.compare(__y) == 0; } template constexpr bool operator==(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.size() == __y.size() && __x.compare(__y) == 0; } template constexpr bool operator==(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.size() == __y.size() && __x.compare(__y) == 0; } template constexpr bool operator!=(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return !(__x == __y); } template constexpr bool operator!=(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return !(__x == __y); } template constexpr bool operator!=(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return !(__x == __y); } template constexpr bool operator< (basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) < 0; } template constexpr bool operator< (basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) < 0; } template constexpr bool operator< (__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) < 0; } template constexpr bool operator> (basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) > 0; } template constexpr bool operator> (basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) > 0; } template constexpr bool operator> (__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) > 0; } template constexpr bool operator<=(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) <= 0; } template constexpr bool operator<=(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) <= 0; } template constexpr bool operator<=(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) <= 0; } template constexpr bool operator>=(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) >= 0; } template constexpr bool operator>=(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) >= 0; } template constexpr bool operator>=(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) >= 0; } // [string.view.io], Inserters and extractors template inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT,_Traits> __str) { return __ostream_insert(__os, __str.data(), __str.size()); } // basic_string_view typedef names using string_view = basic_string_view; #ifdef _GLIBCXX_USE_WCHAR_T using wstring_view = basic_string_view; #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 using u16string_view = basic_string_view; using u32string_view = basic_string_view; #endif // [string.view.hash], hash support: template struct hash; template<> struct hash : public __hash_base { size_t operator()(const string_view& __str) const noexcept { return std::_Hash_impl::hash(__str.data(), __str.length()); } }; template<> struct __is_fast_hash> : std::false_type { }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct hash : public __hash_base { size_t operator()(const wstring_view& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); } }; template<> struct __is_fast_hash> : std::false_type { }; #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 template<> struct hash : public __hash_base { size_t operator()(const u16string_view& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char16_t)); } }; template<> struct __is_fast_hash> : std::false_type { }; template<> struct hash : public __hash_base { size_t operator()(const u32string_view& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char32_t)); } }; template<> struct __is_fast_hash> : std::false_type { }; #endif inline namespace literals { inline namespace string_view_literals { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" inline constexpr basic_string_view operator""sv(const char* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } #ifdef _GLIBCXX_USE_WCHAR_T inline constexpr basic_string_view operator""sv(const wchar_t* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 inline constexpr basic_string_view operator""sv(const char16_t* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } inline constexpr basic_string_view operator""sv(const char32_t* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } #endif #pragma GCC diagnostic pop } // namespace string_literals } // namespace literals _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include #endif // __cplusplus <= 201402L #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW PKgd1]3 3 8/cstringnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 cstring * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c string.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CSTRING #define _GLIBCXX_CSTRING 1 // Get rid of those macros defined in in lieu of real functions. #undef memchr #undef memcmp #undef memcpy #undef memmove #undef memset #undef strcat #undef strchr #undef strcmp #undef strcoll #undef strcpy #undef strcspn #undef strerror #undef strlen #undef strncat #undef strncmp #undef strncpy #undef strpbrk #undef strrchr #undef strspn #undef strstr #undef strtok #undef strxfrm namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::memchr; using ::memcmp; using ::memcpy; using ::memmove; using ::memset; using ::strcat; using ::strcmp; using ::strcoll; using ::strcpy; using ::strcspn; using ::strerror; using ::strlen; using ::strncat; using ::strncmp; using ::strncpy; using ::strspn; using ::strtok; using ::strxfrm; using ::strchr; using ::strpbrk; using ::strrchr; using ::strstr; #ifndef __CORRECT_ISO_CPP_STRING_H_PROTO inline void* memchr(void* __s, int __c, size_t __n) { return __builtin_memchr(__s, __c, __n); } inline char* strchr(char* __s, int __n) { return __builtin_strchr(__s, __n); } inline char* strpbrk(char* __s1, const char* __s2) { return __builtin_strpbrk(__s1, __s2); } inline char* strrchr(char* __s, int __n) { return __builtin_strrchr(__s, __n); } inline char* strstr(char* __s1, const char* __s2) { return __builtin_strstr(__s1, __s2); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]K V8/tuplenu[// -*- C++ -*- // Copyright (C) 2007-2018 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/tuple * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TUPLE #define _GLIBCXX_TUPLE 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ template class tuple; template struct __is_empty_non_tuple : is_empty<_Tp> { }; // Using EBO for elements that are tuples causes ambiguous base errors. template struct __is_empty_non_tuple> : false_type { }; // Use the Empty Base-class Optimization for empty, non-final types. template using __empty_not_final = typename conditional<__is_final(_Tp), false_type, __is_empty_non_tuple<_Tp>>::type; template::value> struct _Head_base; template struct _Head_base<_Idx, _Head, true> : public _Head { constexpr _Head_base() : _Head() { } constexpr _Head_base(const _Head& __h) : _Head(__h) { } constexpr _Head_base(const _Head_base&) = default; constexpr _Head_base(_Head_base&&) = default; template constexpr _Head_base(_UHead&& __h) : _Head(std::forward<_UHead>(__h)) { } _Head_base(allocator_arg_t, __uses_alloc0) : _Head() { } template _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) : _Head(allocator_arg, *__a._M_a) { } template _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) : _Head(*__a._M_a) { } template _Head_base(__uses_alloc0, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } static constexpr _Head& _M_head(_Head_base& __b) noexcept { return __b; } static constexpr const _Head& _M_head(const _Head_base& __b) noexcept { return __b; } }; template struct _Head_base<_Idx, _Head, false> { constexpr _Head_base() : _M_head_impl() { } constexpr _Head_base(const _Head& __h) : _M_head_impl(__h) { } constexpr _Head_base(const _Head_base&) = default; constexpr _Head_base(_Head_base&&) = default; template constexpr _Head_base(_UHead&& __h) : _M_head_impl(std::forward<_UHead>(__h)) { } _Head_base(allocator_arg_t, __uses_alloc0) : _M_head_impl() { } template _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) : _M_head_impl(allocator_arg, *__a._M_a) { } template _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) : _M_head_impl(*__a._M_a) { } template _Head_base(__uses_alloc0, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } static constexpr _Head& _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } static constexpr const _Head& _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } _Head _M_head_impl; }; /** * Contains the actual implementation of the @c tuple template, stored * as a recursive inheritance hierarchy from the first element (most * derived class) to the last (least derived class). The @c Idx * parameter gives the 0-based index of the element stored at this * point in the hierarchy; we use it to implement a constant-time * get() operation. */ template struct _Tuple_impl; /** * Recursive tuple implementation. Here we store the @c Head element * and derive from a @c Tuple_impl containing the remaining elements * (which contains the @c Tail). */ template struct _Tuple_impl<_Idx, _Head, _Tail...> : public _Tuple_impl<_Idx + 1, _Tail...>, private _Head_base<_Idx, _Head> { template friend class _Tuple_impl; typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr _Inherited& _M_tail(_Tuple_impl& __t) noexcept { return __t; } static constexpr const _Inherited& _M_tail(const _Tuple_impl& __t) noexcept { return __t; } constexpr _Tuple_impl() : _Inherited(), _Base() { } explicit constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) : _Inherited(__tail...), _Base(__head) { } template::type> explicit constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) : _Inherited(std::forward<_UTail>(__tail)...), _Base(std::forward<_UHead>(__head)) { } constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(__and_, is_nothrow_move_constructible<_Inherited>>::value) : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } template constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a), _Base(__tag, __use_alloc<_Head>(__a)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Head& __head, const _Tail&... __tail) : _Inherited(__tag, __a, __tail...), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template::type> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head, _UTail&&... __tail) : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(__head)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Inherited(__tag, __a, _M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Inherited(__tag, __a, std::move(_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead, _UTails...>& __in) : _Inherited(__tag, __a, _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(__tag, __a, std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { _M_head(*this) = _M_head(__in); _M_tail(*this) = _M_tail(__in); return *this; } _Tuple_impl& operator=(_Tuple_impl&& __in) noexcept(__and_, is_nothrow_move_assignable<_Inherited>>::value) { _M_head(*this) = std::forward<_Head>(_M_head(__in)); _M_tail(*this) = std::move(_M_tail(__in)); return *this; } template _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UElements...>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); return *this; } template _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) { _M_head(*this) = std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); _M_tail(*this) = std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); return *this; } protected: void _M_swap(_Tuple_impl& __in) noexcept(__is_nothrow_swappable<_Head>::value && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) { using std::swap; swap(_M_head(*this), _M_head(__in)); _Inherited::_M_swap(_M_tail(__in)); } }; // Basis case of inheritance recursion. template struct _Tuple_impl<_Idx, _Head> : private _Head_base<_Idx, _Head> { template friend class _Tuple_impl; typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } constexpr _Tuple_impl() : _Base() { } explicit constexpr _Tuple_impl(const _Head& __head) : _Base(__head) { } template explicit constexpr _Tuple_impl(_UHead&& __head) : _Base(std::forward<_UHead>(__head)) { } constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(is_nothrow_move_constructible<_Head>::value) : _Base(std::forward<_Head>(_M_head(__in))) { } template constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Base(__tag, __use_alloc<_Head>(__a)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Head& __head) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(__head)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead>& __in) : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead>&& __in) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { _M_head(*this) = _M_head(__in); return *this; } _Tuple_impl& operator=(_Tuple_impl&& __in) noexcept(is_nothrow_move_assignable<_Head>::value) { _M_head(*this) = std::forward<_Head>(_M_head(__in)); return *this; } template _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UHead>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); return *this; } template _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead>&& __in) { _M_head(*this) = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); return *this; } protected: void _M_swap(_Tuple_impl& __in) noexcept(__is_nothrow_swappable<_Head>::value) { using std::swap; swap(_M_head(*this), _M_head(__in)); } }; // Concept utility functions, reused in conditionally-explicit // constructors. template struct _TC { template static constexpr bool _ConstructibleTuple() { return __and_...>::value; } template static constexpr bool _ImplicitlyConvertibleTuple() { return __and_...>::value; } template static constexpr bool _MoveConstructibleTuple() { return __and_...>::value; } template static constexpr bool _ImplicitlyMoveConvertibleTuple() { return __and_...>::value; } template static constexpr bool _NonNestedTuple() { return __and_<__not_, typename remove_cv< typename remove_reference<_SrcTuple>::type >::type>>, __not_>, __not_> >::value; } template static constexpr bool _NotSameTuple() { return __not_, typename remove_const< typename remove_reference<_UElements...>::type >::type>>::value; } }; template struct _TC { template static constexpr bool _ConstructibleTuple() { return false; } template static constexpr bool _ImplicitlyConvertibleTuple() { return false; } template static constexpr bool _MoveConstructibleTuple() { return false; } template static constexpr bool _ImplicitlyMoveConvertibleTuple() { return false; } template static constexpr bool _NonNestedTuple() { return true; } template static constexpr bool _NotSameTuple() { return true; } }; /// Primary class template, tuple template class tuple : public _Tuple_impl<0, _Elements...> { typedef _Tuple_impl<0, _Elements...> _Inherited; // Used for constraining the default constructor so // that it becomes dependent on the constraints. template struct _TC2 { static constexpr bool _DefaultConstructibleTuple() { return __and_...>::value; } static constexpr bool _ImplicitlyDefaultConstructibleTuple() { return __and_<__is_implicitly_default_constructible<_Elements>...> ::value; } }; public: template:: _ImplicitlyDefaultConstructibleTuple(), bool>::type = true> constexpr tuple() : _Inherited() { } template:: _DefaultConstructibleTuple() && !_TC2<_Dummy>:: _ImplicitlyDefaultConstructibleTuple(), bool>::type = false> explicit constexpr tuple() : _Inherited() { } // Shortcut for the cases where constructors taking _Elements... // need to be constrained. template using _TCC = _TC::value, _Elements...>; template::template _ConstructibleTuple<_Elements...>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(const _Elements&... __elements) : _Inherited(__elements...) { } template::template _ConstructibleTuple<_Elements...>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>() && (sizeof...(_Elements) >= 1), bool>::type=false> explicit constexpr tuple(const _Elements&... __elements) : _Inherited(__elements...) { } // Shortcut for the cases where constructors taking _UElements... // need to be constrained. template using _TMC = _TC<(sizeof...(_Elements) == sizeof...(_UElements)) && (_TC<(sizeof...(_UElements)==1), _Elements...>:: template _NotSameTuple<_UElements...>()), _Elements...>; // Shortcut for the cases where constructors taking tuple<_UElements...> // need to be constrained. template using _TMCT = _TC<(sizeof...(_Elements) == sizeof...(_UElements)) && !is_same, tuple<_UElements...>>::value, _Elements...>; template::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=false> explicit constexpr tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } constexpr tuple(const tuple&) = default; constexpr tuple(tuple&&) = default; // Shortcut for the cases where constructors taking tuples // must avoid creating temporaries. template using _TNTC = _TC::value && sizeof...(_Elements) == 1, _Elements...>; template::template _ConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&>(), bool>::type=true> constexpr tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast&>(__in)) { } template::template _ConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&>(), bool>::type=false> explicit constexpr tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=true> constexpr tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=false> explicit constexpr tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } // Allocator-extended constructors. template tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template::template _ConstructibleTuple<_Elements...>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } template::template _ConstructibleTuple<_Elements...>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } template::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast(__in)) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template::template _ConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template::template _ConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } tuple& operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template typename enable_if::type operator=(const tuple<_UElements...>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } template typename enable_if::type operator=(tuple<_UElements...>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } void swap(tuple& __in) noexcept(noexcept(__in._M_swap(__in))) { _Inherited::_M_swap(__in); } }; #if __cpp_deduction_guides >= 201606 template tuple(_UTypes...) -> tuple<_UTypes...>; template tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; template tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; template tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; template tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; #endif // Explicit specialization, zero-element tuple. template<> class tuple<> { public: void swap(tuple&) noexcept { /* no-op */ } // We need the default since we're going to define no-op // allocator constructors. tuple() = default; // No-op allocator constructors. template tuple(allocator_arg_t, const _Alloc&) { } template tuple(allocator_arg_t, const _Alloc&, const tuple&) { } }; /// Partial specialization, 2-element tuple. /// Includes construction and assignment from a pair. template class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> { typedef _Tuple_impl<0, _T1, _T2> _Inherited; public: template , __is_implicitly_default_constructible<_U2>> ::value, bool>::type = true> constexpr tuple() : _Inherited() { } template , is_default_constructible<_U2>, __not_< __and_<__is_implicitly_default_constructible<_U1>, __is_implicitly_default_constructible<_U2>>>> ::value, bool>::type = false> explicit constexpr tuple() : _Inherited() { } // Shortcut for the cases where constructors taking _T1, _T2 // need to be constrained. template using _TCC = _TC::value, _T1, _T2>; template::template _ConstructibleTuple<_T1, _T2>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type = true> constexpr tuple(const _T1& __a1, const _T2& __a2) : _Inherited(__a1, __a2) { } template::template _ConstructibleTuple<_T1, _T2>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type = false> explicit constexpr tuple(const _T1& __a1, const _T2& __a2) : _Inherited(__a1, __a2) { } // Shortcut for the cases where constructors taking _U1, _U2 // need to be constrained. using _TMC = _TC; template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() && !is_same::type, allocator_arg_t>::value, bool>::type = true> constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() && !is_same::type, allocator_arg_t>::value, bool>::type = false> explicit constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } constexpr tuple(const tuple&) = default; constexpr tuple(tuple&&) = default; template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(const tuple<_U1, _U2>& __in) : _Inherited(static_cast&>(__in)) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(const tuple<_U1, _U2>& __in) : _Inherited(static_cast&>(__in)) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(tuple<_U1, _U2>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(tuple<_U1, _U2>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(const pair<_U1, _U2>& __in) : _Inherited(__in.first, __in.second) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(const pair<_U1, _U2>& __in) : _Inherited(__in.first, __in.second) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(pair<_U1, _U2>&& __in) : _Inherited(std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(pair<_U1, _U2>&& __in) : _Inherited(std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } // Allocator-extended constructors. template tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template::template _ConstructibleTuple<_T1, _T2>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } template::template _ConstructibleTuple<_T1, _T2>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast(__in)) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } tuple& operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template tuple& operator=(const tuple<_U1, _U2>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } template tuple& operator=(tuple<_U1, _U2>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template tuple& operator=(const pair<_U1, _U2>& __in) { this->_M_head(*this) = __in.first; this->_M_tail(*this)._M_head(*this) = __in.second; return *this; } template tuple& operator=(pair<_U1, _U2>&& __in) { this->_M_head(*this) = std::forward<_U1>(__in.first); this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); return *this; } void swap(tuple& __in) noexcept(noexcept(__in._M_swap(__in))) { _Inherited::_M_swap(__in); } }; /// class tuple_size template struct tuple_size> : public integral_constant { }; #if __cplusplus > 201402L template inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; #endif /** * Recursive case for tuple_element: strip off the first element in * the tuple and retrieve the (i-1)th element of the remaining tuple. */ template struct tuple_element<__i, tuple<_Head, _Tail...> > : tuple_element<__i - 1, tuple<_Tail...> > { }; /** * Basis case for tuple_element: The first element is the one we're seeking. */ template struct tuple_element<0, tuple<_Head, _Tail...> > { typedef _Head type; }; /** * Error case for tuple_element: invalid index. */ template struct tuple_element<__i, tuple<>> { static_assert(__i < tuple_size>::value, "tuple index is in range"); }; template constexpr _Head& __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template constexpr const _Head& __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } /// Return a reference to the ith element of a tuple. template constexpr __tuple_element_t<__i, tuple<_Elements...>>& get(tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } /// Return a const reference to the ith element of a const tuple. template constexpr const __tuple_element_t<__i, tuple<_Elements...>>& get(const tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } /// Return an rvalue reference to the ith element of a tuple rvalue. template constexpr __tuple_element_t<__i, tuple<_Elements...>>&& get(tuple<_Elements...>&& __t) noexcept { typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; return std::forward<__element_type&&>(std::get<__i>(__t)); } /// Return a const rvalue reference to the ith element of a const tuple rvalue. template constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& get(const tuple<_Elements...>&& __t) noexcept { typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; return std::forward(std::get<__i>(__t)); } #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 template constexpr _Head& __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template constexpr const _Head& __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } /// Return a reference to the unique element of type _Tp of a tuple. template constexpr _Tp& get(tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } /// Return a reference to the unique element of type _Tp of a tuple rvalue. template constexpr _Tp&& get(tuple<_Types...>&& __t) noexcept { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } /// Return a const reference to the unique element of type _Tp of a tuple. template constexpr const _Tp& get(const tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } /// Return a const reference to the unique element of type _Tp of /// a const tuple rvalue. template constexpr const _Tp&& get(const tuple<_Types...>&& __t) noexcept { return std::forward(std::__get_helper2<_Tp>(__t)); } #endif // This class performs the comparison operations on tuples template struct __tuple_compare { static constexpr bool __eq(const _Tp& __t, const _Up& __u) { return bool(std::get<__i>(__t) == std::get<__i>(__u)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); } static constexpr bool __less(const _Tp& __t, const _Up& __u) { return bool(std::get<__i>(__t) < std::get<__i>(__u)) || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); } }; template struct __tuple_compare<_Tp, _Up, __size, __size> { static constexpr bool __eq(const _Tp&, const _Up&) { return true; } static constexpr bool __less(const _Tp&, const _Up&) { return false; } }; template constexpr bool operator==(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { static_assert(sizeof...(_TElements) == sizeof...(_UElements), "tuple objects can only be compared if they have equal sizes."); using __compare = __tuple_compare, tuple<_UElements...>, 0, sizeof...(_TElements)>; return __compare::__eq(__t, __u); } template constexpr bool operator<(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { static_assert(sizeof...(_TElements) == sizeof...(_UElements), "tuple objects can only be compared if they have equal sizes."); using __compare = __tuple_compare, tuple<_UElements...>, 0, sizeof...(_TElements)>; return __compare::__less(__t, __u); } template constexpr bool operator!=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__t == __u); } template constexpr bool operator>(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return __u < __t; } template constexpr bool operator<=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__u < __t); } template constexpr bool operator>=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__t < __u); } // NB: DR 705. template constexpr tuple::__type...> make_tuple(_Elements&&... __args) { typedef tuple::__type...> __result_type; return __result_type(std::forward<_Elements>(__args)...); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2275. Why is forward_as_tuple not constexpr? template constexpr tuple<_Elements&&...> forward_as_tuple(_Elements&&... __args) noexcept { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } template struct __make_tuple_impl; template struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> : __make_tuple_impl<_Idx + 1, tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, _Tuple, _Nm> { }; template struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> { typedef tuple<_Tp...> __type; }; template struct __do_make_tuple : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> { }; // Returns the std::tuple equivalent of a tuple-like type. template struct __make_tuple : public __do_make_tuple::type>::type> { }; // Combines several std::tuple's into a single one. template struct __combine_tuples; template<> struct __combine_tuples<> { typedef tuple<> __type; }; template struct __combine_tuples> { typedef tuple<_Ts...> __type; }; template struct __combine_tuples, tuple<_T2s...>, _Rem...> { typedef typename __combine_tuples, _Rem...>::__type __type; }; // Computes the result type of tuple_cat given a set of tuple-like types. template struct __tuple_cat_result { typedef typename __combine_tuples ::__type...>::__type __type; }; // Helper to determine the index set for the first tuple-like // type of a given set. template struct __make_1st_indices; template<> struct __make_1st_indices<> { typedef std::_Index_tuple<> __type; }; template struct __make_1st_indices<_Tp, _Tpls...> { typedef typename std::_Build_index_tuple::type>::value>::__type __type; }; // Performs the actual concatenation by step-wise expanding tuple-like // objects into the elements, which are finally forwarded into the // result tuple. template struct __tuple_concater; template struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> { template static constexpr _Ret _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) { typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; return __next::_S_do(std::forward<_Tpls>(__tps)..., std::forward<_Us>(__us)..., std::get<_Is>(std::forward<_Tp>(__tp))...); } }; template struct __tuple_concater<_Ret, std::_Index_tuple<>> { template static constexpr _Ret _S_do(_Us&&... __us) { return _Ret(std::forward<_Us>(__us)...); } }; /// tuple_cat template...>::value>::type> constexpr auto tuple_cat(_Tpls&&... __tpls) -> typename __tuple_cat_result<_Tpls...>::__type { typedef typename __tuple_cat_result<_Tpls...>::__type __ret; typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; return __concater::_S_do(std::forward<_Tpls>(__tpls)...); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2301. Why is tie not constexpr? /// tie template constexpr tuple<_Elements&...> tie(_Elements&... __args) noexcept { return tuple<_Elements&...>(__args...); } /// swap template inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__and_<__is_swappable<_Elements>...>::value >::type #else void #endif swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template typename enable_if...>::value>::type swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; #endif // A class (and instance) which can be used in 'tie' when an element // of a tuple is not required. // _GLIBCXX14_CONSTEXPR // 2933. PR for LWG 2773 could be clearer struct _Swallow_assign { template _GLIBCXX14_CONSTEXPR const _Swallow_assign& operator=(const _Tp&) const { return *this; } }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2773. Making std::ignore constexpr _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; /// Partial specialization for tuples template struct uses_allocator, _Alloc> : true_type { }; // See stl_pair.h... template template inline pair<_T1, _T2>:: pair(piecewise_construct_t, tuple<_Args1...> __first, tuple<_Args2...> __second) : pair(__first, __second, typename _Build_index_tuple::__type(), typename _Build_index_tuple::__type()) { } template template inline pair<_T1, _T2>:: pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) { } #if __cplusplus > 201402L # define __cpp_lib_apply 201603 template constexpr decltype(auto) __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) { return std::__invoke(std::forward<_Fn>(__f), std::get<_Idx>(std::forward<_Tuple>(__t))...); } template constexpr decltype(auto) apply(_Fn&& __f, _Tuple&& __t) { using _Indices = make_index_sequence>>; return std::__apply_impl(std::forward<_Fn>(__f), std::forward<_Tuple>(__t), _Indices{}); } #define __cpp_lib_make_from_tuple 201606 template constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } template constexpr _Tp make_from_tuple(_Tuple&& __t) { return __make_from_tuple_impl<_Tp>( std::forward<_Tuple>(__t), make_index_sequence>>{}); } #endif // C++17 /// @} _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TUPLE PKgd1]=i 8/optionalnu[// -*- C++ -*- // Copyright (C) 2013-2018 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/optional * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_OPTIONAL #define _GLIBCXX_OPTIONAL 1 #pragma GCC system_header #if __cplusplus >= 201703L #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ #define __cpp_lib_optional 201606L template class optional; /// Tag type to disengage optional objects. struct nullopt_t { // Do not user-declare default constructor at all for // optional_value = {} syntax to work. // nullopt_t() = delete; // Used for constructing nullopt. enum class _Construct { _Token }; // Must be constexpr for nullopt_t to be literal. explicit constexpr nullopt_t(_Construct) { } }; /// Tag to disengage optional objects. inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; /** * @brief Exception class thrown when a disengaged optional object is * dereferenced. * @ingroup exceptions */ class bad_optional_access : public exception { public: bad_optional_access() { } virtual const char* what() const noexcept override { return "bad optional access"; } virtual ~bad_optional_access() noexcept = default; }; void __throw_bad_optional_access() __attribute__((__noreturn__)); // XXX Does not belong here. inline void __throw_bad_optional_access() { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); } // Payload for optionals with non-trivial destructor. template , bool /*_HasTrivialCopy */ = is_trivially_copy_assignable_v<_Tp> && is_trivially_copy_constructible_v<_Tp>, bool /*_HasTrivialMove */ = is_trivially_move_assignable_v<_Tp> && is_trivially_move_constructible_v<_Tp>> struct _Optional_payload { constexpr _Optional_payload() noexcept : _M_empty() { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _Optional_payload(__other) { } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _Optional_payload(std::move(__other)) { } constexpr _Optional_payload(const _Optional_payload& __other) { if (__other._M_engaged) this->_M_construct(__other._M_payload); } constexpr _Optional_payload(_Optional_payload&& __other) { if (__other._M_engaged) this->_M_construct(std::move(__other._M_payload)); } constexpr _Optional_payload& operator=(const _Optional_payload& __other) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = __other._M_get(); else { if (__other._M_engaged) this->_M_construct(__other._M_get()); else this->_M_reset(); } return *this; } constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, is_nothrow_move_assignable<_Tp>>()) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = std::move(__other._M_get()); else { if (__other._M_engaged) this->_M_construct(std::move(__other._M_get())); else this->_M_reset(); } return *this; } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged = false; ~_Optional_payload() { if (_M_engaged) _M_payload.~_Stored_type(); } template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; // Payload for potentially-constexpr optionals. template struct _Optional_payload<_Tp, true, true, true> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } }; // Payload for optionals with non-trivial copy assignment. template struct _Optional_payload<_Tp, true, false, true> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; constexpr _Optional_payload& operator=(const _Optional_payload& __other) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = __other._M_get(); else { if (__other._M_engaged) this->_M_construct(__other._M_get()); else this->_M_reset(); } return *this; } _Optional_payload& operator=(_Optional_payload&& __other) = default; using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; // Payload for optionals with non-trivial move assignment. template struct _Optional_payload<_Tp, true, true, false> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; _Optional_payload& operator=(const _Optional_payload& __other) = default; constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, is_nothrow_move_assignable<_Tp>>()) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = std::move(__other._M_get()); else { if (__other._M_engaged) this->_M_construct(std::move(__other._M_get())); else this->_M_reset(); } return *this; } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; // Payload for optionals with non-trivial copy and move assignment. template struct _Optional_payload<_Tp, true, false, false> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) {} template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; constexpr _Optional_payload& operator=(const _Optional_payload& __other) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = __other._M_get(); else { if (__other._M_engaged) this->_M_construct(__other._M_get()); else this->_M_reset(); } return *this; } constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, is_nothrow_move_assignable<_Tp>>()) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = std::move(__other._M_get()); else { if (__other._M_engaged) this->_M_construct(std::move(__other._M_get())); else this->_M_reset(); } return *this; } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; template class _Optional_base_impl { protected: using _Stored_type = remove_const_t<_Tp>; // The _M_construct operation has !_M_engaged as a precondition // while _M_destruct has _M_engaged as a precondition. template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload)) _Stored_type(std::forward<_Args>(__args)...); static_cast<_Dp*>(this)->_M_payload._M_engaged = true; } void _M_destruct() noexcept { static_cast<_Dp*>(this)->_M_payload._M_engaged = false; static_cast<_Dp*>(this)->_M_payload._M_payload.~_Stored_type(); } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (static_cast<_Dp*>(this)->_M_payload._M_engaged) static_cast<_Dp*>(this)->_M_destruct(); } }; /** * @brief Class template that takes care of copy/move constructors of optional * * Such a separate base class template is necessary in order to * conditionally make copy/move constructors trivial. * @see optional, _Enable_special_members */ template, bool = is_trivially_move_constructible_v<_Tp>> class _Optional_base // protected inheritance because optional needs to reach that base too : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) : _M_payload(__other._M_payload._M_engaged, __other._M_payload) { } constexpr _Optional_base(_Optional_base&& __other) noexcept(is_nothrow_move_constructible<_Tp>()) : _M_payload(__other._M_payload._M_engaged, std::move(__other._M_payload)) { } // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class _Optional_base<_Tp, false, true> : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) : _M_payload(__other._M_payload._M_engaged, __other._M_payload) { } constexpr _Optional_base(_Optional_base&& __other) = default; // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class _Optional_base<_Tp, true, false> : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) = default; constexpr _Optional_base(_Optional_base&& __other) noexcept(is_nothrow_move_constructible<_Tp>()) : _M_payload(__other._M_payload._M_engaged, std::move(__other._M_payload)) { } // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class _Optional_base<_Tp, true, true> : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) = default; constexpr _Optional_base(_Optional_base&& __other) = default; // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class optional; template using __converts_from_optional = __or_&>, is_constructible<_Tp, optional<_Up>&>, is_constructible<_Tp, const optional<_Up>&&>, is_constructible<_Tp, optional<_Up>&&>, is_convertible&, _Tp>, is_convertible&, _Tp>, is_convertible&&, _Tp>, is_convertible&&, _Tp>>; template using __assigns_from_optional = __or_&>, is_assignable<_Tp&, optional<_Up>&>, is_assignable<_Tp&, const optional<_Up>&&>, is_assignable<_Tp&, optional<_Up>&&>>; /** * @brief Class template for optional values. */ template class optional : private _Optional_base<_Tp>, private _Enable_copy_move< // Copy constructor. is_copy_constructible<_Tp>::value, // Copy assignment. __and_, is_copy_assignable<_Tp>>::value, // Move constructor. is_move_constructible<_Tp>::value, // Move assignment. __and_, is_move_assignable<_Tp>>::value, // Unique tag type. optional<_Tp>> { static_assert(!is_same_v, nullopt_t>); static_assert(!is_same_v, in_place_t>); static_assert(!is_reference_v<_Tp>); private: using _Base = _Optional_base<_Tp>; public: using value_type = _Tp; constexpr optional() = default; constexpr optional(nullopt_t) noexcept { } // Converting constructors for engaged optionals. template , decay_t<_Up>>>, __not_>>, is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp> >::value, bool> = true> constexpr optional(_Up&& __t) : _Base(std::in_place, std::forward<_Up>(__t)) { } template , decay_t<_Up>>>, __not_>>, is_constructible<_Tp, _Up&&>, __not_> >::value, bool> = false> explicit constexpr optional(_Up&& __t) : _Base(std::in_place, std::forward<_Up>(__t)) { } template >, is_constructible<_Tp, const _Up&>, is_convertible, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = true> constexpr optional(const optional<_Up>& __t) { if (__t) emplace(*__t); } template >, is_constructible<_Tp, const _Up&>, __not_>, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = false> explicit constexpr optional(const optional<_Up>& __t) { if (__t) emplace(*__t); } template >, is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp>, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = true> constexpr optional(optional<_Up>&& __t) { if (__t) emplace(std::move(*__t)); } template >, is_constructible<_Tp, _Up&&>, __not_>, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = false> explicit constexpr optional(optional<_Up>&& __t) { if (__t) emplace(std::move(*__t)); } template, bool> = false> explicit constexpr optional(in_place_t, _Args&&... __args) : _Base(std::in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> explicit constexpr optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { } // Assignment operators. optional& operator=(nullopt_t) noexcept { this->_M_reset(); return *this; } template enable_if_t<__and_< __not_, decay_t<_Up>>>, is_constructible<_Tp, _Up>, __not_<__and_, is_same<_Tp, decay_t<_Up>>>>, is_assignable<_Tp&, _Up>>::value, optional&> operator=(_Up&& __u) { if (this->_M_is_engaged()) this->_M_get() = std::forward<_Up>(__u); else this->_M_construct(std::forward<_Up>(__u)); return *this; } template enable_if_t<__and_< __not_>, is_constructible<_Tp, const _Up&>, is_assignable<_Tp&, _Up>, __not_<__converts_from_optional<_Tp, _Up>>, __not_<__assigns_from_optional<_Tp, _Up>> >::value, optional&> operator=(const optional<_Up>& __u) { if (__u) { if (this->_M_is_engaged()) this->_M_get() = *__u; else this->_M_construct(*__u); } else { this->_M_reset(); } return *this; } template enable_if_t<__and_< __not_>, is_constructible<_Tp, _Up>, is_assignable<_Tp&, _Up>, __not_<__converts_from_optional<_Tp, _Up>>, __not_<__assigns_from_optional<_Tp, _Up>> >::value, optional&> operator=(optional<_Up>&& __u) { if (__u) { if (this->_M_is_engaged()) this->_M_get() = std::move(*__u); else this->_M_construct(std::move(*__u)); } else { this->_M_reset(); } return *this; } template enable_if_t::value, _Tp&> emplace(_Args&&... __args) { this->_M_reset(); this->_M_construct(std::forward<_Args>(__args)...); return this->_M_get(); } template enable_if_t&, _Args&&...>::value, _Tp&> emplace(initializer_list<_Up> __il, _Args&&... __args) { this->_M_reset(); this->_M_construct(__il, std::forward<_Args>(__args)...); return this->_M_get(); } // Destructor is implicit, implemented in _Optional_base. // Swap. void swap(optional& __other) noexcept(is_nothrow_move_constructible<_Tp>() && is_nothrow_swappable_v<_Tp>) { using std::swap; if (this->_M_is_engaged() && __other._M_is_engaged()) swap(this->_M_get(), __other._M_get()); else if (this->_M_is_engaged()) { __other._M_construct(std::move(this->_M_get())); this->_M_destruct(); } else if (__other._M_is_engaged()) { this->_M_construct(std::move(__other._M_get())); __other._M_destruct(); } } // Observers. constexpr const _Tp* operator->() const { return std::__addressof(this->_M_get()); } constexpr _Tp* operator->() { return std::__addressof(this->_M_get()); } constexpr const _Tp& operator*() const& { return this->_M_get(); } constexpr _Tp& operator*()& { return this->_M_get(); } constexpr _Tp&& operator*()&& { return std::move(this->_M_get()); } constexpr const _Tp&& operator*() const&& { return std::move(this->_M_get()); } constexpr explicit operator bool() const noexcept { return this->_M_is_engaged(); } constexpr bool has_value() const noexcept { return this->_M_is_engaged(); } constexpr const _Tp& value() const& { return this->_M_is_engaged() ? this->_M_get() : (__throw_bad_optional_access(), this->_M_get()); } constexpr _Tp& value()& { return this->_M_is_engaged() ? this->_M_get() : (__throw_bad_optional_access(), this->_M_get()); } constexpr _Tp&& value()&& { return this->_M_is_engaged() ? std::move(this->_M_get()) : (__throw_bad_optional_access(), std::move(this->_M_get())); } constexpr const _Tp&& value() const&& { return this->_M_is_engaged() ? std::move(this->_M_get()) : (__throw_bad_optional_access(), std::move(this->_M_get())); } template constexpr _Tp value_or(_Up&& __u) const& { static_assert(is_copy_constructible_v<_Tp>); static_assert(is_convertible_v<_Up&&, _Tp>); return this->_M_is_engaged() ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u)); } template constexpr _Tp value_or(_Up&& __u) && { static_assert(is_move_constructible_v<_Tp>); static_assert(is_convertible_v<_Up&&, _Tp>); return this->_M_is_engaged() ? std::move(this->_M_get()) : static_cast<_Tp>(std::forward<_Up>(__u)); } void reset() noexcept { this->_M_reset(); } }; template using __optional_relop_t = enable_if_t::value, bool>; // Comparisons between optional values. template constexpr auto operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() == declval<_Up>())> { return static_cast(__lhs) == static_cast(__rhs) && (!__lhs || *__lhs == *__rhs); } template constexpr auto operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() != declval<_Up>())> { return static_cast(__lhs) != static_cast(__rhs) || (static_cast(__lhs) && *__lhs != *__rhs); } template constexpr auto operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() < declval<_Up>())> { return static_cast(__rhs) && (!__lhs || *__lhs < *__rhs); } template constexpr auto operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() > declval<_Up>())> { return static_cast(__lhs) && (!__rhs || *__lhs > *__rhs); } template constexpr auto operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() <= declval<_Up>())> { return !__lhs || (static_cast(__rhs) && *__lhs <= *__rhs); } template constexpr auto operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() >= declval<_Up>())> { return !__rhs || (static_cast(__lhs) && *__lhs >= *__rhs); } // Comparisons with nullopt. template constexpr bool operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept { return !__lhs; } template constexpr bool operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept { return !__rhs; } template constexpr bool operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept { return static_cast(__lhs); } template constexpr bool operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept { return static_cast(__rhs); } template constexpr bool operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept { return false; } template constexpr bool operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept { return static_cast(__rhs); } template constexpr bool operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept { return static_cast(__lhs); } template constexpr bool operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept { return false; } template constexpr bool operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept { return !__lhs; } template constexpr bool operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept { return true; } template constexpr bool operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept { return true; } template constexpr bool operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept { return !__rhs; } // Comparisons with value type. template constexpr auto operator==(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() == declval<_Up>())> { return __lhs && *__lhs == __rhs; } template constexpr auto operator==(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() == declval<_Tp>())> { return __rhs && __lhs == *__rhs; } template constexpr auto operator!=(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() != declval<_Up>())> { return !__lhs || *__lhs != __rhs; } template constexpr auto operator!=(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() != declval<_Tp>())> { return !__rhs || __lhs != *__rhs; } template constexpr auto operator<(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() < declval<_Up>())> { return !__lhs || *__lhs < __rhs; } template constexpr auto operator<(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() < declval<_Tp>())> { return __rhs && __lhs < *__rhs; } template constexpr auto operator>(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() > declval<_Up>())> { return __lhs && *__lhs > __rhs; } template constexpr auto operator>(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() > declval<_Tp>())> { return !__rhs || __lhs > *__rhs; } template constexpr auto operator<=(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() <= declval<_Up>())> { return !__lhs || *__lhs <= __rhs; } template constexpr auto operator<=(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() <= declval<_Tp>())> { return __rhs && __lhs <= *__rhs; } template constexpr auto operator>=(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() >= declval<_Up>())> { return __lhs && *__lhs >= __rhs; } template constexpr auto operator>=(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() >= declval<_Tp>())> { return !__rhs || __lhs >= *__rhs; } // Swap and creation functions. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2748. swappable traits for optionals template inline enable_if_t && is_swappable_v<_Tp>> swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } template enable_if_t && is_swappable_v<_Tp>)> swap(optional<_Tp>&, optional<_Tp>&) = delete; template constexpr optional> make_optional(_Tp&& __t) { return optional> { std::forward<_Tp>(__t) }; } template constexpr optional<_Tp> make_optional(_Args&&... __args) { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; } template constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; } // Hash. template, bool = __poison_hash<_Up>::__enable_hash_call> struct __optional_hash_call_base { size_t operator()(const optional<_Tp>& __t) const noexcept(noexcept(hash<_Up>{}(*__t))) { // We pick an arbitrary hash for disengaged optionals which hopefully // usual values of _Tp won't typically hash to. constexpr size_t __magic_disengaged_hash = static_cast(-3333); return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash; } }; template struct __optional_hash_call_base<_Tp, _Up, false> {}; template struct hash> : private __poison_hash>, public __optional_hash_call_base<_Tp> { using result_type [[__deprecated__]] = size_t; using argument_type [[__deprecated__]] = optional<_Tp>; }; template struct __is_fast_hash>> : __is_fast_hash> { }; /// @} #if __cpp_deduction_guides >= 201606 template optional(_Tp) -> optional<_Tp>; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_OPTIONAL PKgd1])tt8/chrononu[// -*- C++ -*- // Copyright (C) 2008-2018 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/chrono * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CHRONO #define _GLIBCXX_CHRONO 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include // for literals support. #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup chrono Time * @ingroup utilities * * Classes and functions for time. * @{ */ /** @namespace std::chrono * @brief ISO C++ 2011 entities sub-namespace for time and date. */ namespace chrono { template> struct duration; template struct time_point; } // 20.11.4.3 specialization of common_type (for duration, sfinae-friendly) template struct __duration_common_type_wrapper { private: typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num; typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den; typedef typename _CT::type __cr; typedef ratio<__gcd_num::value, (_Period1::den / __gcd_den::value) * _Period2::den> __r; public: typedef __success_type> type; }; template struct __duration_common_type_wrapper<__failure_type, _Period1, _Period2> { typedef __failure_type type; }; template struct common_type, chrono::duration<_Rep2, _Period2>> : public __duration_common_type_wrapper>::type, _Period1, _Period2>::type { }; // 20.11.4.3 specialization of common_type (for time_point, sfinae-friendly) template struct __timepoint_common_type_wrapper { typedef __success_type> type; }; template struct __timepoint_common_type_wrapper<__failure_type, _Clock> { typedef __failure_type type; }; template struct common_type, chrono::time_point<_Clock, _Duration2>> : public __timepoint_common_type_wrapper>::type, _Clock>::type { }; namespace chrono { // Primary template for duration_cast impl. template struct __duration_cast_impl { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>(static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, true, true> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>(__d.count())); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, true, false> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>( static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, false, true> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>( static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num))); } }; template struct __is_duration : std::false_type { }; template struct __is_duration> : std::true_type { }; template using __enable_if_is_duration = typename enable_if<__is_duration<_Tp>::value, _Tp>::type; template using __disable_if_is_duration = typename enable_if::value, _Tp>::type; /// duration_cast template constexpr __enable_if_is_duration<_ToDur> duration_cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::period __to_period; typedef typename _ToDur::rep __to_rep; typedef ratio_divide<_Period, __to_period> __cf; typedef typename common_type<__to_rep, _Rep, intmax_t>::type __cr; typedef __duration_cast_impl<_ToDur, __cf, __cr, __cf::num == 1, __cf::den == 1> __dc; return __dc::__cast(__d); } /// treat_as_floating_point template struct treat_as_floating_point : is_floating_point<_Rep> { }; #if __cplusplus > 201402L template inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; #endif // C++17 #if __cplusplus >= 201703L # define __cpp_lib_chrono 201611 template constexpr __enable_if_is_duration<_ToDur> floor(const duration<_Rep, _Period>& __d) { auto __to = chrono::duration_cast<_ToDur>(__d); if (__to > __d) return __to - _ToDur{1}; return __to; } template constexpr __enable_if_is_duration<_ToDur> ceil(const duration<_Rep, _Period>& __d) { auto __to = chrono::duration_cast<_ToDur>(__d); if (__to < __d) return __to + _ToDur{1}; return __to; } template constexpr enable_if_t< __and_<__is_duration<_ToDur>, __not_>>::value, _ToDur> round(const duration<_Rep, _Period>& __d) { _ToDur __t0 = chrono::floor<_ToDur>(__d); _ToDur __t1 = __t0 + _ToDur{1}; auto __diff0 = __d - __t0; auto __diff1 = __t1 - __d; if (__diff0 == __diff1) { if (__t0.count() & 1) return __t1; return __t0; } else if (__diff0 < __diff1) return __t0; return __t1; } template constexpr enable_if_t::is_signed, duration<_Rep, _Period>> abs(duration<_Rep, _Period> __d) { if (__d >= __d.zero()) return __d; return -__d; } #endif // C++17 /// duration_values template struct duration_values { static constexpr _Rep zero() noexcept { return _Rep(0); } static constexpr _Rep max() noexcept { return numeric_limits<_Rep>::max(); } static constexpr _Rep min() noexcept { return numeric_limits<_Rep>::lowest(); } }; template struct __is_ratio : std::false_type { }; template struct __is_ratio> : std::true_type { }; /// duration template struct duration { private: template using __is_float = treat_as_floating_point<_Rep2>; // _Period2 is an exact multiple of _Period template using __is_harmonic = __bool_constant::den == 1>; public: typedef _Rep rep; typedef _Period period; static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration"); static_assert(__is_ratio<_Period>::value, "period must be a specialization of ratio"); static_assert(_Period::num > 0, "period must be positive"); // 20.11.5.1 construction / copy / destroy constexpr duration() = default; duration(const duration&) = default; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3050. Conversion specification problem in chrono::duration template, __or_<__is_float, __not_<__is_float<_Rep2>>>>> constexpr explicit duration(const _Rep2& __rep) : __r(static_cast(__rep)) { } template, __and_<__is_harmonic<_Period2>, __not_<__is_float<_Rep2>>>>>> constexpr duration(const duration<_Rep2, _Period2>& __d) : __r(duration_cast(__d).count()) { } ~duration() = default; duration& operator=(const duration&) = default; // 20.11.5.2 observer constexpr rep count() const { return __r; } // 20.11.5.3 arithmetic constexpr duration operator+() const { return *this; } constexpr duration operator-() const { return duration(-__r); } _GLIBCXX17_CONSTEXPR duration& operator++() { ++__r; return *this; } _GLIBCXX17_CONSTEXPR duration operator++(int) { return duration(__r++); } _GLIBCXX17_CONSTEXPR duration& operator--() { --__r; return *this; } _GLIBCXX17_CONSTEXPR duration operator--(int) { return duration(__r--); } _GLIBCXX17_CONSTEXPR duration& operator+=(const duration& __d) { __r += __d.count(); return *this; } _GLIBCXX17_CONSTEXPR duration& operator-=(const duration& __d) { __r -= __d.count(); return *this; } _GLIBCXX17_CONSTEXPR duration& operator*=(const rep& __rhs) { __r *= __rhs; return *this; } _GLIBCXX17_CONSTEXPR duration& operator/=(const rep& __rhs) { __r /= __rhs; return *this; } // DR 934. template _GLIBCXX17_CONSTEXPR typename enable_if::value, duration&>::type operator%=(const rep& __rhs) { __r %= __rhs; return *this; } template _GLIBCXX17_CONSTEXPR typename enable_if::value, duration&>::type operator%=(const duration& __d) { __r %= __d.count(); return *this; } // 20.11.5.4 special values static constexpr duration zero() noexcept { return duration(duration_values::zero()); } static constexpr duration min() noexcept { return duration(duration_values::min()); } static constexpr duration max() noexcept { return duration(duration_values::max()); } private: rep __r; }; template constexpr typename common_type, duration<_Rep2, _Period2>>::type operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__cd(__lhs).count() + __cd(__rhs).count()); } template constexpr typename common_type, duration<_Rep2, _Period2>>::type operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__cd(__lhs).count() - __cd(__rhs).count()); } // SFINAE helper to obtain common_type<_Rep1, _Rep2> only if _Rep2 // is implicitly convertible to it. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3050. Conversion specification problem in chrono::duration constructor template::type> using __common_rep_t = typename enable_if::value, _CRep>::type; template constexpr duration<__common_rep_t<_Rep1, _Rep2>, _Period> operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef duration::type, _Period> __cd; return __cd(__cd(__d).count() * __s); } template constexpr duration<__common_rep_t<_Rep2, _Rep1>, _Period> operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) { return __d * __s; } template constexpr duration<__common_rep_t<_Rep1, __disable_if_is_duration<_Rep2>>, _Period> operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef duration::type, _Period> __cd; return __cd(__cd(__d).count() / __s); } template constexpr typename common_type<_Rep1, _Rep2>::type operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__lhs).count() / __cd(__rhs).count(); } // DR 934. template constexpr duration<__common_rep_t<_Rep1, __disable_if_is_duration<_Rep2>>, _Period> operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef duration::type, _Period> __cd; return __cd(__cd(__d).count() % __s); } template constexpr typename common_type, duration<_Rep2, _Period2>>::type operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__cd(__lhs).count() % __cd(__rhs).count()); } // comparisons template constexpr bool operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs).count() == __ct(__rhs).count(); } template constexpr bool operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs).count() < __ct(__rhs).count(); } template constexpr bool operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs == __rhs); } template constexpr bool operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__rhs < __lhs); } template constexpr bool operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __rhs < __lhs; } template constexpr bool operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs < __rhs); } /// nanoseconds typedef duration nanoseconds; /// microseconds typedef duration microseconds; /// milliseconds typedef duration milliseconds; /// seconds typedef duration seconds; /// minutes typedef duration> minutes; /// hours typedef duration> hours; /// time_point template struct time_point { typedef _Clock clock; typedef _Dur duration; typedef typename duration::rep rep; typedef typename duration::period period; constexpr time_point() : __d(duration::zero()) { } constexpr explicit time_point(const duration& __dur) : __d(__dur) { } // conversions template>> constexpr time_point(const time_point& __t) : __d(__t.time_since_epoch()) { } // observer constexpr duration time_since_epoch() const { return __d; } // arithmetic _GLIBCXX17_CONSTEXPR time_point& operator+=(const duration& __dur) { __d += __dur; return *this; } _GLIBCXX17_CONSTEXPR time_point& operator-=(const duration& __dur) { __d -= __dur; return *this; } // special values static constexpr time_point min() noexcept { return time_point(duration::min()); } static constexpr time_point max() noexcept { return time_point(duration::max()); } private: duration __d; }; /// time_point_cast template constexpr typename enable_if<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>>::type time_point_cast(const time_point<_Clock, _Dur>& __t) { typedef time_point<_Clock, _ToDur> __time_point; return __time_point(duration_cast<_ToDur>(__t.time_since_epoch())); } #if __cplusplus > 201402L template constexpr enable_if_t<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>> floor(const time_point<_Clock, _Dur>& __tp) { return time_point<_Clock, _ToDur>{ chrono::floor<_ToDur>(__tp.time_since_epoch())}; } template constexpr enable_if_t<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>> ceil(const time_point<_Clock, _Dur>& __tp) { return time_point<_Clock, _ToDur>{ chrono::ceil<_ToDur>(__tp.time_since_epoch())}; } template constexpr enable_if_t< __and_<__is_duration<_ToDur>, __not_>>::value, time_point<_Clock, _ToDur>> round(const time_point<_Clock, _Dur>& __tp) { return time_point<_Clock, _ToDur>{ chrono::round<_ToDur>(__tp.time_since_epoch())}; } #endif // C++17 template constexpr time_point<_Clock, typename common_type<_Dur1, duration<_Rep2, _Period2>>::type> operator+(const time_point<_Clock, _Dur1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs.time_since_epoch() + __rhs); } template constexpr time_point<_Clock, typename common_type, _Dur2>::type> operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef typename common_type<__dur1,_Dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__rhs.time_since_epoch() + __lhs); } template constexpr time_point<_Clock, typename common_type<_Dur1, duration<_Rep2, _Period2>>::type> operator-(const time_point<_Clock, _Dur1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs.time_since_epoch() -__rhs); } template constexpr typename common_type<_Dur1, _Dur2>::type operator-(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } template constexpr bool operator==(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } template constexpr bool operator!=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__lhs == __rhs); } template constexpr bool operator<(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } template constexpr bool operator<=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__rhs < __lhs); } template constexpr bool operator>(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __rhs < __lhs; } template constexpr bool operator>=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__lhs < __rhs); } // Clocks. // Why nanosecond resolution as the default? // Why have std::system_clock always count in the highest // resolution (ie nanoseconds), even if on some OSes the low 3 // or 9 decimal digits will be always zero? This allows later // implementations to change the system_clock::now() // implementation any time to provide better resolution without // changing function signature or units. // To support the (forward) evolution of the library's defined // clocks, wrap inside inline namespace so that the current // defintions of system_clock, steady_clock, and // high_resolution_clock types are uniquely mangled. This way, new // code can use the latests clocks, while the library can contain // compatibility definitions for previous versions. At some // point, when these clocks settle down, the inlined namespaces // can be removed. XXX GLIBCXX_ABI Deprecated inline namespace _V2 { /** * @brief System clock. * * Time returned represents wall time from the system-wide clock. */ struct system_clock { typedef chrono::nanoseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static_assert(system_clock::duration::min() < system_clock::duration::zero(), "a clock's minimum duration cannot be less than its epoch"); static constexpr bool is_steady = false; static time_point now() noexcept; // Map to C API static std::time_t to_time_t(const time_point& __t) noexcept { return std::time_t(duration_cast (__t.time_since_epoch()).count()); } static time_point from_time_t(std::time_t __t) noexcept { typedef chrono::time_point __from; return time_point_cast (__from(chrono::seconds(__t))); } }; /** * @brief Monotonic clock * * Time returned has the property of only increasing at a uniform rate. */ struct steady_clock { typedef chrono::nanoseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static constexpr bool is_steady = true; static time_point now() noexcept; }; /** * @brief Highest-resolution clock * * This is the clock "with the shortest tick period." Alias to * std::system_clock until higher-than-nanosecond definitions * become feasible. */ using high_resolution_clock = system_clock; } // end inline namespace _V2 } // namespace chrono #if __cplusplus > 201103L #define __cpp_lib_chrono_udls 201304 inline namespace literals { inline namespace chrono_literals { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" template struct _Checked_integral_constant : integral_constant<_Rep, static_cast<_Rep>(_Val)> { static_assert(_Checked_integral_constant::value >= 0 && _Checked_integral_constant::value == _Val, "literal value cannot be represented by duration type"); }; template constexpr _Dur __check_overflow() { using _Val = __parse_int::_Parse_int<_Digits...>; using _Rep = typename _Dur::rep; // TODO: should be simply integral_constant<_Rep, _Val::value> // but GCC doesn't reject narrowing conversions to _Rep. using _CheckedVal = _Checked_integral_constant<_Rep, _Val::value>; return _Dur{_CheckedVal::value}; } constexpr chrono::duration> operator""h(long double __hours) { return chrono::duration>{__hours}; } template constexpr chrono::hours operator""h() { return __check_overflow(); } constexpr chrono::duration> operator""min(long double __mins) { return chrono::duration>{__mins}; } template constexpr chrono::minutes operator""min() { return __check_overflow(); } constexpr chrono::duration operator""s(long double __secs) { return chrono::duration{__secs}; } template constexpr chrono::seconds operator""s() { return __check_overflow(); } constexpr chrono::duration operator""ms(long double __msecs) { return chrono::duration{__msecs}; } template constexpr chrono::milliseconds operator""ms() { return __check_overflow(); } constexpr chrono::duration operator""us(long double __usecs) { return chrono::duration{__usecs}; } template constexpr chrono::microseconds operator""us() { return __check_overflow(); } constexpr chrono::duration operator""ns(long double __nsecs) { return chrono::duration{__nsecs}; } template constexpr chrono::nanoseconds operator""ns() { return __check_overflow(); } #pragma GCC diagnostic pop } // inline namespace chrono_literals } // inline namespace literals namespace chrono { using namespace literals::chrono_literals; } // namespace chrono #endif // C++14 // @} group chrono _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif //_GLIBCXX_CHRONO PKgd1]>Dpp 8/cassertnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 cassert * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c assert.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 19.2 Assertions // // No include guards on this header... #pragma GCC system_header #include #include PKgd1]S1aa8/cfloatnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cfloat * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c float.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 18.2.2 Implementation properties: C library // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CFLOAT #define _GLIBCXX_CFLOAT 1 #if __cplusplus >= 201103L # ifndef DECIMAL_DIG # define DECIMAL_DIG __DECIMAL_DIG__ # endif # ifndef FLT_EVAL_METHOD # define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ # endif #endif #endif PKgd1]ؚ 8/exceptionnu[// Exception Handling support header for -*- C++ -*- // Copyright (C) 1995-2018 Free Software Foundation, Inc. // // This file is part of GCC. // // GCC 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. // // GCC 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 exception * This is a Standard C++ Library header. */ #ifndef __EXCEPTION__ #define __EXCEPTION__ #pragma GCC system_header #pragma GCC visibility push(default) #include #include extern "C++" { namespace std { /** If an %exception is thrown which is not listed in a function's * %exception specification, one of these may be thrown. */ class bad_exception : public exception { public: bad_exception() _GLIBCXX_USE_NOEXCEPT { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc. virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; }; /// If you write a replacement %terminate handler, it must be of this type. typedef void (*terminate_handler) (); /// If you write a replacement %unexpected handler, it must be of this type. typedef void (*unexpected_handler) (); /// Takes a new handler function as an argument, returns the old function. terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L /// Return the current terminate handler. terminate_handler get_terminate() noexcept; #endif /** The runtime will call this function if %exception handling must be * abandoned for any reason. It can also be called by the user. */ void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__)); /// Takes a new handler function as an argument, returns the old function. unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L /// Return the current unexpected handler. unexpected_handler get_unexpected() noexcept; #endif /** The runtime will call this function if an %exception is thrown which * violates the function's %exception specification. */ void unexpected() __attribute__ ((__noreturn__)); /** [18.6.4]/1: 'Returns true after completing evaluation of a * throw-expression until either completing initialization of the * exception-declaration in the matching handler or entering @c unexpected() * due to the throw; or after entering @c terminate() for any reason * other than an explicit call to @c terminate(). [Note: This includes * stack unwinding [15.2]. end note]' * * 2: 'When @c uncaught_exception() is true, throwing an * %exception can result in a call of @c terminate() * (15.5.1).' */ _GLIBCXX17_DEPRECATED bool uncaught_exception() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); #if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++98 #define __cpp_lib_uncaught_exceptions 201411L /// The number of uncaught exceptions. int uncaught_exceptions() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); #endif // @} group exceptions } // namespace std namespace __gnu_cxx { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A replacement for the standard terminate_handler which * prints more information about the terminating exception (if any) * on stderr. * * @ingroup exceptions * * Call * @code * std::set_terminate(__gnu_cxx::__verbose_terminate_handler) * @endcode * to use. For more info, see * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html * * In 3.4 and later, this is on by default. */ void __verbose_terminate_handler(); _GLIBCXX_END_NAMESPACE_VERSION } // namespace } // extern "C++" #pragma GCC visibility pop #if (__cplusplus >= 201103L) #include #include #endif #endif PKgd1]!(\i i 8/cctypenu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cctype * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c ctype.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CCTYPE #define _GLIBCXX_CCTYPE 1 // Get rid of those macros defined in in lieu of real functions. #undef isalnum #undef isalpha #undef iscntrl #undef isdigit #undef isgraph #undef islower #undef isprint #undef ispunct #undef isspace #undef isupper #undef isxdigit #undef tolower #undef toupper namespace std { using ::isalnum; using ::isalpha; using ::iscntrl; using ::isdigit; using ::isgraph; using ::islower; using ::isprint; using ::ispunct; using ::isspace; using ::isupper; using ::isxdigit; using ::tolower; using ::toupper; } // namespace std #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_CTYPE_TR1 #undef isblank namespace std { using ::isblank; } // namespace std #endif // _GLIBCXX_USE_C99_CTYPE_TR1 #endif // C++11 #endif PKgd1]$Y(( 8/cstddefnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 cstddef * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stddef.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 18.1 Types // #ifndef _GLIBCXX_CSTDDEF #define _GLIBCXX_CSTDDEF 1 #pragma GCC system_header #undef __need_wchar_t #undef __need_ptrdiff_t #undef __need_size_t #undef __need_NULL #undef __need_wint_t #include #include #if __cplusplus >= 201103L namespace std { // We handle size_t, ptrdiff_t, and nullptr_t in c++config.h. using ::max_align_t; } #endif #if __cplusplus >= 201703L namespace std { #define __cpp_lib_byte 201603 /// std::byte enum class byte : unsigned char {}; template struct __byte_operand { }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct __byte_operand { using __type = byte; }; #endif template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_0> { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_1> { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_2> { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #endif template struct __byte_operand : __byte_operand<_IntegerType> { }; template struct __byte_operand : __byte_operand<_IntegerType> { }; template struct __byte_operand : __byte_operand<_IntegerType> { }; template using __byte_op_t = typename __byte_operand<_IntegerType>::__type; template constexpr __byte_op_t<_IntegerType>& operator<<=(byte& __b, _IntegerType __shift) noexcept { return __b = byte(static_cast(__b) << __shift); } template constexpr __byte_op_t<_IntegerType> operator<<(byte __b, _IntegerType __shift) noexcept { return byte(static_cast(__b) << __shift); } template constexpr __byte_op_t<_IntegerType>& operator>>=(byte& __b, _IntegerType __shift) noexcept { return __b = byte(static_cast(__b) >> __shift); } template constexpr __byte_op_t<_IntegerType> operator>>(byte __b, _IntegerType __shift) noexcept { return byte(static_cast(__b) >> __shift); } constexpr byte& operator|=(byte& __l, byte __r) noexcept { return __l = byte(static_cast(__l) | static_cast(__r)); } constexpr byte operator|(byte __l, byte __r) noexcept { return byte(static_cast(__l) | static_cast(__r)); } constexpr byte& operator&=(byte& __l, byte __r) noexcept { return __l = byte(static_cast(__l) & static_cast(__r)); } constexpr byte operator&(byte __l, byte __r) noexcept { return byte(static_cast(__l) & static_cast(__r)); } constexpr byte& operator^=(byte& __l, byte __r) noexcept { return __l = byte(static_cast(__l) ^ static_cast(__r)); } constexpr byte operator^(byte __l, byte __r) noexcept { return byte(static_cast(__l) ^ static_cast(__r)); } constexpr byte operator~(byte __b) noexcept { return byte(~static_cast(__b)); } template constexpr _IntegerType to_integer(__byte_op_t<_IntegerType> __b) noexcept { return _IntegerType(__b); } } // namespace std #endif #endif // _GLIBCXX_CSTDDEF PKgd1]&г 8/fstreamnu[// File based streams -*- C++ -*- // Copyright (C) 1997-2018 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/fstream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.8 File-based streams // #ifndef _GLIBCXX_FSTREAM #define _GLIBCXX_FSTREAM 1 #pragma GCC system_header #include #include #include #include // For BUFSIZ #include // For __basic_file, __c_lock #if __cplusplus >= 201103L #include // For std::string overloads. #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201703L // Enable if _Path is a filesystem::path or experimental::filesystem::path template().make_preferred().filename())> using _If_fs_path = enable_if_t, _Result>; #endif // C++17 // [27.8.1.1] template class basic_filebuf /** * @brief The actual work of input and output (for files). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class associates both its input and output sequence with an * external disk file, and maintains a joint file position for both * sequences. Many of its semantics are described in terms of similar * behavior in the Standard C Library's @c FILE streams. * * Requirements on traits_type, specific to this class: * - traits_type::pos_type must be fpos * - traits_type::off_type must be streamoff * - traits_type::state_type must be Assignable and DefaultConstructible, * - traits_type::state_type() must be the initial state for codecvt. */ template class basic_filebuf : public basic_streambuf<_CharT, _Traits> { #if __cplusplus >= 201103L template using __chk_state = __and_, is_copy_constructible<_Tp>, is_default_constructible<_Tp>>; static_assert(__chk_state::value, "state_type must be CopyAssignable, CopyConstructible" " and DefaultConstructible"); static_assert(is_same>::value, "pos_type must be fpos"); #endif public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef basic_streambuf __streambuf_type; typedef basic_filebuf __filebuf_type; typedef __basic_file __file_type; typedef typename traits_type::state_type __state_type; typedef codecvt __codecvt_type; friend class ios_base; // For sync_with_stdio. protected: // Data Members: // MT lock inherited from libio or other low-level io library. __c_lock _M_lock; // External buffer. __file_type _M_file; /// Place to stash in || out || in | out settings for current filebuf. ios_base::openmode _M_mode; // Beginning state type for codecvt. __state_type _M_state_beg; // During output, the state that corresponds to pptr(), // during input, the state that corresponds to egptr() and // _M_ext_next. __state_type _M_state_cur; // Not used for output. During input, the state that corresponds // to eback() and _M_ext_buf. __state_type _M_state_last; /// Pointer to the beginning of internal buffer. char_type* _M_buf; /** * Actual size of internal buffer. This number is equal to the size * of the put area + 1 position, reserved for the overflow char of * a full area. */ size_t _M_buf_size; // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. bool _M_buf_allocated; /** * _M_reading == false && _M_writing == false for @b uncommitted mode; * _M_reading == true for @b read mode; * _M_writing == true for @b write mode; * * NB: _M_reading == true && _M_writing == true is unused. */ bool _M_reading; bool _M_writing; //@{ /** * Necessary bits for putback buffer management. * * @note pbacks of over one character are not currently supported. */ char_type _M_pback; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; bool _M_pback_init; //@} // Cached codecvt facet. const __codecvt_type* _M_codecvt; /** * Buffer for external characters. Used for input when * codecvt::always_noconv() == false. When valid, this corresponds * to eback(). */ char* _M_ext_buf; /** * Size of buffer held by _M_ext_buf. */ streamsize _M_ext_buf_size; /** * Pointers into the buffer held by _M_ext_buf that delimit a * subsequence of bytes that have been read but not yet converted. * When valid, _M_ext_next corresponds to egptr(). */ const char* _M_ext_next; char* _M_ext_end; /** * Initializes pback buffers, and moves normal buffers to safety. * Assumptions: * _M_in_cur has already been moved back */ void _M_create_pback() { if (!_M_pback_init) { _M_pback_cur_save = this->gptr(); _M_pback_end_save = this->egptr(); this->setg(&_M_pback, &_M_pback, &_M_pback + 1); _M_pback_init = true; } } /** * Deactivates pback buffer contents, and restores normal buffer. * Assumptions: * The pback buffer has only moved forward. */ void _M_destroy_pback() throw() { if (_M_pback_init) { // Length _M_in_cur moved in the pback buffer. _M_pback_cur_save += this->gptr() != this->eback(); this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); _M_pback_init = false; } } public: // Constructors/destructor: /** * @brief Does not open any files. * * The default constructor initializes the parent class using its * own default ctor. */ basic_filebuf(); #if __cplusplus >= 201103L basic_filebuf(const basic_filebuf&) = delete; basic_filebuf(basic_filebuf&&); #endif /** * @brief The destructor closes the file first. */ virtual ~basic_filebuf() { this->close(); } #if __cplusplus >= 201103L basic_filebuf& operator=(const basic_filebuf&) = delete; basic_filebuf& operator=(basic_filebuf&&); void swap(basic_filebuf&); #endif // Members: /** * @brief Returns true if the external file is open. */ bool is_open() const throw() { return _M_file.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * @return @c this on success, NULL on failure * * If a file is already open, this function immediately fails. * Otherwise it tries to open the file named @a __s using the flags * given in @a __mode. * * Table 92, adapted here, gives the relation between openmode * combinations and the equivalent @c fopen() flags. * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, * and binary|in|app per DR 596) *
       *  +---------------------------------------------------------+
       *  | ios_base Flag combination            stdio equivalent   |
       *  |binary  in  out  trunc  app                              |
       *  +---------------------------------------------------------+
       *  |             +                        w                  |
       *  |             +           +            a                  |
       *  |                         +            a                  |
       *  |             +     +                  w                  |
       *  |         +                            r                  |
       *  |         +   +                        r+                 |
       *  |         +   +     +                  w+                 |
       *  |         +   +           +            a+                 |
       *  |         +               +            a+                 |
       *  +---------------------------------------------------------+
       *  |   +         +                        wb                 |
       *  |   +         +           +            ab                 |
       *  |   +                     +            ab                 |
       *  |   +         +     +                  wb                 |
       *  |   +     +                            rb                 |
       *  |   +     +   +                        r+b                |
       *  |   +     +   +     +                  w+b                |
       *  |   +     +   +           +            a+b                |
       *  |   +     +               +            a+b                |
       *  +---------------------------------------------------------+
       *  
*/ __filebuf_type* open(const char* __s, ios_base::openmode __mode); #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * @return @c this on success, NULL on failure */ __filebuf_type* open(const std::string& __s, ios_base::openmode __mode) { return open(__s.c_str(), __mode); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * @return @c this on success, NULL on failure */ template _If_fs_path<_Path, __filebuf_type*> open(const _Path& __s, ios_base::openmode __mode) { return open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Closes the currently associated file. * @return @c this on success, NULL on failure * * If no file is currently open, this function immediately fails. * * If a put buffer area exists, @c overflow(eof) is * called to flush all the characters. The file is then * closed. * * If any operations fail, this function also fails. */ __filebuf_type* close(); protected: void _M_allocate_internal_buffer(); void _M_destroy_internal_buffer() throw(); // [27.8.1.4] overridden virtual functions virtual streamsize showmanyc(); // Stroustrup, 1998, p. 628 // underflow() and uflow() functions are called to get the next // character from the real input source when the buffer is empty. // Buffered input uses underflow() virtual int_type underflow(); virtual int_type pbackfail(int_type __c = _Traits::eof()); // Stroustrup, 1998, p 648 // The overflow() function is called to transfer characters to the // real output destination when the buffer is full. A call to // overflow(c) outputs the contents of the buffer plus the // character c. // 27.5.2.4.5 // Consume some sequence of the characters in the pending sequence. virtual int_type overflow(int_type __c = _Traits::eof()); // Convert internal byte sequence to external, char-based // sequence via codecvt. bool _M_convert_to_external(char_type*, streamsize); /** * @brief Manipulates the buffer. * @param __s Pointer to a buffer area. * @param __n Size of @a __s. * @return @c this * * If no file has been opened, and both @a __s and @a __n are zero, then * the stream becomes unbuffered. Otherwise, @c __s is used as a * buffer; see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more. */ virtual __streambuf_type* setbuf(char_type* __s, streamsize __n); virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); // Common code for seekoff, seekpos, and overflow pos_type _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); int _M_get_ext_pos(__state_type &__state); virtual int sync(); virtual void imbue(const locale& __loc); virtual streamsize xsgetn(char_type* __s, streamsize __n); virtual streamsize xsputn(const char_type* __s, streamsize __n); // Flushes output buffer, then writes unshift sequence. bool _M_terminate_output(); /** * This function sets the pointers of the internal buffer, both get * and put areas. Typically: * * __off == egptr() - eback() upon underflow/uflow (@b read mode); * __off == 0 upon overflow (@b write mode); * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). * * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size * reflects the actual allocated memory and the last cell is reserved * for the overflow char of a full put area. */ void _M_set_buffer(streamsize __off) { const bool __testin = _M_mode & ios_base::in; const bool __testout = (_M_mode & ios_base::out || _M_mode & ios_base::app); if (__testin && __off > 0) this->setg(_M_buf, _M_buf, _M_buf + __off); else this->setg(_M_buf, _M_buf, _M_buf); if (__testout && __off == 0 && _M_buf_size > 1 ) this->setp(_M_buf, _M_buf + _M_buf_size - 1); else this->setp(0, 0); } }; // [27.8.1.5] Template class basic_ifstream /** * @brief Controlling input for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from named files, using the inherited * functions from std::basic_istream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template class basic_ifstream : public basic_istream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf __filebuf_type; typedef basic_istream __istream_type; private: __filebuf_type _M_filebuf; public: // Constructors/Destructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ifstream() : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an input file stream. * @param __s std::string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ explicit basic_ifstream(const std::string& __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an input file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ template> basic_ifstream(const _Path& __s, ios_base::openmode __mode = ios_base::in) : basic_ifstream(__s.c_str(), __mode) { } #endif // C++17 basic_ifstream(const basic_ifstream&) = delete; basic_ifstream(basic_ifstream&& __rhs) : __istream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __istream_type::set_rdbuf(&_M_filebuf); } #endif // C++11 /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ifstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_ifstream& operator=(const basic_ifstream&) = delete; basic_ifstream& operator=(basic_ifstream&& __rhs) { __istream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_ifstream& __rhs) { __istream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::in) { if (!_M_filebuf.open(__s, __mode | ios_base::in)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::in) { if (!_M_filebuf.open(__s, __mode | ios_base::in)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ template _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::in) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; // [27.8.1.8] Template class basic_ofstream /** * @brief Controlling output for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from named files, using the inherited * functions from std::basic_ostream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template class basic_ofstream : public basic_ostream<_CharT,_Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf __filebuf_type; typedef basic_ostream __ostream_type; private: __filebuf_type _M_filebuf; public: // Constructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ofstream(): __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an output file stream. * @param __s std::string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ explicit basic_ofstream(const std::string& __s, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an output file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ template> basic_ofstream(const _Path& __s, ios_base::openmode __mode = ios_base::out) : basic_ofstream(__s.c_str(), __mode) { } #endif // C++17 basic_ofstream(const basic_ofstream&) = delete; basic_ofstream(basic_ofstream&& __rhs) : __ostream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __ostream_type::set_rdbuf(&_M_filebuf); } #endif /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ofstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_ofstream& operator=(const basic_ofstream&) = delete; basic_ofstream& operator=(basic_ofstream&& __rhs) { __ostream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_ofstream& __rhs) { __ostream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|out). If that * function fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::out) { if (!_M_filebuf.open(__s, __mode | ios_base::out)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,mode|out). If that * function fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::out) { if (!_M_filebuf.open(__s, __mode | ios_base::out)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|out). If that * function fails, @c failbit is set in the stream's error state. */ template _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::out) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; // [27.8.1.11] Template class basic_fstream /** * @brief Controlling input and output for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from and writing to named files, using * the inherited functions from std::basic_iostream. To control the * associated sequence, an instance of std::basic_filebuf is used, which * this page refers to as @c sb. */ template class basic_fstream : public basic_iostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf __filebuf_type; typedef basic_ios __ios_type; typedef basic_iostream __iostream_type; private: __filebuf_type _M_filebuf; public: // Constructors/destructor: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_fstream() : __iostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input/output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : __iostream_type(0), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an input/output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ explicit basic_fstream(const std::string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : __iostream_type(0), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an input/output file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ template> basic_fstream(const _Path& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : basic_fstream(__s.c_str(), __mode) { } #endif // C++17 basic_fstream(const basic_fstream&) = delete; basic_fstream(basic_fstream&& __rhs) : __iostream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __iostream_type::set_rdbuf(&_M_filebuf); } #endif /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_fstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_fstream& operator=(const basic_fstream&) = delete; basic_fstream& operator=(basic_fstream&& __rhs) { __iostream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_fstream& __rhs) { __iostream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ template _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; #if __cplusplus >= 201103L /// Swap specialization for filebufs. template inline void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for ifstreams. template inline void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for ofstreams. template inline void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for fstreams. template inline void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) { __x.swap(__y); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_FSTREAM */ PKgd1]q888/parallel/set_operations.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/set_operations.h * @brief Parallel implementations of set operations for random-access * iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Marius Elvert and Felix Bondarenko. #ifndef _GLIBCXX_PARALLEL_SET_OPERATIONS_H #define _GLIBCXX_PARALLEL_SET_OPERATIONS_H 1 #include #include #include namespace __gnu_parallel { template _OutputIterator __copy_tail(std::pair<_IIter, _IIter> __b, std::pair<_IIter, _IIter> __e, _OutputIterator __r) { if (__b.first != __e.first) { do { *__r++ = *__b.first++; } while (__b.first != __e.first); } else { while (__b.second != __e.second) *__r++ = *__b.second++; } return __r; } template struct __symmetric_difference_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __symmetric_difference_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; ++__r; } else if (_M_comp(*__c, *__a)) { *__r = *__c; ++__c; ++__r; } else { ++__a; ++__c; } } return std::copy(__c, __d, std::copy(__a, __b, __r)); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; ++__counter; } else if (_M_comp(*__c, *__a)) { ++__c; ++__counter; } else { ++__a; ++__c; } } return __counter + (__b - __a) + (__d - __c); } _OutputIterator __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const { return std::copy(__c, __d, __out); } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template struct __difference_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __difference_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; ++__r; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } } return std::copy(__a, __b, __r); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; ++__counter; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } } return __counter + (__b - __a); } _OutputIterator __first_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template struct __intersection_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __intersection_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { *__r = *__a; ++__a; ++__c; ++__r; } } return __r; } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; ++__counter; } } return __counter; } _OutputIterator __first_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } _OutputIterator __second_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } }; template struct __union_func { typedef typename std::iterator_traits<_IIter>::difference_type _DifferenceType; __union_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, const _IIter __b, _IIter __c, const _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; } else if (_M_comp(*__c, *__a)) { *__r = *__c; ++__c; } else { *__r = *__a; ++__a; ++__c; } ++__r; } return std::copy(__c, __d, std::copy(__a, __b, __r)); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } ++__counter; } __counter += (__b - __a); __counter += (__d - __c); return __counter; } _OutputIterator __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const { return std::copy(__c, __d, __out); } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template _OutputIterator __parallel_set_operation(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Operation __op) { _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; if (__begin1 == __end1) return __op.__first_empty(__begin2, __end2, __result); if (__begin2 == __end2) return __op.__second_empty(__begin1, __end1, __result); const _DifferenceType __size = (__end1 - __begin1) + (__end2 - __begin2); const _IteratorPair __sequence[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) }; _OutputIterator __return_value = __result; _DifferenceType *__borders; _IteratorPair *__block_begins; _DifferenceType* __lengths; _ThreadIndex __num_threads = std::min<_DifferenceType>(__get_max_threads(), std::min(__end1 - __begin1, __end2 - __begin2)); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; __equally_split(__size, __num_threads + 1, __borders); __block_begins = new _IteratorPair[__num_threads + 1]; // Very __start. __block_begins[0] = std::make_pair(__begin1, __begin2); __lengths = new _DifferenceType[__num_threads]; } //single _ThreadIndex __iam = omp_get_thread_num(); // _Result from multiseq_partition. _IIter __offset[2]; const _DifferenceType __rank = __borders[__iam + 1]; multiseq_partition(__sequence, __sequence + 2, __rank, __offset, __op._M_comp); // allowed to read? // together // *(__offset[ 0 ] - 1) == *__offset[ 1 ] if (__offset[ 0 ] != __begin1 && __offset[1] != __end2 && !__op._M_comp(*(__offset[0] - 1), *__offset[1]) && !__op._M_comp(*__offset[1], *(__offset[0] - 1))) { // Avoid split between globally equal elements: move one to // front in first sequence. --__offset[0]; } _IteratorPair __block_end = __block_begins[__iam + 1] = _IteratorPair(__offset[0], __offset[1]); // Make sure all threads have their block_begin result written out. # pragma omp barrier _IteratorPair __block_begin = __block_begins[__iam]; // Begin working for the first block, while the others except // the last start to count. if (__iam == 0) { // The first thread can copy already. __lengths[ __iam ] = __op._M_invoke(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second, __result) - __result; } else { __lengths[ __iam ] = __op.__count(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second); } // Make sure everyone wrote their lengths. # pragma omp barrier _OutputIterator __r = __result; if (__iam == 0) { // Do the last block. for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __r += __lengths[__i]; __block_begin = __block_begins[__num_threads]; // Return the result iterator of the last block. __return_value = __op._M_invoke(__block_begin.first, __end1, __block_begin.second, __end2, __r); } else { for (_ThreadIndex __i = 0; __i < __iam; ++__i) __r += __lengths[ __i ]; // Reset begins for copy pass. __op._M_invoke(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second, __r); } } return __return_value; } template inline _OutputIterator __parallel_set_union(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __union_func< _IIter, _OutputIterator, _Compare>(__comp)); } template inline _OutputIterator __parallel_set_intersection(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __intersection_func<_IIter, _OutputIterator, _Compare>(__comp)); } template inline _OutputIterator __parallel_set_difference(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __difference_func<_IIter, _OutputIterator, _Compare>(__comp)); } template inline _OutputIterator __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __symmetric_difference_func<_IIter, _OutputIterator, _Compare>(__comp)); } } #endif /* _GLIBCXX_PARALLEL_SET_OPERATIONS_H */ PKgd1]e׶ 8/parallel/features.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/features.h * @brief Defines on whether to include algorithm variants. * * Less variants reduce executable size and compile time. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_FEATURES_H #define _GLIBCXX_PARALLEL_FEATURES_H 1 #ifndef _GLIBCXX_MERGESORT /** @def _GLIBCXX_MERGESORT * @brief Include parallel multi-way mergesort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_MERGESORT 1 #endif #ifndef _GLIBCXX_QUICKSORT /** @def _GLIBCXX_QUICKSORT * @brief Include parallel unbalanced quicksort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_QUICKSORT 1 #endif #ifndef _GLIBCXX_BAL_QUICKSORT /** @def _GLIBCXX_BAL_QUICKSORT * @brief Include parallel dynamically load-balanced quicksort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_BAL_QUICKSORT 1 #endif #ifndef _GLIBCXX_FIND_GROWING_BLOCKS /** @brief Include the growing blocks variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_GROWING_BLOCKS 1 #endif #ifndef _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS /** @brief Include the equal-sized blocks variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS 1 #endif #ifndef _GLIBCXX_FIND_EQUAL_SPLIT /** @def _GLIBCXX_FIND_EQUAL_SPLIT * @brief Include the equal splitting variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_EQUAL_SPLIT 1 #endif #ifndef _GLIBCXX_TREE_INITIAL_SPLITTING /** @def _GLIBCXX_TREE_INITIAL_SPLITTING * @brief Include the initial splitting variant for * _Rb_tree::insert_unique(_IIter beg, _IIter __end). * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_INITIAL_SPLITTING 1 #endif #ifndef _GLIBCXX_TREE_DYNAMIC_BALANCING /** @def _GLIBCXX_TREE_DYNAMIC_BALANCING * @brief Include the dynamic balancing variant for * _Rb_tree::insert_unique(_IIter beg, _IIter __end). * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_DYNAMIC_BALANCING 1 #endif #ifndef _GLIBCXX_TREE_FULL_COPY /** @def _GLIBCXX_TREE_FULL_COPY * @brief In order to sort the input sequence of * _Rb_tree::insert_unique(_IIter beg, _IIter __end) a * full copy of the input elements is done. * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_FULL_COPY 1 #endif #endif /* _GLIBCXX_PARALLEL_FEATURES_H */ PKgd1]p8/parallel/compatibility.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/compatibility.h * @brief Compatibility layer, mostly concerned with atomic operations. * * This file is a GNU parallel extension to the Standard C++ Library * and contains implementation details for the library's internal use. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_COMPATIBILITY_H #define _GLIBCXX_PARALLEL_COMPATIBILITY_H 1 #include #include #if !defined(_WIN32) || defined (__CYGWIN__) #include #endif #ifdef __MINGW32__ // Including will drag in all the windows32 names. Since // that can cause user code portability problems, we just declare the // one needed function here. extern "C" __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long); #endif namespace __gnu_parallel { template inline _Tp __add_omp(volatile _Tp* __ptr, _Tp __addend) { int64_t __res; #pragma omp critical { __res = *__ptr; *(__ptr) += __addend; } return __res; } /** @brief Add a value to a variable, atomically. * * @param __ptr Pointer to a signed integer. * @param __addend Value to add. */ template inline _Tp __fetch_and_add(volatile _Tp* __ptr, _Tp __addend) { if (__atomic_always_lock_free(sizeof(_Tp), __ptr)) return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL); return __add_omp(__ptr, __addend); } template inline bool __cas_omp(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement) { bool __res = false; #pragma omp critical { if (*__ptr == __comparand) { *__ptr = __replacement; __res = true; } } return __res; } /** @brief Compare-and-swap * * Compare @c *__ptr and @c __comparand. If equal, let @c * *__ptr=__replacement and return @c true, return @c false otherwise. * * @param __ptr Pointer to signed integer. * @param __comparand Compare value. * @param __replacement Replacement value. */ template inline bool __compare_and_swap(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement) { if (__atomic_always_lock_free(sizeof(_Tp), __ptr)) return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); return __cas_omp(__ptr, __comparand, __replacement); } /** @brief Yield control to another thread, without waiting for * the end of the time slice. */ inline void __yield() { #if defined (_WIN32) && !defined (__CYGWIN__) Sleep(0); #else sched_yield(); #endif } } // end namespace #endif /* _GLIBCXX_PARALLEL_COMPATIBILITY_H */ PKgd1]q..8/parallel/iterator.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/iterator.h * @brief Helper iterator classes for the std::transform() functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_ITERATOR_H #define _GLIBCXX_PARALLEL_ITERATOR_H 1 #include #include namespace __gnu_parallel { /** @brief A pair of iterators. The usual iterator operations are * applied to both child iterators. */ template class _IteratorPair : public std::pair<_Iterator1, _Iterator2> { private: typedef std::pair<_Iterator1, _Iterator2> _Base; public: typedef _IteratorCategory iterator_category; typedef void value_type; typedef std::iterator_traits<_Iterator1> _TraitsType; typedef typename _TraitsType::difference_type difference_type; typedef _IteratorPair* pointer; typedef _IteratorPair& reference; _IteratorPair() { } _IteratorPair(const _Iterator1& __first, const _Iterator2& __second) : _Base(__first, __second) { } // Pre-increment operator. _IteratorPair& operator++() { ++_Base::first; ++_Base::second; return *this; } // Post-increment operator. const _IteratorPair operator++(int) { return _IteratorPair(_Base::first++, _Base::second++); } // Pre-decrement operator. _IteratorPair& operator--() { --_Base::first; --_Base::second; return *this; } // Post-decrement operator. const _IteratorPair operator--(int) { return _IteratorPair(_Base::first--, _Base::second--); } // Type conversion. operator _Iterator2() const { return _Base::second; } _IteratorPair& operator=(const _IteratorPair& __other) { _Base::first = __other.first; _Base::second = __other.second; return *this; } _IteratorPair operator+(difference_type __delta) const { return _IteratorPair(_Base::first + __delta, _Base::second + __delta); } difference_type operator-(const _IteratorPair& __other) const { return _Base::first - __other.first; } }; /** @brief A triple of iterators. The usual iterator operations are applied to all three child iterators. */ template class _IteratorTriple { public: typedef _IteratorCategory iterator_category; typedef void value_type; typedef typename std::iterator_traits<_Iterator1>::difference_type difference_type; typedef _IteratorTriple* pointer; typedef _IteratorTriple& reference; _Iterator1 _M_first; _Iterator2 _M_second; _Iterator3 _M_third; _IteratorTriple() { } _IteratorTriple(const _Iterator1& __first, const _Iterator2& __second, const _Iterator3& __third) { _M_first = __first; _M_second = __second; _M_third = __third; } // Pre-increment operator. _IteratorTriple& operator++() { ++_M_first; ++_M_second; ++_M_third; return *this; } // Post-increment operator. const _IteratorTriple operator++(int) { return _IteratorTriple(_M_first++, _M_second++, _M_third++); } // Pre-decrement operator. _IteratorTriple& operator--() { --_M_first; --_M_second; --_M_third; return *this; } // Post-decrement operator. const _IteratorTriple operator--(int) { return _IteratorTriple(_M_first--, _M_second--, _M_third--); } // Type conversion. operator _Iterator3() const { return _M_third; } _IteratorTriple& operator=(const _IteratorTriple& __other) { _M_first = __other._M_first; _M_second = __other._M_second; _M_third = __other._M_third; return *this; } _IteratorTriple operator+(difference_type __delta) const { return _IteratorTriple(_M_first + __delta, _M_second + __delta, _M_third + __delta); } difference_type operator-(const _IteratorTriple& __other) const { return _M_first - __other._M_first; } }; } #endif /* _GLIBCXX_PARALLEL_ITERATOR_H */ PKgd1]8_8/parallel/unique_copy.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/unique_copy.h * @brief Parallel implementations of std::unique_copy(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Robert Geisberger and Robin Dapp. #ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H #define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1 #include #include namespace __gnu_parallel { /** @brief Parallel std::unique_copy(), w/__o explicit equality predicate. * @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence. * @param __binary_pred Equality predicate. * @return End iterator of result __sequence. */ template _OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result, _BinaryPredicate __binary_pred) { _GLIBCXX_CALL(__last - __first) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __size = __last - __first; if (__size == 0) return __result; // Let the first thread process two parts. _DifferenceType *__counter; _DifferenceType *__borders; _ThreadIndex __num_threads = __get_max_threads(); // First part contains at least one element. # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; __equally_split(__size, __num_threads + 1, __borders); __counter = new _DifferenceType[__num_threads + 1]; } _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __begin, __end; // Check for length without duplicates // Needed for position in output _DifferenceType __i = 0; _OutputIterator __out = __result; if (__iam == 0) { __begin = __borders[0] + 1; // == 1 __end = __borders[__iam + 1]; ++__i; *__out++ = *__first; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) { ++__i; *__out++ = *__iter; } } } else { __begin = __borders[__iam]; //one part __end = __borders[__iam + 1]; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) ++__i; } } __counter[__iam] = __i; // Last part still untouched. _DifferenceType __begin_output; # pragma omp barrier // Store result in output on calculated positions. __begin_output = 0; if (__iam == 0) { for (_ThreadIndex __t = 0; __t < __num_threads; ++__t) __begin_output += __counter[__t]; __i = 0; _OutputIterator __iter_out = __result + __begin_output; __begin = __borders[__num_threads]; __end = __size; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (__iter == __first || !__binary_pred(*__iter, *(__iter - 1))) { ++__i; *__iter_out++ = *__iter; } } __counter[__num_threads] = __i; } else { for (_ThreadIndex __t = 0; __t < __iam; __t++) __begin_output += __counter[__t]; _OutputIterator __iter_out = __result + __begin_output; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) *__iter_out++ = *__iter; } } } _DifferenceType __end_output = 0; for (_ThreadIndex __t = 0; __t < __num_threads + 1; __t++) __end_output += __counter[__t]; delete[] __borders; return __result + __end_output; } /** @brief Parallel std::unique_copy(), without explicit equality predicate * @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence. * @return End iterator of result __sequence. */ template inline _OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result) { typedef typename std::iterator_traits<_IIter>::value_type _ValueType; return __parallel_unique_copy(__first, __last, __result, std::equal_to<_ValueType>()); } }//namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_UNIQUE_COPY_H */ PKgd1]/ee8/parallel/algorithmnu[// Algorithm extensions -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algorithm * This file is a GNU extension to the Standard C++ Library. */ #ifndef _PARALLEL_ALGORITHM #define _PARALLEL_ALGORITHM 1 #pragma GCC system_header #include #include #include #include #endif PKgd1]҃8/parallel/random_number.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/random_number.h * @brief Random number generator based on the Mersenne twister. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_RANDOM_NUMBER_H #define _GLIBCXX_PARALLEL_RANDOM_NUMBER_H 1 #include #include #include namespace __gnu_parallel { /** @brief Random number generator, based on the Mersenne twister. */ class _RandomNumber { private: std::tr1::mt19937 _M_mt; uint64_t _M_supremum; uint64_t _M_rand_sup; double _M_supremum_reciprocal; double _M_rand_sup_reciprocal; // Assumed to be twice as long as the usual random number. uint64_t __cache; // Bit results. int __bits_left; static uint32_t __scale_down(uint64_t __x, #if _GLIBCXX_SCALE_DOWN_FPU uint64_t /*_M_supremum*/, double _M_supremum_reciprocal) #else uint64_t _M_supremum, double /*_M_supremum_reciprocal*/) #endif { #if _GLIBCXX_SCALE_DOWN_FPU return uint32_t(__x * _M_supremum_reciprocal); #else return static_cast(__x % _M_supremum); #endif } public: /** @brief Default constructor. Seed with 0. */ _RandomNumber() : _M_mt(0), _M_supremum(0x100000000ULL), _M_rand_sup(1ULL << std::numeric_limits::digits), _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)), _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)), __cache(0), __bits_left(0) { } /** @brief Constructor. * @param __seed Random __seed. * @param _M_supremum Generate integer random numbers in the * interval @c [0,_M_supremum). */ _RandomNumber(uint32_t __seed, uint64_t _M_supremum = 0x100000000ULL) : _M_mt(__seed), _M_supremum(_M_supremum), _M_rand_sup(1ULL << std::numeric_limits::digits), _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)), _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)), __cache(0), __bits_left(0) { } /** @brief Generate unsigned random 32-bit integer. */ uint32_t operator()() { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); } /** @brief Generate unsigned random 32-bit integer in the interval @c [0,local_supremum). */ uint32_t operator()(uint64_t local_supremum) { return __scale_down(_M_mt(), local_supremum, double(local_supremum * _M_rand_sup_reciprocal)); } /** @brief Generate a number of random bits, run-time parameter. * @param __bits Number of bits to generate. */ unsigned long __genrand_bits(int __bits) { unsigned long __res = __cache & ((1 << __bits) - 1); __cache = __cache >> __bits; __bits_left -= __bits; if (__bits_left < 32) { __cache |= ((uint64_t(_M_mt())) << __bits_left); __bits_left += 32; } return __res; } }; } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_RANDOM_NUMBER_H */ PKgd1] E)E)8/parallel/for_each_selectors.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/for_each_selectors.h * @brief Functors representing different tasks to be plugged into the * generic parallelization methods for embarrassingly parallel functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1 #include namespace __gnu_parallel { /** @brief Generic __selector for embarrassingly parallel functions. */ template struct __generic_for_each_selector { /** @brief _Iterator on last element processed; needed for some * algorithms (e. g. std::transform()). */ _It _M_finish_iterator; }; /** @brief std::for_each() selector. */ template struct __for_each_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { __o(*__i); return true; } }; /** @brief std::generate() selector. */ template struct __generate_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { *__i = __o(); return true; } }; /** @brief std::fill() selector. */ template struct __fill_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. */ template bool operator()(_ValueType& __v, _It __i) { *__i = __v; return true; } }; /** @brief std::transform() __selector, one input sequence variant. */ template struct __transform1_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { *__i.second = __o(*__i.first); return true; } }; /** @brief std::transform() __selector, two input sequences variant. */ template struct __transform2_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { *__i._M_third = __o(*__i._M_first, *__i._M_second); return true; } }; /** @brief std::replace() selector. */ template struct __replace_selector : public __generic_for_each_selector<_It> { /** @brief Value to replace with. */ const _Tp& __new_val; /** @brief Constructor * @param __new_val Value to replace with. */ explicit __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {} /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. */ bool operator()(_Tp& __v, _It __i) { if (*__i == __v) *__i = __new_val; return true; } }; /** @brief std::replace() selector. */ template struct __replace_if_selector : public __generic_for_each_selector<_It> { /** @brief Value to replace with. */ const _Tp& __new_val; /** @brief Constructor. * @param __new_val Value to replace with. */ explicit __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { } /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ bool operator()(_Op& __o, _It __i) { if (__o(*__i)) *__i = __new_val; return true; } }; /** @brief std::count() selector. */ template struct __count_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. * @return 1 if count, 0 if does not count. */ template _Diff operator()(_ValueType& __v, _It __i) { return (__v == *__i) ? 1 : 0; } }; /** @brief std::count_if () selector. */ template struct __count_if_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. * @return 1 if count, 0 if does not count. */ template _Diff operator()(_Op& __o, _It __i) { return (__o(*__i)) ? 1 : 0; } }; /** @brief std::accumulate() selector. */ template struct __accumulate_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator (unused). * @param __i iterator referencing object. * @return The current value. */ template typename std::iterator_traits<_It>::value_type operator()(_Op __o, _It __i) { return *__i; } }; /** @brief std::inner_product() selector. */ template struct __inner_product_selector : public __generic_for_each_selector<_It> { /** @brief Begin iterator of first sequence. */ _It __begin1_iterator; /** @brief Begin iterator of second sequence. */ _It2 __begin2_iterator; /** @brief Constructor. * @param __b1 Begin iterator of first sequence. * @param __b2 Begin iterator of second sequence. */ explicit __inner_product_selector(_It __b1, _It2 __b2) : __begin1_iterator(__b1), __begin2_iterator(__b2) { } /** @brief Functor execution. * @param __mult Multiplication functor. * @param __current iterator referencing object. * @return Inner product elemental __result. */ template _Tp operator()(_Op __mult, _It __current) { typename std::iterator_traits<_It>::difference_type __position = __current - __begin1_iterator; return __mult(*__current, *(__begin2_iterator + __position)); } }; /** @brief Selector that just returns the passed iterator. */ template struct __identity_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator (unused). * @param __i iterator referencing object. * @return Passed iterator. */ template _It operator()(_Op __o, _It __i) { return __i; } }; /** @brief Selector that returns the difference between two adjacent * __elements. */ template struct __adjacent_difference_selector : public __generic_for_each_selector<_It> { template bool operator()(_Op& __o, _It __i) { typename _It::first_type __go_back_one = __i.first; --__go_back_one; *__i.second = __o(*__i.first, *__go_back_one); return true; } }; /** @brief Functor doing nothing * * For some __reduction tasks (this is not a function object, but is * passed as __selector __dummy parameter. */ struct _Nothing { /** @brief Functor execution. * @param __i iterator referencing object. */ template void operator()(_It __i) { } }; /** @brief Reduction function doing nothing. */ struct _DummyReduct { bool operator()(bool, bool) const { return true; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template struct __min_element_reduct { _Compare& __comp; explicit __min_element_reduct(_Compare &__c) : __comp(__c) { } _It operator()(_It __x, _It __y) { return (__comp(*__x, *__y)) ? __x : __y; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template struct __max_element_reduct { _Compare& __comp; explicit __max_element_reduct(_Compare& __c) : __comp(__c) { } _It operator()(_It __x, _It __y) { return (__comp(*__x, *__y)) ? __y : __x; } }; /** @brief General reduction, using a binary operator. */ template struct __accumulate_binop_reduct { _BinOp& __binop; explicit __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { } template _Result operator()(const _Result& __x, const _Addend& __y) { return __binop(__x, __y); } }; } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */ PKgd1]b558/parallel/find.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/find.h * @brief Parallel implementation base for std::find(), std::equal() * and related functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_FIND_H #define _GLIBCXX_PARALLEL_FIND_H 1 #include #include #include #include #include namespace __gnu_parallel { /** * @brief Parallel std::find, switch for different algorithms. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Must have same * length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. */ template inline std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector) { switch (_Settings::get().find_algorithm) { case GROWING_BLOCKS: return __find_template(__begin1, __end1, __begin2, __pred, __selector, growing_blocks_tag()); case CONSTANT_SIZE_BLOCKS: return __find_template(__begin1, __end1, __begin2, __pred, __selector, constant_size_blocks_tag()); case EQUAL_SPLIT: return __find_template(__begin1, __end1, __begin2, __pred, __selector, equal_split_tag()); default: _GLIBCXX_PARALLEL_ASSERT(false); return std::make_pair(__begin1, __begin2); } } #if _GLIBCXX_FIND_EQUAL_SPLIT /** * @brief Parallel std::find, equal splitting variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. */ template std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, equal_split_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; _DifferenceType __length = __end1 - __begin1; _DifferenceType __result = __length; _DifferenceType* __borders; omp_lock_t __result_lock; omp_init_lock(&__result_lock); _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 1]; __equally_split(__length, __num_threads, __borders); } //single _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __start = __borders[__iam], __stop = __borders[__iam + 1]; _RAIter1 __i1 = __begin1 + __start; _RAIter2 __i2 = __begin2 + __start; for (_DifferenceType __pos = __start; __pos < __stop; ++__pos) { # pragma omp flush(__result) // Result has been set to something lower. if (__result < __pos) break; if (__selector(__i1, __i2, __pred)) { omp_set_lock(&__result_lock); if (__pos < __result) __result = __pos; omp_unset_lock(&__result_lock); break; } ++__i1; ++__i2; } } //parallel omp_destroy_lock(&__result_lock); delete[] __borders; return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif #if _GLIBCXX_FIND_GROWING_BLOCKS /** * @brief Parallel std::find, growing block size variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. * @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_scale_factor * * There are two main differences between the growing blocks and * the constant-size blocks variants. * 1. For GB, the block size grows; for CSB, the block size is fixed. * 2. For GB, the blocks are allocated dynamically; * for CSB, the blocks are allocated in a predetermined manner, * namely spacial round-robin. */ template std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, growing_blocks_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; const _Settings& __s = _Settings::get(); _DifferenceType __length = __end1 - __begin1; _DifferenceType __sequential_search_size = std::min<_DifferenceType> (__length, __s.find_sequential_search_size); // Try it sequentially first. std::pair<_RAIter1, _RAIter2> __find_seq_result = __selector._M_sequential_algorithm (__begin1, __begin1 + __sequential_search_size, __begin2, __pred); if (__find_seq_result.first != (__begin1 + __sequential_search_size)) return __find_seq_result; // Index of beginning of next free block (after sequential find). _DifferenceType __next_block_start = __sequential_search_size; _DifferenceType __result = __length; omp_lock_t __result_lock; omp_init_lock(&__result_lock); const float __scale_factor = __s.find_scale_factor; _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel shared(__result) num_threads(__num_threads) { # pragma omp single __num_threads = omp_get_num_threads(); // Not within first __k elements -> start parallel. _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __block_size = std::max<_DifferenceType>(1, __scale_factor * __next_block_start); _DifferenceType __start = __fetch_and_add<_DifferenceType> (&__next_block_start, __block_size); // Get new block, update pointer to next block. _DifferenceType __stop = std::min<_DifferenceType>(__length, __start + __block_size); std::pair<_RAIter1, _RAIter2> __local_result; while (__start < __length) { # pragma omp flush(__result) // Get new value of result. if (__result < __start) { // No chance to find first element. break; } __local_result = __selector._M_sequential_algorithm (__begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred); if (__local_result.first != (__begin1 + __stop)) { omp_set_lock(&__result_lock); if ((__local_result.first - __begin1) < __result) { __result = __local_result.first - __begin1; // Result cannot be in future blocks, stop algorithm. __fetch_and_add<_DifferenceType>(&__next_block_start, __length); } omp_unset_lock(&__result_lock); } _DifferenceType __block_size = std::max<_DifferenceType>(1, __scale_factor * __next_block_start); // Get new block, update pointer to next block. __start = __fetch_and_add<_DifferenceType>(&__next_block_start, __block_size); __stop = std::min<_DifferenceType>(__length, __start + __block_size); } } //parallel omp_destroy_lock(&__result_lock); // Return iterator on found element. return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif #if _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS /** * @brief Parallel std::find, constant block size variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. * @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_block_size * There are two main differences between the growing blocks and the * constant-size blocks variants. * 1. For GB, the block size grows; for CSB, the block size is fixed. * 2. For GB, the blocks are allocated dynamically; for CSB, the * blocks are allocated in a predetermined manner, namely spacial * round-robin. */ template std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, constant_size_blocks_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; const _Settings& __s = _Settings::get(); _DifferenceType __length = __end1 - __begin1; _DifferenceType __sequential_search_size = std::min<_DifferenceType> (__length, __s.find_sequential_search_size); // Try it sequentially first. std::pair<_RAIter1, _RAIter2> __find_seq_result = __selector._M_sequential_algorithm (__begin1, __begin1 + __sequential_search_size, __begin2, __pred); if (__find_seq_result.first != (__begin1 + __sequential_search_size)) return __find_seq_result; _DifferenceType __result = __length; omp_lock_t __result_lock; omp_init_lock(&__result_lock); // Not within first __sequential_search_size elements -> start parallel. _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel shared(__result) num_threads(__num_threads) { # pragma omp single __num_threads = omp_get_num_threads(); _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __block_size = __s.find_initial_block_size; // First element of thread's current iteration. _DifferenceType __iteration_start = __sequential_search_size; // Where to work (initialization). _DifferenceType __start = __iteration_start + __iam * __block_size; _DifferenceType __stop = std::min<_DifferenceType>(__length, __start + __block_size); std::pair<_RAIter1, _RAIter2> __local_result; while (__start < __length) { // Get new value of result. # pragma omp flush(__result) // No chance to find first element. if (__result < __start) break; __local_result = __selector._M_sequential_algorithm (__begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred); if (__local_result.first != (__begin1 + __stop)) { omp_set_lock(&__result_lock); if ((__local_result.first - __begin1) < __result) __result = __local_result.first - __begin1; omp_unset_lock(&__result_lock); // Will not find better value in its interval. break; } __iteration_start += __num_threads * __block_size; // Where to work. __start = __iteration_start + __iam * __block_size; __stop = std::min<_DifferenceType>(__length, __start + __block_size); } } //parallel omp_destroy_lock(&__result_lock); // Return iterator on found element. return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif } // end namespace #endif /* _GLIBCXX_PARALLEL_FIND_H */ PKgd1]8/parallel/list_partition.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/list_partition.h * @brief _Functionality to split __sequence referenced by only input * iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Leonor Frias Moya and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_LIST_PARTITION_H #define _GLIBCXX_PARALLEL_LIST_PARTITION_H 1 #include #include namespace __gnu_parallel { /** @brief Shrinks and doubles the ranges. * @param __os_starts Start positions worked on (oversampled). * @param __count_to_two Counts up to 2. * @param __range_length Current length of a chunk. * @param __make_twice Whether the @c __os_starts is allowed to be * grown or not */ template void __shrink_and_double(std::vector<_IIter>& __os_starts, size_t& __count_to_two, size_t& __range_length, const bool __make_twice) { ++__count_to_two; if (!__make_twice || __count_to_two < 2) __shrink(__os_starts, __count_to_two, __range_length); else { __os_starts.resize((__os_starts.size() - 1) * 2 + 1); __count_to_two = 0; } } /** @brief Combines two ranges into one and thus halves the number of ranges. * @param __os_starts Start positions worked on (oversampled). * @param __count_to_two Counts up to 2. * @param __range_length Current length of a chunk. */ template void __shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two, size_t& __range_length) { for (typename std::vector<_IIter>::size_type __i = 0; __i <= (__os_starts.size() / 2); ++__i) __os_starts[__i] = __os_starts[__i * 2]; __range_length *= 2; } /** @brief Splits a sequence given by input iterators into parts of * almost equal size * * The function needs only one pass over the sequence. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __starts Start iterators for the resulting parts, dimension * @c __num_parts+1. For convenience, @c __starts @c [__num_parts] * contains the end iterator of the sequence. * @param __lengths Length of the resulting parts. * @param __num_parts Number of parts to split the sequence into. * @param __f Functor to be applied to each element by traversing __it * @param __oversampling Oversampling factor. If 0, then the * partitions will differ in at most * \f$\sqrt{\mathrm{end} - \mathrm{begin}}\f$ * elements. Otherwise, the ratio between the * longest and the shortest part is bounded by * \f$1/(\mathrm{oversampling} \cdot \mathrm{num\_parts})\f$ * @return Length of the whole sequence. */ template size_t list_partition(const _IIter __begin, const _IIter __end, _IIter* __starts, size_t* __lengths, const int __num_parts, _FunctorType& __f, int __oversampling = 0) { bool __make_twice = false; // The resizing algorithm is chosen according to the oversampling factor. if (__oversampling == 0) { __make_twice = true; __oversampling = 1; } std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1); __os_starts[0] = __begin; _IIter __prev = __begin, __it = __begin; size_t __dist_limit = 0, __dist = 0; size_t __cur = 1, __next = 1; size_t __range_length = 1; size_t __count_to_two = 0; while (__it != __end) { __cur = __next; for (; __cur < __os_starts.size() and __it != __end; ++__cur) { for (__dist_limit += __range_length; __dist < __dist_limit and __it != __end; ++__dist) { __f(__it); ++__it; } __os_starts[__cur] = __it; } // Must compare for end and not __cur < __os_starts.size() , because // __cur could be == __os_starts.size() as well if (__it == __end) break; __shrink_and_double(__os_starts, __count_to_two, __range_length, __make_twice); __next = __os_starts.size() / 2 + 1; } // Calculation of the parts (one must be extracted from __current // because the partition beginning at end, consists only of // itself). size_t __size_part = (__cur - 1) / __num_parts; int __size_greater = static_cast((__cur - 1) % __num_parts); __starts[0] = __os_starts[0]; size_t __index = 0; // Smallest partitions. for (int __i = 1; __i < (__num_parts + 1 - __size_greater); ++__i) { __lengths[__i - 1] = __size_part * __range_length; __index += __size_part; __starts[__i] = __os_starts[__index]; } // Biggest partitions. for (int __i = __num_parts + 1 - __size_greater; __i <= __num_parts; ++__i) { __lengths[__i - 1] = (__size_part+1) * __range_length; __index += (__size_part+1); __starts[__i] = __os_starts[__index]; } // Correction of the end size (the end iteration has not finished). __lengths[__num_parts - 1] -= (__dist_limit - __dist); return __dist; } } #endif /* _GLIBCXX_PARALLEL_LIST_PARTITION_H */ PKgd1]4]}}8/parallel/algorithmfwd.hnu[// Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algorithmfwd.h * This file is a GNU parallel extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PARALLEL_ALGORITHMFWD_H #define _GLIBCXX_PARALLEL_ALGORITHMFWD_H 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { template _FIter adjacent_find(_FIter, _FIter); template _FIter adjacent_find(_FIter, _FIter, __gnu_parallel::sequential_tag); template _FIter __adjacent_find_switch(_FIter, _FIter, _IterTag); template _RAIter __adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag); template _FIter adjacent_find(_FIter, _FIter, _BiPredicate); template _FIter adjacent_find(_FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag); template _FIter __adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag); template _RAIter __adjacent_find_switch(_RAIter, _RAIter, _BiPredicate, random_access_iterator_tag); template typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&); template typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&, __gnu_parallel::sequential_tag); template typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&, __gnu_parallel::_Parallelism); template typename iterator_traits<_IIter>::difference_type __count_switch(_IIter, _IIter, const _Tp&, _IterTag); template typename iterator_traits<_RAIter>::difference_type __count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate); template typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate, __gnu_parallel::sequential_tag); template typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate, __gnu_parallel::_Parallelism); template typename iterator_traits<_IIter>::difference_type __count_if_switch(_IIter, _IIter, _Predicate, _IterTag); template typename iterator_traits<_RAIter>::difference_type __count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); // algobase.h template bool equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); template bool equal(_IIter1, _IIter1, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template bool equal(_IIter1, _IIter1, _IIter2); template bool equal(_IIter1, _IIter1, _IIter2, _Predicate); template _IIter find(_IIter, _IIter, const _Tp&, __gnu_parallel::sequential_tag); template _IIter find(_IIter, _IIter, const _Tp& __val); template _IIter __find_switch(_IIter, _IIter, const _Tp&, _IterTag); template _RAIter __find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag); template _IIter find_if(_IIter, _IIter, _Predicate, __gnu_parallel::sequential_tag); template _IIter find_if(_IIter, _IIter, _Predicate); template _IIter __find_if_switch(_IIter, _IIter, _Predicate, _IterTag); template _RAIter __find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, __gnu_parallel::sequential_tag); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter); template _IIter __find_first_of_switch( _IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2); template _RAIter __find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate, random_access_iterator_tag, _IterTag); template _IIter __find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate, _IterTag1, _IterTag2); template _Function for_each(_IIter, _IIter, _Function); template _Function for_each(_IIter, _IIter, _Function, __gnu_parallel::sequential_tag); template _Function for_each(_Iterator, _Iterator, _Function, __gnu_parallel::_Parallelism); template _Function __for_each_switch(_IIter, _IIter, _Function, _IterTag); template _Function __for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template void generate(_FIter, _FIter, _Generator); template void generate(_FIter, _FIter, _Generator, __gnu_parallel::sequential_tag); template void generate(_FIter, _FIter, _Generator, __gnu_parallel::_Parallelism); template void __generate_switch(_FIter, _FIter, _Generator, _IterTag); template void __generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter generate_n(_OIter, _Size, _Generator); template _OIter generate_n(_OIter, _Size, _Generator, __gnu_parallel::sequential_tag); template _OIter generate_n(_OIter, _Size, _Generator, __gnu_parallel::_Parallelism); template _OIter __generate_n_switch(_OIter, _Size, _Generator, _IterTag); template _RAIter __generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, __gnu_parallel::sequential_tag); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate); template bool __lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate, _IterTag1, _IterTag2); template bool __lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Predicate, random_access_iterator_tag, random_access_iterator_tag); // algo.h template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2); template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _Predicate); template pair<_IIter1, _IIter2> __mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate, _IterTag1, _IterTag2); template pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate, random_access_iterator_tag, random_access_iterator_tag); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, __gnu_parallel::sequential_tag); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, __gnu_parallel::sequential_tag); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate); template _RAIter1 __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, random_access_iterator_tag, random_access_iterator_tag); template _FIter1 __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2); template _RAIter1 __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate, random_access_iterator_tag, random_access_iterator_tag); template _FIter1 __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, _IterTag1, _IterTag2); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, __gnu_parallel::sequential_tag); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate, __gnu_parallel::sequential_tag); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate); template _RAIter __search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&, _BiPredicate, random_access_iterator_tag); template _FIter __search_n_switch(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate, _IterTag); template _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation); template _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation, __gnu_parallel::sequential_tag); template _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation, __gnu_parallel::_Parallelism); template _OIter __transform1_switch(_IIter, _IIter, _OIter, _UnaryOperation, _IterTag1, _IterTag2); template _RAOIter __transform1_switch(_RAIIter, _RAIIter, _RAOIter, _UnaryOperation, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation); template _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __gnu_parallel::sequential_tag); template _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __gnu_parallel::_Parallelism); template _RAIter3 __transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter __transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, _Tag1, _Tag2, _Tag3); template void replace(_FIter, _FIter, const _Tp&, const _Tp&); template void replace(_FIter, _FIter, const _Tp&, const _Tp&, __gnu_parallel::sequential_tag); template void replace(_FIter, _FIter, const _Tp&, const _Tp&, __gnu_parallel::_Parallelism); template void __replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag); template void __replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism); template void replace_if(_FIter, _FIter, _Predicate, const _Tp&); template void replace_if(_FIter, _FIter, _Predicate, const _Tp&, __gnu_parallel::sequential_tag); template void replace_if(_FIter, _FIter, _Predicate, const _Tp&, __gnu_parallel::_Parallelism); template void __replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag); template void __replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism); template _FIter max_element(_FIter, _FIter); template _FIter max_element(_FIter, _FIter, __gnu_parallel::sequential_tag); template _FIter max_element(_FIter, _FIter, __gnu_parallel::_Parallelism); template _FIter max_element(_FIter, _FIter, _Compare); template _FIter max_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag); template _FIter max_element(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism); template _FIter __max_element_switch(_FIter, _FIter, _Compare, _IterTag); template _RAIter __max_element_switch( _RAIter, _RAIter, _Compare, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, __gnu_parallel::sequential_tag); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, _IterTag1, _IterTag2, _IterTag3); template _OIter __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _FIter min_element(_FIter, _FIter); template _FIter min_element(_FIter, _FIter, __gnu_parallel::sequential_tag); template _FIter min_element(_FIter, _FIter, __gnu_parallel::_Parallelism __parallelism_tag); template _FIter min_element(_FIter, _FIter, _Compare); template _FIter min_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag); template _FIter min_element(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism); template _FIter __min_element_switch(_FIter, _FIter, _Compare, _IterTag); template _RAIter __min_element_switch( _RAIter, _RAIter, _Compare, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template void nth_element(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag); template void nth_element(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void nth_element(_RAIter, _RAIter, _RAIter, _Compare); template void nth_element(_RAIter, _RAIter, _RAIter); template void partial_sort(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void partial_sort(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag); template void partial_sort(_RAIter, _RAIter, _RAIter, _Compare); template void partial_sort(_RAIter, _RAIter, _RAIter); template _FIter partition(_FIter, _FIter, _Predicate, __gnu_parallel::sequential_tag); template _FIter partition(_FIter, _FIter, _Predicate); template _FIter __partition_switch(_FIter, _FIter, _Predicate, _IterTag); template _RAIter __partition_switch( _RAIter, _RAIter, _Predicate, random_access_iterator_tag); template void random_shuffle(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template void random_shuffle(_RAIter, _RAIter, _RandomNumberGenerator&, __gnu_parallel::sequential_tag); template void random_shuffle(_RAIter, _RAIter); template void random_shuffle(_RAIter, _RAIter, #if __cplusplus >= 201103L _RandomNumberGenerator&&); #else _RandomNumberGenerator&); #endif template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template void sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template void sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void sort(_RAIter, _RAIter); template void sort(_RAIter, _RAIter, _Compare); template void stable_sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template void stable_sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void stable_sort(_RAIter, _RAIter); template void stable_sort(_RAIter, _RAIter, _Compare); template _OIter unique_copy(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template _OIter unique_copy(_IIter, _IIter, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter unique_copy(_IIter, _IIter, _OIter); template _OIter unique_copy(_IIter, _IIter, _OIter, _Predicate); template _OIter __unique_copy_switch(_IIter, _IIter, _OIter, _Predicate, _IterTag1, _IterTag2); template _RandomAccess_OIter __unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag); } // end namespace __parallel } // end namespace std #endif /* _GLIBCXX_PARALLEL_ALGORITHMFWD_H */ PKgd1]"  8/parallel/equally_split.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/equally_split.h * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H #define _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H 1 namespace __gnu_parallel { /** @brief function to split a sequence into parts of almost equal size. * * The resulting sequence __s of length __num_threads+1 contains the * splitting positions when splitting the range [0,__n) into parts of * almost equal size (plus minus 1). The first entry is 0, the last * one n. There may result empty parts. * @param __n Number of elements * @param __num_threads Number of parts * @param __s Splitters * @returns End of __splitter sequence, i.e. @c __s+__num_threads+1 */ template _OutputIterator __equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s) { _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads; _DifferenceType __pos = 0; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { *__s++ = __pos; __pos += ((__i < __num_longer_chunks) ? (__chunk_length + 1) : __chunk_length); } *__s++ = __n; return __s; } /** @brief function to split a sequence into parts of almost equal size. * * Returns the position of the splitting point between * thread number __thread_no (included) and * thread number __thread_no+1 (excluded). * @param __n Number of elements * @param __num_threads Number of parts * @param __thread_no Number of threads * @returns splitting point */ template _DifferenceType __equally_split_point(_DifferenceType __n, _ThreadIndex __num_threads, _ThreadIndex __thread_no) { _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads; if (__thread_no < __num_longer_chunks) return __thread_no * (__chunk_length + 1); else return __num_longer_chunks * (__chunk_length + 1) + (__thread_no - __num_longer_chunks) * __chunk_length; } } #endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */ PKgd1]+8/parallel/queue.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/queue.h * @brief Lock-free double-ended queue. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_QUEUE_H #define _GLIBCXX_PARALLEL_QUEUE_H 1 #include #include #include /** @brief Decide whether to declare certain variable volatile in this file. */ #define _GLIBCXX_VOLATILE volatile namespace __gnu_parallel { /**@brief Double-ended queue of bounded size, allowing lock-free * atomic access. push_front() and pop_front() must not be called * concurrently to each other, while pop_back() can be called * concurrently at all times. * @c empty(), @c size(), and @c top() are intentionally not provided. * Calling them would not make sense in a concurrent setting. * @param _Tp Contained element type. */ template class _RestrictedBoundedConcurrentQueue { private: /** @brief Array of elements, seen as cyclic buffer. */ _Tp* _M_base; /** @brief Maximal number of elements contained at the same time. */ _SequenceIndex _M_max_size; /** @brief Cyclic __begin and __end pointers contained in one atomically changeable value. */ _GLIBCXX_VOLATILE _CASable _M_borders; public: /** @brief Constructor. Not to be called concurrent, of course. * @param __max_size Maximal number of elements to be contained. */ _RestrictedBoundedConcurrentQueue(_SequenceIndex __max_size) { _M_max_size = __max_size; _M_base = new _Tp[__max_size]; _M_borders = __encode2(0, 0); #pragma omp flush } /** @brief Destructor. Not to be called concurrent, of course. */ ~_RestrictedBoundedConcurrentQueue() { delete[] _M_base; } /** @brief Pushes one element into the queue at the front end. * Must not be called concurrently with pop_front(). */ void push_front(const _Tp& __t) { _CASable __former_borders = _M_borders; int __former_front, __former_back; __decode2(__former_borders, __former_front, __former_back); *(_M_base + __former_front % _M_max_size) = __t; #if _GLIBCXX_PARALLEL_ASSERTIONS // Otherwise: front - back > _M_max_size eventually. _GLIBCXX_PARALLEL_ASSERT(((__former_front + 1) - __former_back) <= _M_max_size); #endif __fetch_and_add(&_M_borders, __encode2(1, 0)); } /** @brief Pops one element from the queue at the front end. * Must not be called concurrently with pop_front(). */ bool pop_front(_Tp& __t) { int __former_front, __former_back; #pragma omp flush __decode2(_M_borders, __former_front, __former_back); while (__former_front > __former_back) { // Chance. _CASable __former_borders = __encode2(__former_front, __former_back); _CASable __new_borders = __encode2(__former_front - 1, __former_back); if (__compare_and_swap(&_M_borders, __former_borders, __new_borders)) { __t = *(_M_base + (__former_front - 1) % _M_max_size); return true; } #pragma omp flush __decode2(_M_borders, __former_front, __former_back); } return false; } /** @brief Pops one element from the queue at the front end. * Must not be called concurrently with pop_front(). */ bool pop_back(_Tp& __t) //queue behavior { int __former_front, __former_back; #pragma omp flush __decode2(_M_borders, __former_front, __former_back); while (__former_front > __former_back) { // Chance. _CASable __former_borders = __encode2(__former_front, __former_back); _CASable __new_borders = __encode2(__former_front, __former_back + 1); if (__compare_and_swap(&_M_borders, __former_borders, __new_borders)) { __t = *(_M_base + __former_back % _M_max_size); return true; } #pragma omp flush __decode2(_M_borders, __former_front, __former_back); } return false; } }; } //namespace __gnu_parallel #undef _GLIBCXX_VOLATILE #endif /* _GLIBCXX_PARALLEL_QUEUE_H */ PKgd1]m ;V;V8/parallel/multiseq_selection.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/multiseq_selection.h * @brief Functions to find elements of a certain global __rank in * multiple sorted sequences. Also serves for splitting such * sequence sets. * * The algorithm description can be found in * * P. J. Varman, S. D. Scheufler, B. R. Iyer, and G. R. Ricard. * Merging Multiple Lists on Hierarchical-Memory Multiprocessors. * Journal of Parallel and Distributed Computing, 12(2):171–177, 1991. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H #define _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H 1 #include #include #include namespace __gnu_parallel { /** @brief Compare __a pair of types lexicographically, ascending. */ template class _Lexicographic : public std::binary_function, std::pair<_T1, _T2>, bool> { private: _Compare& _M_comp; public: _Lexicographic(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const std::pair<_T1, _T2>& __p1, const std::pair<_T1, _T2>& __p2) const { if (_M_comp(__p1.first, __p2.first)) return true; if (_M_comp(__p2.first, __p1.first)) return false; // Firsts are equal. return __p1.second < __p2.second; } }; /** @brief Compare __a pair of types lexicographically, descending. */ template class _LexicographicReverse : public std::binary_function<_T1, _T2, bool> { private: _Compare& _M_comp; public: _LexicographicReverse(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const std::pair<_T1, _T2>& __p1, const std::pair<_T1, _T2>& __p2) const { if (_M_comp(__p2.first, __p1.first)) return true; if (_M_comp(__p1.first, __p2.first)) return false; // Firsts are equal. return __p2.second < __p1.second; } }; /** * @brief Splits several sorted sequences at a certain global __rank, * resulting in a splitting point for each sequence. * The sequences are passed via a sequence of random-access * iterator pairs, none of the sequences may be empty. If there * are several equal elements across the split, the ones on the * __left side will be chosen from sequences with smaller number. * @param __begin_seqs Begin of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs. * @param __rank The global rank to partition at. * @param __begin_offsets A random-access __sequence __begin where the * __result will be stored in. Each element of the sequence is an * iterator that points to the first element on the greater part of * the respective __sequence. * @param __comp The ordering functor, defaults to std::less<_Tp>. */ template void multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator __begin_offsets, _Compare __comp = std::less< typename std::iterator_traits::value_type:: first_type>::value_type>()) // std::less<_Tp> { _GLIBCXX_CALL(__end_seqs - __begin_seqs) typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type _It; typedef typename std::iterator_traits<_RanSeqs>::difference_type _SeqNumber; typedef typename std::iterator_traits<_It>::difference_type _DifferenceType; typedef typename std::iterator_traits<_It>::value_type _ValueType; _Lexicographic<_ValueType, _SeqNumber, _Compare> __lcomp(__comp); _LexicographicReverse<_ValueType, _SeqNumber, _Compare> __lrcomp(__comp); // Number of sequences, number of elements in total (possibly // including padding). _DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __nn = 0, __nmax, __n, __r; for (_SeqNumber __i = 0; __i < __m; __i++) { __nn += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); _GLIBCXX_PARALLEL_ASSERT( std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second) > 0); } if (__rank == __nn) { for (_SeqNumber __i = 0; __i < __m; __i++) __begin_offsets[__i] = __begin_seqs[__i].second; // Very end. // Return __m - 1; return; } _GLIBCXX_PARALLEL_ASSERT(__m != 0); _GLIBCXX_PARALLEL_ASSERT(__nn != 0); _GLIBCXX_PARALLEL_ASSERT(__rank >= 0); _GLIBCXX_PARALLEL_ASSERT(__rank < __nn); _DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __b = new _DifferenceType[__m]; _DifferenceType __l; __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second); __nmax = __ns[0]; for (_SeqNumber __i = 0; __i < __m; __i++) { __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); __nmax = std::max(__nmax, __ns[__i]); } __r = __rd_log2(__nmax) + 1; // Pad all lists to this length, at least as long as any ns[__i], // equality iff __nmax = 2^__k - 1. __l = (1ULL << __r) - 1; for (_SeqNumber __i = 0; __i < __m; __i++) { __a[__i] = 0; __b[__i] = __l; } __n = __l / 2; // Invariants: // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l #define __S(__i) (__begin_seqs[__i].first) // Initial partition. std::vector > __sample; for (_SeqNumber __i = 0; __i < __m; __i++) if (__n < __ns[__i]) //__sequence long enough __sample.push_back(std::make_pair(__S(__i)[__n], __i)); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp); for (_SeqNumber __i = 0; __i < __m; __i++) //conceptual infinity if (__n >= __ns[__i]) //__sequence too short, conceptual infinity __sample.push_back( std::make_pair(__S(__i)[0] /*__dummy element*/, __i)); _DifferenceType __localrank = __rank / __l; _SeqNumber __j; for (__j = 0; __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j) __a[__sample[__j].second] += __n + 1; for (; __j < __m; __j++) __b[__sample[__j].second] -= __n + 1; // Further refinement. while (__n > 0) { __n /= 2; _SeqNumber __lmax_seq = -1; // to avoid warning const _ValueType* __lmax = 0; // impossible to avoid the warning? for (_SeqNumber __i = 0; __i < __m; __i++) { if (__a[__i] > 0) { if (!__lmax) { __lmax = &(__S(__i)[__a[__i] - 1]); __lmax_seq = __i; } else { // Max, favor rear sequences. if (!__comp(__S(__i)[__a[__i] - 1], *__lmax)) { __lmax = &(__S(__i)[__a[__i] - 1]); __lmax_seq = __i; } } } } _SeqNumber __i; for (__i = 0; __i < __m; __i++) { _DifferenceType __middle = (__b[__i] + __a[__i]) / 2; if (__lmax && __middle < __ns[__i] && __lcomp(std::make_pair(__S(__i)[__middle], __i), std::make_pair(*__lmax, __lmax_seq))) __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]); else __b[__i] -= __n + 1; } _DifferenceType __leftsize = 0; for (_SeqNumber __i = 0; __i < __m; __i++) __leftsize += __a[__i] / (__n + 1); _DifferenceType __skew = __rank / (__n + 1) - __leftsize; if (__skew > 0) { // Move to the left, find smallest. std::priority_queue, std::vector >, _LexicographicReverse<_ValueType, _SeqNumber, _Compare> > __pq(__lrcomp); for (_SeqNumber __i = 0; __i < __m; __i++) if (__b[__i] < __ns[__i]) __pq.push(std::make_pair(__S(__i)[__b[__i]], __i)); for (; __skew != 0 && !__pq.empty(); --__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] = std::min(__a[__source] + __n + 1, __ns[__source]); __b[__source] += __n + 1; if (__b[__source] < __ns[__source]) __pq.push( std::make_pair(__S(__source)[__b[__source]], __source)); } } else if (__skew < 0) { // Move to the right, find greatest. std::priority_queue, std::vector >, _Lexicographic<_ValueType, _SeqNumber, _Compare> > __pq(__lcomp); for (_SeqNumber __i = 0; __i < __m; __i++) if (__a[__i] > 0) __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i)); for (; __skew != 0; ++__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] -= __n + 1; __b[__source] -= __n + 1; if (__a[__source] > 0) __pq.push(std::make_pair( __S(__source)[__a[__source] - 1], __source)); } } } // Postconditions: // __a[__i] == __b[__i] in most cases, except when __a[__i] has been // clamped because of having reached the boundary // Now return the result, calculate the offset. // Compare the keys on both edges of the border. // Maximum of left edge, minimum of right edge. _ValueType* __maxleft = 0; _ValueType* __minright = 0; for (_SeqNumber __i = 0; __i < __m; __i++) { if (__a[__i] > 0) { if (!__maxleft) __maxleft = &(__S(__i)[__a[__i] - 1]); else { // Max, favor rear sequences. if (!__comp(__S(__i)[__a[__i] - 1], *__maxleft)) __maxleft = &(__S(__i)[__a[__i] - 1]); } } if (__b[__i] < __ns[__i]) { if (!__minright) __minright = &(__S(__i)[__b[__i]]); else { // Min, favor fore sequences. if (__comp(__S(__i)[__b[__i]], *__minright)) __minright = &(__S(__i)[__b[__i]]); } } } _SeqNumber __seq = 0; for (_SeqNumber __i = 0; __i < __m; __i++) __begin_offsets[__i] = __S(__i) + __a[__i]; delete[] __ns; delete[] __a; delete[] __b; } /** * @brief Selects the element at a certain global __rank from several * sorted sequences. * * The sequences are passed via a sequence of random-access * iterator pairs, none of the sequences may be empty. * @param __begin_seqs Begin of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs. * @param __rank The global rank to partition at. * @param __offset The rank of the selected element in the global * subsequence of elements equal to the selected element. If the * selected element is unique, this number is 0. * @param __comp The ordering functor, defaults to std::less. */ template _Tp multiseq_selection(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankType& __offset, _Compare __comp = std::less<_Tp>()) { _GLIBCXX_CALL(__end_seqs - __begin_seqs) typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type _It; typedef typename std::iterator_traits<_RanSeqs>::difference_type _SeqNumber; typedef typename std::iterator_traits<_It>::difference_type _DifferenceType; _Lexicographic<_Tp, _SeqNumber, _Compare> __lcomp(__comp); _LexicographicReverse<_Tp, _SeqNumber, _Compare> __lrcomp(__comp); // Number of sequences, number of elements in total (possibly // including padding). _DifferenceType __m = std::distance(__begin_seqs, __end_seqs); _DifferenceType __nn = 0; _DifferenceType __nmax, __n, __r; for (_SeqNumber __i = 0; __i < __m; __i++) __nn += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); if (__m == 0 || __nn == 0 || __rank < 0 || __rank >= __nn) { // result undefined if there is no data or __rank is outside bounds throw std::exception(); } _DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __b = new _DifferenceType[__m]; _DifferenceType __l; __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second); __nmax = __ns[0]; for (_SeqNumber __i = 0; __i < __m; ++__i) { __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); __nmax = std::max(__nmax, __ns[__i]); } __r = __rd_log2(__nmax) + 1; // Pad all lists to this length, at least as long as any ns[__i], // equality iff __nmax = 2^__k - 1 __l = __round_up_to_pow2(__r) - 1; for (_SeqNumber __i = 0; __i < __m; ++__i) { __a[__i] = 0; __b[__i] = __l; } __n = __l / 2; // Invariants: // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l #define __S(__i) (__begin_seqs[__i].first) // Initial partition. std::vector > __sample; for (_SeqNumber __i = 0; __i < __m; __i++) if (__n < __ns[__i]) __sample.push_back(std::make_pair(__S(__i)[__n], __i)); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp, sequential_tag()); // Conceptual infinity. for (_SeqNumber __i = 0; __i < __m; __i++) if (__n >= __ns[__i]) __sample.push_back( std::make_pair(__S(__i)[0] /*__dummy element*/, __i)); _DifferenceType __localrank = __rank / __l; _SeqNumber __j; for (__j = 0; __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j) __a[__sample[__j].second] += __n + 1; for (; __j < __m; ++__j) __b[__sample[__j].second] -= __n + 1; // Further refinement. while (__n > 0) { __n /= 2; const _Tp* __lmax = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) { if (__a[__i] > 0) { if (!__lmax) __lmax = &(__S(__i)[__a[__i] - 1]); else { if (__comp(*__lmax, __S(__i)[__a[__i] - 1])) //max __lmax = &(__S(__i)[__a[__i] - 1]); } } } _SeqNumber __i; for (__i = 0; __i < __m; __i++) { _DifferenceType __middle = (__b[__i] + __a[__i]) / 2; if (__lmax && __middle < __ns[__i] && __comp(__S(__i)[__middle], *__lmax)) __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]); else __b[__i] -= __n + 1; } _DifferenceType __leftsize = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) __leftsize += __a[__i] / (__n + 1); _DifferenceType __skew = __rank / (__n + 1) - __leftsize; if (__skew > 0) { // Move to the left, find smallest. std::priority_queue, std::vector >, _LexicographicReverse<_Tp, _SeqNumber, _Compare> > __pq(__lrcomp); for (_SeqNumber __i = 0; __i < __m; ++__i) if (__b[__i] < __ns[__i]) __pq.push(std::make_pair(__S(__i)[__b[__i]], __i)); for (; __skew != 0 && !__pq.empty(); --__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] = std::min(__a[__source] + __n + 1, __ns[__source]); __b[__source] += __n + 1; if (__b[__source] < __ns[__source]) __pq.push( std::make_pair(__S(__source)[__b[__source]], __source)); } } else if (__skew < 0) { // Move to the right, find greatest. std::priority_queue, std::vector >, _Lexicographic<_Tp, _SeqNumber, _Compare> > __pq(__lcomp); for (_SeqNumber __i = 0; __i < __m; ++__i) if (__a[__i] > 0) __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i)); for (; __skew != 0; ++__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] -= __n + 1; __b[__source] -= __n + 1; if (__a[__source] > 0) __pq.push(std::make_pair( __S(__source)[__a[__source] - 1], __source)); } } } // Postconditions: // __a[__i] == __b[__i] in most cases, except when __a[__i] has been // clamped because of having reached the boundary // Now return the result, calculate the offset. // Compare the keys on both edges of the border. // Maximum of left edge, minimum of right edge. bool __maxleftset = false, __minrightset = false; // Impossible to avoid the warning? _Tp __maxleft, __minright; for (_SeqNumber __i = 0; __i < __m; ++__i) { if (__a[__i] > 0) { if (!__maxleftset) { __maxleft = __S(__i)[__a[__i] - 1]; __maxleftset = true; } else { // Max. if (__comp(__maxleft, __S(__i)[__a[__i] - 1])) __maxleft = __S(__i)[__a[__i] - 1]; } } if (__b[__i] < __ns[__i]) { if (!__minrightset) { __minright = __S(__i)[__b[__i]]; __minrightset = true; } else { // Min. if (__comp(__S(__i)[__b[__i]], __minright)) __minright = __S(__i)[__b[__i]]; } } } // Minright is the __splitter, in any case. if (!__maxleftset || __comp(__minright, __maxleft)) { // Good luck, everything is split unambiguously. __offset = 0; } else { // We have to calculate an offset. __offset = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) { _DifferenceType lb = std::lower_bound(__S(__i), __S(__i) + __ns[__i], __minright, __comp) - __S(__i); __offset += __a[__i] - lb; } } delete[] __ns; delete[] __a; delete[] __b; return __minright; } } #undef __S #endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */ PKgd1], 8/parallel/sort.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/sort.h * @brief Parallel sorting algorithm switch. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_SORT_H #define _GLIBCXX_PARALLEL_SORT_H 1 #include #include #include #if _GLIBCXX_PARALLEL_ASSERTIONS #include #endif #if _GLIBCXX_MERGESORT #include #endif #if _GLIBCXX_QUICKSORT #include #endif #if _GLIBCXX_BAL_QUICKSORT #include #endif namespace __gnu_parallel { //prototype template void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism); /** * @brief Choose multiway mergesort, splitting variant at run-time, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) if(_Settings::get().sort_splitting == EXACT) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); else parallel_sort_mwms<__stable, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with exact splitting, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_exact_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with splitting by sampling, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_sampling_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) parallel_sort_mwms<__stable, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose quicksort for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, quicksort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) _GLIBCXX_PARALLEL_ASSERT(__stable == false); __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose balanced quicksort for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, balanced_quicksort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) _GLIBCXX_PARALLEL_ASSERT(__stable == false); __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with exact splitting, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, default_parallel_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) __parallel_sort<__stable> (__begin, __end, __comp, multiway_mergesort_exact_tag(__parallelism.__get_num_threads())); } /** * @brief Choose a parallel sorting algorithm. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, parallel_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (false) ; #if _GLIBCXX_MERGESORT else if (__stable || _Settings::get().sort_algorithm == MWMS) { if(_Settings::get().sort_splitting == EXACT) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); else parallel_sort_mwms (__begin, __end, __comp, __parallelism.__get_num_threads()); } #endif #if _GLIBCXX_QUICKSORT else if (_Settings::get().sort_algorithm == QS) __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads()); #endif #if _GLIBCXX_BAL_QUICKSORT else if (_Settings::get().sort_algorithm == QS_BALANCED) __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads()); #endif else __gnu_sequential::sort(__begin, __end, __comp); } } // end namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_SORT_H */ PKgd1];Ƨ;;8/parallel/multiway_mergesort.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/multiway_mergesort.h * @brief Parallel multiway merge sort. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H #define _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H 1 #include #include #include #include #include namespace __gnu_parallel { /** @brief Subsequence description. */ template struct _Piece { typedef _DifferenceTp _DifferenceType; /** @brief Begin of subsequence. */ _DifferenceType _M_begin; /** @brief End of subsequence. */ _DifferenceType _M_end; }; /** @brief Data accessed by all threads. * * PMWMS = parallel multiway mergesort */ template struct _PMWMSSortingData { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Number of threads involved. */ _ThreadIndex _M_num_threads; /** @brief Input __begin. */ _RAIter _M_source; /** @brief Start indices, per thread. */ _DifferenceType* _M_starts; /** @brief Storage in which to sort. */ _ValueType** _M_temporary; /** @brief Samples. */ _ValueType* _M_samples; /** @brief Offsets to add to the found positions. */ _DifferenceType* _M_offsets; /** @brief Pieces of data to merge @c [thread][__sequence] */ std::vector<_Piece<_DifferenceType> >* _M_pieces; }; /** * @brief Select _M_samples from a sequence. * @param __sd Pointer to algorithm data. _Result will be placed in * @c __sd->_M_samples. * @param __num_samples Number of _M_samples to select. */ template void __determine_samples(_PMWMSSortingData<_RAIter>* __sd, _DifferenceTp __num_samples) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef _DifferenceTp _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType* __es = new _DifferenceType[__num_samples + 2]; __equally_split(__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam], __num_samples + 1, __es); for (_DifferenceType __i = 0; __i < __num_samples; ++__i) ::new(&(__sd->_M_samples[__iam * __num_samples + __i])) _ValueType(__sd->_M_source[__sd->_M_starts[__iam] + __es[__i + 1]]); delete[] __es; } /** @brief Split consistently. */ template struct _SplitConsistently { }; /** @brief Split by exact splitting. */ template struct _SplitConsistently { void operator()(const _ThreadIndex __iam, _PMWMSSortingData<_RAIter>* __sd, _Compare& __comp, const typename std::iterator_traits<_RAIter>::difference_type __num_samples) const { # pragma omp barrier std::vector > __seqs(__sd->_M_num_threads); for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) __seqs[__s] = std::make_pair(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s])); std::vector<_SortingPlacesIterator> __offsets(__sd->_M_num_threads); // if not last thread if (__iam < __sd->_M_num_threads - 1) multiseq_partition(__seqs.begin(), __seqs.end(), __sd->_M_starts[__iam + 1], __offsets.begin(), __comp); for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++) { // for each sequence if (__iam < (__sd->_M_num_threads - 1)) __sd->_M_pieces[__iam][__seq]._M_end = __offsets[__seq] - __seqs[__seq].first; else // very end of this sequence __sd->_M_pieces[__iam][__seq]._M_end = __sd->_M_starts[__seq + 1] - __sd->_M_starts[__seq]; } # pragma omp barrier for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++) { // For each sequence. if (__iam > 0) __sd->_M_pieces[__iam][__seq]._M_begin = __sd->_M_pieces[__iam - 1][__seq]._M_end; else // Absolute beginning. __sd->_M_pieces[__iam][__seq]._M_begin = 0; } } }; /** @brief Split by sampling. */ template struct _SplitConsistently { void operator()(const _ThreadIndex __iam, _PMWMSSortingData<_RAIter>* __sd, _Compare& __comp, const typename std::iterator_traits<_RAIter>::difference_type __num_samples) const { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; __determine_samples(__sd, __num_samples); # pragma omp barrier # pragma omp single __gnu_sequential::sort(__sd->_M_samples, __sd->_M_samples + (__num_samples * __sd->_M_num_threads), __comp); # pragma omp barrier for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s) { // For each sequence. if (__num_samples * __iam > 0) __sd->_M_pieces[__iam][__s]._M_begin = std::lower_bound(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]), __sd->_M_samples[__num_samples * __iam], __comp) - __sd->_M_temporary[__s]; else // Absolute beginning. __sd->_M_pieces[__iam][__s]._M_begin = 0; if ((__num_samples * (__iam + 1)) < (__num_samples * __sd->_M_num_threads)) __sd->_M_pieces[__iam][__s]._M_end = std::lower_bound(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]), __sd->_M_samples[__num_samples * (__iam + 1)], __comp) - __sd->_M_temporary[__s]; else // Absolute end. __sd->_M_pieces[__iam][__s]._M_end = (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]); } } }; template struct __possibly_stable_sort { }; template struct __possibly_stable_sort { void operator()(const _RAIter& __begin, const _RAIter& __end, _Compare& __comp) const { __gnu_sequential::stable_sort(__begin, __end, __comp); } }; template struct __possibly_stable_sort { void operator()(const _RAIter __begin, const _RAIter __end, _Compare& __comp) const { __gnu_sequential::sort(__begin, __end, __comp); } }; template struct __possibly_stable_multiway_merge { }; template struct __possibly_stable_multiway_merge { void operator()(const Seq_RAIter& __seqs_begin, const Seq_RAIter& __seqs_end, const _RAIter& __target, _Compare& __comp, _DiffType __length_am) const { stable_multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, sequential_tag()); } }; template struct __possibly_stable_multiway_merge { void operator()(const Seq_RAIter& __seqs_begin, const Seq_RAIter& __seqs_end, const _RAIter& __target, _Compare& __comp, _DiffType __length_am) const { multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, sequential_tag()); } }; /** @brief PMWMS code executed by each thread. * @param __sd Pointer to algorithm data. * @param __comp Comparator. */ template void parallel_sort_mwms_pu(_PMWMSSortingData<_RAIter>* __sd, _Compare& __comp) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); // Length of this thread's chunk, before merging. _DifferenceType __length_local = __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]; // Sort in temporary storage, leave space for sentinel. typedef _ValueType* _SortingPlacesIterator; __sd->_M_temporary[__iam] = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * (__length_local + 1))); // Copy there. std::uninitialized_copy(__sd->_M_source + __sd->_M_starts[__iam], __sd->_M_source + __sd->_M_starts[__iam] + __length_local, __sd->_M_temporary[__iam]); __possibly_stable_sort<__stable, _SortingPlacesIterator, _Compare>() (__sd->_M_temporary[__iam], __sd->_M_temporary[__iam] + __length_local, __comp); // Invariant: locally sorted subsequence in sd->_M_temporary[__iam], // __sd->_M_temporary[__iam] + __length_local. // No barrier here: Synchronization is done by the splitting routine. _DifferenceType __num_samples = _Settings::get().sort_mwms_oversampling * __sd->_M_num_threads - 1; _SplitConsistently<__exact, _RAIter, _Compare, _SortingPlacesIterator>() (__iam, __sd, __comp, __num_samples); // Offset from __target __begin, __length after merging. _DifferenceType __offset = 0, __length_am = 0; for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) { __length_am += (__sd->_M_pieces[__iam][__s]._M_end - __sd->_M_pieces[__iam][__s]._M_begin); __offset += __sd->_M_pieces[__iam][__s]._M_begin; } typedef std::vector< std::pair<_SortingPlacesIterator, _SortingPlacesIterator> > _SeqVector; _SeqVector __seqs(__sd->_M_num_threads); for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s) { __seqs[__s] = std::make_pair(__sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_begin, __sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_end); } __possibly_stable_multiway_merge< __stable, typename _SeqVector::iterator, _RAIter, _Compare, _DifferenceType>()(__seqs.begin(), __seqs.end(), __sd->_M_source + __offset, __comp, __length_am); # pragma omp barrier for (_DifferenceType __i = 0; __i < __length_local; ++__i) __sd->_M_temporary[__iam][__i].~_ValueType(); ::operator delete(__sd->_M_temporary[__iam]); } /** @brief PMWMS main call. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @param __num_threads Number of threads to use. */ template void parallel_sort_mwms(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; if (__n <= 1) return; // at least one element per thread if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); // shared variables _PMWMSSortingData<_RAIter> __sd; _DifferenceType* __starts; _DifferenceType __size; # pragma omp parallel num_threads(__num_threads) { __num_threads = omp_get_num_threads(); //no more threads than requested # pragma omp single { __sd._M_num_threads = __num_threads; __sd._M_source = __begin; __sd._M_temporary = new _ValueType*[__num_threads]; if (!__exact) { __size = (_Settings::get().sort_mwms_oversampling * __num_threads - 1) * __num_threads; __sd._M_samples = static_cast<_ValueType*> (::operator new(__size * sizeof(_ValueType))); } else __sd._M_samples = 0; __sd._M_offsets = new _DifferenceType[__num_threads - 1]; __sd._M_pieces = new std::vector<_Piece<_DifferenceType> >[__num_threads]; for (_ThreadIndex __s = 0; __s < __num_threads; ++__s) __sd._M_pieces[__s].resize(__num_threads); __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1]; _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __split = __n % __num_threads; _DifferenceType __pos = 0; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __starts[__i] = __pos; __pos += ((__i < __split) ? (__chunk_length + 1) : __chunk_length); } __starts[__num_threads] = __pos; } //single // Now sort in parallel. parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp); } //parallel delete[] __starts; delete[] __sd._M_temporary; if (!__exact) { for (_DifferenceType __i = 0; __i < __size; ++__i) __sd._M_samples[__i].~_ValueType(); ::operator delete(__sd._M_samples); } delete[] __sd._M_offsets; delete[] __sd._M_pieces; } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H */ PKgd1]ت008/parallel/settings.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/settings.h * @brief Runtime settings and tuning parameters, heuristics to decide * whether to use parallelized algorithms. * This file is a GNU parallel extension to the Standard C++ Library. * * @section parallelization_decision * The decision whether to run an algorithm in parallel. * * There are several ways the user can switch on and __off the parallel * execution of an algorithm, both at compile- and run-time. * * Only sequential execution can be forced at compile-time. This * reduces code size and protects code parts that have * non-thread-safe side effects. * * Ultimately, forcing parallel execution at compile-time makes * sense. Often, the sequential algorithm implementation is used as * a subroutine, so no reduction in code size can be achieved. Also, * the machine the program is run on might have only one processor * core, so to avoid overhead, the algorithm is executed * sequentially. * * To force sequential execution of an algorithm ultimately at * compile-time, the user must add the tag * gnu_parallel::sequential_tag() to the end of the parameter list, * e. g. * * \code * std::sort(__v.begin(), __v.end(), __gnu_parallel::sequential_tag()); * \endcode * * This is compatible with all overloaded algorithm variants. No * additional code will be instantiated, at all. The same holds for * most algorithm calls with iterators not providing random access. * * If the algorithm call is not forced to be executed sequentially * at compile-time, the decision is made at run-time. * The global variable __gnu_parallel::_Settings::algorithm_strategy * is checked. _It is a tristate variable corresponding to: * * a. force_sequential, meaning the sequential algorithm is executed. * b. force_parallel, meaning the parallel algorithm is executed. * c. heuristic * * For heuristic, the parallel algorithm implementation is called * only if the input size is sufficiently large. For most * algorithms, the input size is the (combined) length of the input * sequence(__s). The threshold can be set by the user, individually * for each algorithm. The according variables are called * gnu_parallel::_Settings::[algorithm]_minimal_n . * * For some of the algorithms, there are even more tuning options, * e. g. the ability to choose from multiple algorithm variants. See * below for details. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_SETTINGS_H #define _GLIBCXX_PARALLEL_SETTINGS_H 1 #include /** * @brief Determine at compile(?)-time if the parallel variant of an * algorithm should be called. * @param __c A condition that is convertible to bool that is overruled by * __gnu_parallel::_Settings::algorithm_strategy. Usually a decision * based on the input size. */ #define _GLIBCXX_PARALLEL_CONDITION(__c) \ (__gnu_parallel::_Settings::get().algorithm_strategy \ != __gnu_parallel::force_sequential \ && ((__gnu_parallel::__get_max_threads() > 1 && (__c)) \ || __gnu_parallel::_Settings::get().algorithm_strategy \ == __gnu_parallel::force_parallel)) /* inline bool parallel_condition(bool __c) { bool ret = false; const _Settings& __s = _Settings::get(); if (__s.algorithm_strategy != force_seqential) { if (__s.algorithm_strategy == force_parallel) ret = true; else ret = __get_max_threads() > 1 && __c; } return ret; } */ namespace __gnu_parallel { /// class _Settings /// Run-time settings for the parallel mode including all tunable parameters. struct _Settings { _AlgorithmStrategy algorithm_strategy; _SortAlgorithm sort_algorithm; _PartialSumAlgorithm partial_sum_algorithm; _MultiwayMergeAlgorithm multiway_merge_algorithm; _FindAlgorithm find_algorithm; _SplittingAlgorithm sort_splitting; _SplittingAlgorithm merge_splitting; _SplittingAlgorithm multiway_merge_splitting; // Per-algorithm settings. /// Minimal input size for accumulate. _SequenceIndex accumulate_minimal_n; /// Minimal input size for adjacent_difference. unsigned int adjacent_difference_minimal_n; /// Minimal input size for count and count_if. _SequenceIndex count_minimal_n; /// Minimal input size for fill. _SequenceIndex fill_minimal_n; /// Block size increase factor for find. double find_increasing_factor; /// Initial block size for find. _SequenceIndex find_initial_block_size; /// Maximal block size for find. _SequenceIndex find_maximum_block_size; /// Start with looking for this many elements sequentially, for find. _SequenceIndex find_sequential_search_size; /// Minimal input size for for_each. _SequenceIndex for_each_minimal_n; /// Minimal input size for generate. _SequenceIndex generate_minimal_n; /// Minimal input size for max_element. _SequenceIndex max_element_minimal_n; /// Minimal input size for merge. _SequenceIndex merge_minimal_n; /// Oversampling factor for merge. unsigned int merge_oversampling; /// Minimal input size for min_element. _SequenceIndex min_element_minimal_n; /// Minimal input size for multiway_merge. _SequenceIndex multiway_merge_minimal_n; /// Oversampling factor for multiway_merge. int multiway_merge_minimal_k; /// Oversampling factor for multiway_merge. unsigned int multiway_merge_oversampling; /// Minimal input size for nth_element. _SequenceIndex nth_element_minimal_n; /// Chunk size for partition. _SequenceIndex partition_chunk_size; /// Chunk size for partition, relative to input size. If > 0.0, /// this value overrides partition_chunk_size. double partition_chunk_share; /// Minimal input size for partition. _SequenceIndex partition_minimal_n; /// Minimal input size for partial_sort. _SequenceIndex partial_sort_minimal_n; /// Ratio for partial_sum. Assume "sum and write result" to be /// this factor slower than just "sum". float partial_sum_dilation; /// Minimal input size for partial_sum. unsigned int partial_sum_minimal_n; /// Minimal input size for random_shuffle. unsigned int random_shuffle_minimal_n; /// Minimal input size for replace and replace_if. _SequenceIndex replace_minimal_n; /// Minimal input size for set_difference. _SequenceIndex set_difference_minimal_n; /// Minimal input size for set_intersection. _SequenceIndex set_intersection_minimal_n; /// Minimal input size for set_symmetric_difference. _SequenceIndex set_symmetric_difference_minimal_n; /// Minimal input size for set_union. _SequenceIndex set_union_minimal_n; /// Minimal input size for parallel sorting. _SequenceIndex sort_minimal_n; /// Oversampling factor for parallel std::sort (MWMS). unsigned int sort_mwms_oversampling; /// Such many samples to take to find a good pivot (quicksort). unsigned int sort_qs_num_samples_preset; /// Maximal subsequence __length to switch to unbalanced __base case. /// Applies to std::sort with dynamically load-balanced quicksort. _SequenceIndex sort_qsb_base_case_maximal_n; /// Minimal input size for parallel std::transform. _SequenceIndex transform_minimal_n; /// Minimal input size for unique_copy. _SequenceIndex unique_copy_minimal_n; _SequenceIndex workstealing_chunk_size; // Hardware dependent tuning parameters. /// size of the L1 cache in bytes (underestimation). unsigned long long L1_cache_size; /// size of the L2 cache in bytes (underestimation). unsigned long long L2_cache_size; /// size of the Translation Lookaside Buffer (underestimation). unsigned int TLB_size; /// Overestimation of cache line size. Used to avoid false /// sharing, i.e. elements of different threads are at least this /// amount apart. unsigned int cache_line_size; // Statistics. /// The number of stolen ranges in load-balanced quicksort. _SequenceIndex qsb_steals; /// Minimal input size for search and search_n. _SequenceIndex search_minimal_n; /// Block size scale-down factor with respect to current position. float find_scale_factor; /// Get the global settings. _GLIBCXX_CONST static const _Settings& get() throw(); /// Set the global settings. static void set(_Settings&) throw(); explicit _Settings() : algorithm_strategy(heuristic), sort_algorithm(MWMS), partial_sum_algorithm(LINEAR), multiway_merge_algorithm(LOSER_TREE), find_algorithm(CONSTANT_SIZE_BLOCKS), sort_splitting(EXACT), merge_splitting(EXACT), multiway_merge_splitting(EXACT), accumulate_minimal_n(1000), adjacent_difference_minimal_n(1000), count_minimal_n(1000), fill_minimal_n(1000), find_increasing_factor(2.0), find_initial_block_size(256), find_maximum_block_size(8192), find_sequential_search_size(256), for_each_minimal_n(1000), generate_minimal_n(1000), max_element_minimal_n(1000), merge_minimal_n(1000), merge_oversampling(10), min_element_minimal_n(1000), multiway_merge_minimal_n(1000), multiway_merge_minimal_k(2), multiway_merge_oversampling(10), nth_element_minimal_n(1000), partition_chunk_size(1000), partition_chunk_share(0.0), partition_minimal_n(1000), partial_sort_minimal_n(1000), partial_sum_dilation(1.0f), partial_sum_minimal_n(1000), random_shuffle_minimal_n(1000), replace_minimal_n(1000), set_difference_minimal_n(1000), set_intersection_minimal_n(1000), set_symmetric_difference_minimal_n(1000), set_union_minimal_n(1000), sort_minimal_n(1000), sort_mwms_oversampling(10), sort_qs_num_samples_preset(100), sort_qsb_base_case_maximal_n(100), transform_minimal_n(1000), unique_copy_minimal_n(10000), workstealing_chunk_size(100), L1_cache_size(16 << 10), L2_cache_size(256 << 10), TLB_size(128), cache_line_size(64), qsb_steals(0), search_minimal_n(1000), find_scale_factor(0.01f) { } }; } #endif /* _GLIBCXX_PARALLEL_SETTINGS_H */ PKgd1]u8/parallel/checkers.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/checkers.h * @brief Routines for checking the correctness of algorithm results. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_CHECKERS_H #define _GLIBCXX_PARALLEL_CHECKERS_H 1 #include #include #include namespace __gnu_parallel { /** * @brief Check whether @c [__begin, @c __end) is sorted according * to @c __comp. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @return @c true if sorted, @c false otherwise. */ template bool __is_sorted(_IIter __begin, _IIter __end, _Compare __comp) { if (__begin == __end) return true; _IIter __current(__begin), __recent(__begin); unsigned long long __position = 1; for (__current++; __current != __end; __current++) { if (__comp(*__current, *__recent)) { return false; } __recent = __current; __position++; } return true; } } #endif /* _GLIBCXX_PARALLEL_CHECKERS_H */ PKgd1]84°oo8/parallel/losertree.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/losertree.h * @brief Many generic loser tree variants. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H #define _GLIBCXX_PARALLEL_LOSERTREE_H 1 #include #include #include #include namespace __gnu_parallel { /** * @brief Guarded loser/tournament tree. * * The smallest element is at the top. * * Guarding is done explicitly through one flag _M_sup per element, * inf is not needed due to a better initialization routine. This * is a well-performing variant. * * @param _Tp the element type * @param _Compare the comparator to use, defaults to std::less<_Tp> */ template class _LoserTreeBase { protected: /** @brief Internal representation of a _LoserTree element. */ struct _Loser { /** @brief flag, true iff this is a "maximum" __sentinel. */ bool _M_sup; /** @brief __index of the __source __sequence. */ int _M_source; /** @brief _M_key of the element in the _LoserTree. */ _Tp _M_key; }; unsigned int _M_ik, _M_k, _M_offset; /** log_2{_M_k} */ unsigned int _M_log_k; /** @brief _LoserTree __elements. */ _Loser* _M_losers; /** @brief _Compare to use. */ _Compare _M_comp; /** * @brief State flag that determines whether the _LoserTree is empty. * * Only used for building the _LoserTree. */ bool _M_first_insert; public: /** * @brief The constructor. * * @param __k The number of sequences to merge. * @param __comp The comparator to use. */ _LoserTreeBase(unsigned int __k, _Compare __comp) : _M_comp(__comp) { _M_ik = __k; // Compute log_2{_M_k} for the _Loser Tree _M_log_k = __rd_log2(_M_ik - 1) + 1; // Next greater power of 2. _M_k = 1 << _M_log_k; _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser))); for (unsigned int __i = _M_ik - 1; __i < _M_k; ++__i) _M_losers[__i + _M_k]._M_sup = true; _M_first_insert = true; } /** * @brief The destructor. */ ~_LoserTreeBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } /** * @brief Initializes the sequence "_M_source" with the element "__key". * * @param __key the element to insert * @param __source __index of the __source __sequence * @param __sup flag that determines whether the value to insert is an * explicit __supremum. */ void __insert_start(const _Tp& __key, int __source, bool __sup) { unsigned int __pos = _M_k + __source; if (_M_first_insert) { // Construct all keys, so we can easily destruct them. for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) ::new(&(_M_losers[__i]._M_key)) _Tp(__key); _M_first_insert = false; } else _M_losers[__pos]._M_key = __key; _M_losers[__pos]._M_sup = __sup; _M_losers[__pos]._M_source = __source; } /** * @return the index of the sequence with the smallest element. */ int __get_min_source() { return _M_losers[0]._M_source; } }; /** * @brief Stable _LoserTree variant. * * Provides the stable implementations of insert_start, __init_winner, * __init and __delete_min_insert. * * Unstable variant is done using partial specialisation below. */ template class _LoserTree : public _LoserTreeBase<_Tp, _Compare> { typedef _LoserTreeBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; using _Base::_M_first_insert; public: _LoserTree(unsigned int __k, _Compare __comp) : _Base::_LoserTreeBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } /** * @brief Delete the smallest element and insert a new element from * the previously smallest element's sequence. * * This implementation is stable. */ // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool __sup) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if ((__sup && (!_M_losers[__pos]._M_sup || _M_losers[__pos]._M_source < __source)) || (!__sup && !_M_losers[__pos]._M_sup && ((_M_comp(_M_losers[__pos]._M_key, __key)) || (!_M_comp(__key, _M_losers[__pos]._M_key) && _M_losers[__pos]._M_source < __source)))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Unstable _LoserTree variant. * * Stability (non-stable here) is selected with partial specialization. */ template class _LoserTree : public _LoserTreeBase<_Tp, _Compare> { typedef _LoserTreeBase<_Tp, _Compare> _Base; using _Base::_M_log_k; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; using _Base::_M_first_insert; public: _LoserTree(unsigned int __k, _Compare __comp) : _Base::_LoserTreeBase(__k, __comp) { } /** * Computes the winner of the competition at position "__root". * * Called recursively (starting at 0) to build the initial tree. * * @param __root __index of the "game" to start. */ unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } /** * Delete the _M_key smallest element and insert the element __key * instead. * * @param __key the _M_key to insert * @param __sup true iff __key is an explicitly marked supremum */ // Do not pass a const reference since __key will be used as local // variable. void __delete_min_insert(_Tp __key, bool __sup) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (__sup || (!_M_losers[__pos]._M_sup && _M_comp(_M_losers[__pos]._M_key, __key))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Base class of _Loser Tree implementation using pointers. */ template class _LoserTreePointerBase { protected: /** @brief Internal representation of _LoserTree __elements. */ struct _Loser { bool _M_sup; int _M_source; const _Tp* _M_keyp; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreePointerBase(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; _M_losers = new _Loser[_M_k * 2]; for (unsigned int __i = _M_ik - 1; __i < _M_k; __i++) _M_losers[__i + _M_k]._M_sup = true; } ~_LoserTreePointerBase() { delete[] _M_losers; } int __get_min_source() { return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool __sup) { unsigned int __pos = _M_k + __source; _M_losers[__pos]._M_sup = __sup; _M_losers[__pos]._M_source = __source; _M_losers[__pos]._M_keyp = &__key; } }; /** * @brief Stable _LoserTree implementation. * * The unstable variant is implemented using partial instantiation below. */ template class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare> { typedef _LoserTreePointerBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by __source. if ((__sup && (!_M_losers[__pos]._M_sup || _M_losers[__pos]._M_source < __source)) || (!__sup && !_M_losers[__pos]._M_sup && ((_M_comp(*_M_losers[__pos]._M_keyp, *__keyp)) || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp) && _M_losers[__pos]._M_source < __source)))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** * @brief Unstable _LoserTree implementation. * * The stable variant is above. */ template class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare> { typedef _LoserTreePointerBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (__sup || (!_M_losers[__pos]._M_sup && _M_comp(*_M_losers[__pos]._M_keyp, *__keyp))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** @brief Base class for unguarded _LoserTree implementation. * * The whole element is copied into the tree structure. * * No guarding is done, therefore not a single input sequence must * run empty. Unused __sequence heads are marked with a sentinel which * is > all elements that are to be merged. * * This is a very fast variant. */ template class _LoserTreeUnguardedBase { protected: struct _Loser { int _M_source; _Tp _M_key; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreeUnguardedBase(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser))); for (unsigned int __i = 0; __i < _M_k; ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } } ~_LoserTreeUnguardedBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } int __get_min_source() { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool) { unsigned int __pos = _M_k + __source; ::new(&(_M_losers[__pos]._M_key)) _Tp(__key); _M_losers[__pos]._M_source = __source; } }; /** * @brief Stable implementation of unguarded _LoserTree. * * Unstable variant is selected below with partial specialization. */ template class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare> { typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if (_M_comp(_M_losers[__pos]._M_key, __key) || (!_M_comp(__key, _M_losers[__pos]._M_key) && _M_losers[__pos]._M_source < __source)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Non-Stable implementation of unguarded _LoserTree. * * Stable implementation is above. */ template class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare> { typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); #if _GLIBCXX_PARALLEL_ASSERTIONS // If __left one is sentinel then __right one must be, too. if (_M_losers[__left]._M_source == -1) _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1); #endif if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (_M_comp(_M_losers[__pos]._M_key, __key)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** @brief Unguarded loser tree, keeping only pointers to the * elements in the tree structure. * * No guarding is done, therefore not a single input sequence must * run empty. This is a very fast variant. */ template class _LoserTreePointerUnguardedBase { protected: struct _Loser { int _M_source; const _Tp* _M_keyp; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreePointerUnguardedBase(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = new _Loser[2 * _M_k]; for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { _M_losers[__i]._M_keyp = &__sentinel; _M_losers[__i]._M_source = -1; } } ~_LoserTreePointerUnguardedBase() { delete[] _M_losers; } int __get_min_source() { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool) { unsigned int __pos = _M_k + __source; _M_losers[__pos]._M_keyp = &__key; _M_losers[__pos]._M_source = __source; } }; /** * @brief Stable unguarded _LoserTree variant storing pointers. * * Unstable variant is implemented below using partial specialization. */ template class _LoserTreePointerUnguarded : public _LoserTreePointerUnguardedBase<_Tp, _Compare> { typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if (_M_comp(*_M_losers[__pos]._M_keyp, *__keyp) || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp) && _M_losers[__pos]._M_source < __source)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** * @brief Unstable unguarded _LoserTree variant storing pointers. * * Stable variant is above. */ template class _LoserTreePointerUnguarded : public _LoserTreePointerUnguardedBase<_Tp, _Compare> { typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); #if _GLIBCXX_PARALLEL_ASSERTIONS // If __left one is sentinel then __right one must be, too. if (_M_losers[__left]._M_source == -1) _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1); #endif if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (_M_comp(*(_M_losers[__pos]._M_keyp), *__keyp)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */ PKgd1]w/((8/parallel/parallel.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/parallel.h * @brief End-user include file. Provides advanced settings and * tuning options. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_PARALLEL_H #define _GLIBCXX_PARALLEL_PARALLEL_H 1 #include #include #include #include #include #endif /* _GLIBCXX_PARALLEL_PARALLEL_H */ PKgd1]63CC8/parallel/algobase.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algobase.h * @brief Parallel STL function calls corresponding to the * stl_algobase.h header. The functions defined here mainly do case * switches and call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one * function call, are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H #define _GLIBCXX_PARALLEL_ALGOBASE_H 1 #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // NB: equal and lexicographical_compare require mismatch. // Sequential fallback template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); } // Sequential fallback template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Sequential fallback for input iterator case template inline pair<_IIter1, _IIter2> __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Parallel mismatch for random access iterators template pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { _RAIter1 __res = __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, __gnu_parallel:: __mismatch_selector()).first; return make_pair(__res , __begin2 + (__res - __begin1)); } else return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Public interface template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { return __mismatch_switch(__begin1, __end1, __begin2, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #if __cplusplus > 201103L // Sequential fallback. template inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); } // Sequential fallback. template inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2, __binary_pred); } // Sequential fallback for input iterator case template inline pair<_IIter1, _IIter2> __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __end2, __pred); } // Parallel mismatch for random access iterators template pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { if ((__end2 - __begin2) < (__end1 - __begin1)) __end1 = __begin1 + (__end2 - __begin2); _RAIter1 __res = __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, __gnu_parallel:: __mismatch_selector()).first; return make_pair(__res , __begin2 + (__res - __begin1)); } else return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __end2, __pred); } template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } template inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __begin1, _InputIterator1 __end1, _InputIterator2 __begin2, _InputIterator2 __end2, _BinaryPredicate __binary_pred) { return __mismatch_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #endif // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); } // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); } // Public interface template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first == __end1; } // Public interface template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first == __end1; } #if __cplusplus > 201103L // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2); } // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __binary_pred); } // Sequential fallback for input iterator case template inline bool __equal_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __pred); } // Parallel equal for random access iterators template inline bool __equal_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { if (std::distance(__begin1, __end1) != std::distance(__begin2, __end2)) return false; return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __end2, __pred).first == __end1; } else return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __pred); } template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __equal_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred) { return __equal_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #endif // Sequential fallback template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, __begin2, __end2); } // Sequential fallback template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Sequential fallback for input iterator case template inline bool __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Parallel lexicographical_compare for random access iterators // Limitation: Both valuetypes must be the same template bool __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { typedef iterator_traits<_RAIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_RAIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef __gnu_parallel:: _EqualFromLess<_ValueType1, _ValueType2, _Predicate> _EqualFromLessCompare; // Longer sequence in first place. if ((__end1 - __begin1) < (__end2 - __begin2)) { typedef pair<_RAIter1, _RAIter2> _SpotType; _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2, _EqualFromLessCompare(__pred), random_access_iterator_tag(), random_access_iterator_tag()); return (__mm.first == __end1) || bool(__pred(*__mm.first, *__mm.second)); } else { typedef pair<_RAIter2, _RAIter1> _SpotType; _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1, _EqualFromLessCompare(__pred), random_access_iterator_tag(), random_access_iterator_tag()); return (__mm.first != __end2) && bool(__pred(*__mm.second, *__mm.first)); } } else return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Public interface template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType; return __lexicographical_compare_switch( __begin1, __end1, __begin2, __end2, _LessType(), _IteratorCategory1(), _IteratorCategory2()); } // Public interface template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __lexicographical_compare_switch( __begin1, __end1, __begin2, __end2, __pred, _IteratorCategory1(), _IteratorCategory2()); } } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */ PKgd1]HH8/parallel/random_shuffle.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/random_shuffle.h * @brief Parallel implementation of std::random_shuffle(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H #define _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Type to hold the index of a bin. * * Since many variables of this type are allocated, it should be * chosen as small as possible. */ typedef unsigned short _BinIndex; /** @brief Data known to every thread participating in __gnu_parallel::__parallel_random_shuffle(). */ template struct _DRandomShufflingGlobalData { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Begin iterator of the __source. */ _RAIter& _M_source; /** @brief Temporary arrays for each thread. */ _ValueType** _M_temporaries; /** @brief Two-dimensional array to hold the thread-bin distribution. * * Dimensions (_M_num_threads + 1) __x (_M_num_bins + 1). */ _DifferenceType** _M_dist; /** @brief Start indexes of the threads' __chunks. */ _DifferenceType* _M_starts; /** @brief Number of the thread that will further process the corresponding bin. */ _ThreadIndex* _M_bin_proc; /** @brief Number of bins to distribute to. */ int _M_num_bins; /** @brief Number of bits needed to address the bins. */ int _M_num_bits; /** @brief Constructor. */ _DRandomShufflingGlobalData(_RAIter& __source) : _M_source(__source) { } }; /** @brief Local data for a thread participating in __gnu_parallel::__parallel_random_shuffle(). */ template struct _DRSSorterPU { /** @brief Number of threads participating in total. */ int _M_num_threads; /** @brief Begin index for bins taken care of by this thread. */ _BinIndex _M_bins_begin; /** @brief End index for bins taken care of by this thread. */ _BinIndex __bins_end; /** @brief Random _M_seed for this thread. */ uint32_t _M_seed; /** @brief Pointer to global data. */ _DRandomShufflingGlobalData<_RAIter>* _M_sd; }; /** @brief Generate a random number in @c [0,2^__logp). * @param __logp Logarithm (basis 2) of the upper range __bound. * @param __rng Random number generator to use. */ template inline int __random_number_pow2(int __logp, _RandomNumberGenerator& __rng) { return __rng.__genrand_bits(__logp); } /** @brief Random shuffle code executed by each thread. * @param __pus Array of thread-local data records. */ template void __parallel_random_shuffle_drs_pu(_DRSSorterPU<_RAIter, _RandomNumberGenerator>* __pus) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); _DRSSorterPU<_RAIter, _RandomNumberGenerator>* __d = &__pus[__iam]; _DRandomShufflingGlobalData<_RAIter>* __sd = __d->_M_sd; // Indexing: _M_dist[bin][processor] _DifferenceType __length = (__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]); _BinIndex* __oracles = new _BinIndex[__length]; _DifferenceType* __dist = new _DifferenceType[__sd->_M_num_bins + 1]; _BinIndex* __bin_proc = new _BinIndex[__sd->_M_num_bins]; _ValueType** __temporaries = new _ValueType*[__d->_M_num_threads]; // Compute oracles and count appearances. for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __dist[__b] = 0; int __num_bits = __sd->_M_num_bits; _RandomNumber __rng(__d->_M_seed); // First main loop. for (_DifferenceType __i = 0; __i < __length; ++__i) { _BinIndex __oracle = __random_number_pow2(__num_bits, __rng); __oracles[__i] = __oracle; // To allow prefix (partial) sum. ++(__dist[__oracle + 1]); } for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __sd->_M_dist[__b][__iam + 1] = __dist[__b]; # pragma omp barrier # pragma omp single { // Sum up bins, __sd->_M_dist[__s + 1][__d->_M_num_threads] now // contains the total number of items in bin __s for (_BinIndex __s = 0; __s < __sd->_M_num_bins; ++__s) __gnu_sequential::partial_sum(__sd->_M_dist[__s + 1], __sd->_M_dist[__s + 1] + __d->_M_num_threads + 1, __sd->_M_dist[__s + 1]); } # pragma omp barrier _SequenceIndex __offset = 0, __global_offset = 0; for (_BinIndex __s = 0; __s < __d->_M_bins_begin; ++__s) __global_offset += __sd->_M_dist[__s + 1][__d->_M_num_threads]; # pragma omp barrier for (_BinIndex __s = __d->_M_bins_begin; __s < __d->__bins_end; ++__s) { for (int __t = 0; __t < __d->_M_num_threads + 1; ++__t) __sd->_M_dist[__s + 1][__t] += __offset; __offset = __sd->_M_dist[__s + 1][__d->_M_num_threads]; } __sd->_M_temporaries[__iam] = static_cast<_ValueType*> (::operator new(sizeof(_ValueType) * __offset)); # pragma omp barrier // Draw local copies to avoid false sharing. for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __dist[__b] = __sd->_M_dist[__b][__iam]; for (_BinIndex __b = 0; __b < __sd->_M_num_bins; ++__b) __bin_proc[__b] = __sd->_M_bin_proc[__b]; for (_ThreadIndex __t = 0; __t < __d->_M_num_threads; ++__t) __temporaries[__t] = __sd->_M_temporaries[__t]; _RAIter __source = __sd->_M_source; _DifferenceType __start = __sd->_M_starts[__iam]; // Distribute according to oracles, second main loop. for (_DifferenceType __i = 0; __i < __length; ++__i) { _BinIndex __target_bin = __oracles[__i]; _ThreadIndex __target_p = __bin_proc[__target_bin]; // Last column [__d->_M_num_threads] stays unchanged. ::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++])) _ValueType(*(__source + __i + __start)); } delete[] __oracles; delete[] __dist; delete[] __bin_proc; delete[] __temporaries; # pragma omp barrier // Shuffle bins internally. for (_BinIndex __b = __d->_M_bins_begin; __b < __d->__bins_end; ++__b) { _ValueType* __begin = (__sd->_M_temporaries[__iam] + (__b == __d->_M_bins_begin ? 0 : __sd->_M_dist[__b][__d->_M_num_threads])), *__end = (__sd->_M_temporaries[__iam] + __sd->_M_dist[__b + 1][__d->_M_num_threads]); __sequential_random_shuffle(__begin, __end, __rng); std::copy(__begin, __end, __sd->_M_source + __global_offset + (__b == __d->_M_bins_begin ? 0 : __sd->_M_dist[__b][__d->_M_num_threads])); } for (_SequenceIndex __i = 0; __i < __offset; ++__i) __sd->_M_temporaries[__iam][__i].~_ValueType(); ::operator delete(__sd->_M_temporaries[__iam]); } /** @brief Round up to the next greater power of 2. * @param __x _Integer to round up */ template _Tp __round_up_to_pow2(_Tp __x) { if (__x <= 1) return 1; else return (_Tp)1 << (__rd_log2(__x - 1) + 1); } /** @brief Main parallel random shuffle step. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __n Length of sequence. * @param __num_threads Number of threads to use. * @param __rng Random number generator to use. */ template void __parallel_random_shuffle_drs(_RAIter __begin, _RAIter __end, typename std::iterator_traits <_RAIter>::difference_type __n, _ThreadIndex __num_threads, _RandomNumberGenerator& __rng) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL(__n) const _Settings& __s = _Settings::get(); if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); _BinIndex __num_bins, __num_bins_cache; #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 // Try the L1 cache first. // Must fit into L1. __num_bins_cache = std::max<_DifferenceType>(1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size. __num_bins = std::min<_DifferenceType>(__n, __num_bins_cache); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin. __num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); if (__num_bins < __num_bins_cache) { #endif // Now try the L2 cache // Must fit into L2 __num_bins_cache = static_cast<_BinIndex> (std::max<_DifferenceType>(1, __n / (__s.L2_cache_size / sizeof(_ValueType)))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2. __num_bins = static_cast<_BinIndex> (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache))); // Power of 2 and at least one element per bin, at most the TLB size. #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin. __num_bins = std::min(static_cast<_DifferenceType>(__s.TLB_size / 2), __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 } #endif __num_bins = __round_up_to_pow2( std::max<_BinIndex>(__num_threads, __num_bins)); if (__num_threads <= 1) { _RandomNumber __derived_rng( __rng(std::numeric_limits::max())); __sequential_random_shuffle(__begin, __end, __derived_rng); return; } _DRandomShufflingGlobalData<_RAIter> __sd(__begin); _DRSSorterPU<_RAIter, _RandomNumber >* __pus; _DifferenceType* __starts; # pragma omp parallel num_threads(__num_threads) { _ThreadIndex __num_threads = omp_get_num_threads(); # pragma omp single { __pus = new _DRSSorterPU<_RAIter, _RandomNumber>[__num_threads]; __sd._M_temporaries = new _ValueType*[__num_threads]; __sd._M_dist = new _DifferenceType*[__num_bins + 1]; __sd._M_bin_proc = new _ThreadIndex[__num_bins]; for (_BinIndex __b = 0; __b < __num_bins + 1; ++__b) __sd._M_dist[__b] = new _DifferenceType[__num_threads + 1]; for (_BinIndex __b = 0; __b < (__num_bins + 1); ++__b) { __sd._M_dist[0][0] = 0; __sd._M_dist[__b][0] = 0; } __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1]; int __bin_cursor = 0; __sd._M_num_bins = __num_bins; __sd._M_num_bits = __rd_log2(__num_bins); _DifferenceType __chunk_length = __n / __num_threads, __split = __n % __num_threads, __start = 0; _DifferenceType __bin_chunk_length = __num_bins / __num_threads, __bin_split = __num_bins % __num_threads; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __starts[__i] = __start; __start += (__i < __split ? (__chunk_length + 1) : __chunk_length); int __j = __pus[__i]._M_bins_begin = __bin_cursor; // Range of bins for this processor. __bin_cursor += (__i < __bin_split ? (__bin_chunk_length + 1) : __bin_chunk_length); __pus[__i].__bins_end = __bin_cursor; for (; __j < __bin_cursor; ++__j) __sd._M_bin_proc[__j] = __i; __pus[__i]._M_num_threads = __num_threads; __pus[__i]._M_seed = __rng(std::numeric_limits::max()); __pus[__i]._M_sd = &__sd; } __starts[__num_threads] = __start; } //single // Now shuffle in parallel. __parallel_random_shuffle_drs_pu(__pus); } // parallel delete[] __starts; delete[] __sd._M_bin_proc; for (int __s = 0; __s < (__num_bins + 1); ++__s) delete[] __sd._M_dist[__s]; delete[] __sd._M_dist; delete[] __sd._M_temporaries; delete[] __pus; } /** @brief Sequential cache-efficient random shuffle. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __rng Random number generator to use. */ template void __sequential_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator& __rng) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; const _Settings& __s = _Settings::get(); _BinIndex __num_bins, __num_bins_cache; #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 // Try the L1 cache first, must fit into L1. __num_bins_cache = std::max<_DifferenceType> (1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size __num_bins = std::min(__n, (_DifferenceType)__num_bins_cache); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin __num_bins = std::min((_DifferenceType)__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); if (__num_bins < __num_bins_cache) { #endif // Now try the L2 cache, must fit into L2. __num_bins_cache = static_cast<_BinIndex> (std::max<_DifferenceType>(1, __n / (__s.L2_cache_size / sizeof(_ValueType)))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size. __num_bins = static_cast<_BinIndex> (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache))); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin __num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 } #endif int __num_bits = __rd_log2(__num_bins); if (__num_bins > 1) { _ValueType* __target = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * __n)); _BinIndex* __oracles = new _BinIndex[__n]; _DifferenceType* __dist0 = new _DifferenceType[__num_bins + 1], * __dist1 = new _DifferenceType[__num_bins + 1]; for (int __b = 0; __b < __num_bins + 1; ++__b) __dist0[__b] = 0; _RandomNumber __bitrng(__rng(0xFFFFFFFF)); for (_DifferenceType __i = 0; __i < __n; ++__i) { _BinIndex __oracle = __random_number_pow2(__num_bits, __bitrng); __oracles[__i] = __oracle; // To allow prefix (partial) sum. ++(__dist0[__oracle + 1]); } // Sum up bins. __gnu_sequential::partial_sum(__dist0, __dist0 + __num_bins + 1, __dist0); for (int __b = 0; __b < __num_bins + 1; ++__b) __dist1[__b] = __dist0[__b]; // Distribute according to oracles. for (_DifferenceType __i = 0; __i < __n; ++__i) ::new(&(__target[(__dist0[__oracles[__i]])++])) _ValueType(*(__begin + __i)); for (int __b = 0; __b < __num_bins; ++__b) __sequential_random_shuffle(__target + __dist1[__b], __target + __dist1[__b + 1], __rng); // Copy elements back. std::copy(__target, __target + __n, __begin); delete[] __dist0; delete[] __dist1; delete[] __oracles; for (_DifferenceType __i = 0; __i < __n; ++__i) __target[__i].~_ValueType(); ::operator delete(__target); } else __gnu_sequential::random_shuffle(__begin, __end, __rng); } /** @brief Parallel random public call. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __rng Random number generator to use. */ template inline void __parallel_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator __rng = _RandomNumber()) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; __parallel_random_shuffle_drs(__begin, __end, __n, __get_max_threads(), __rng); } } #endif /* _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H */ PKgd1]8/parallel/search.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/search.h * @brief Parallel implementation base for std::search() and * std::search_n(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_SEARCH_H #define _GLIBCXX_PARALLEL_SEARCH_H 1 #include #include #include namespace __gnu_parallel { /** * @brief Precalculate __advances for Knuth-Morris-Pratt algorithm. * @param __elements Begin iterator of sequence to search for. * @param __length Length of sequence to search for. * @param __off Returned __offsets. */ template void __calc_borders(_RAIter __elements, _DifferenceTp __length, _DifferenceTp* __off) { typedef _DifferenceTp _DifferenceType; __off[0] = -1; if (__length > 1) __off[1] = 0; _DifferenceType __k = 0; for (_DifferenceType __j = 2; __j <= __length; __j++) { while ((__k >= 0) && !(__elements[__k] == __elements[__j-1])) __k = __off[__k]; __off[__j] = ++__k; } } // Generic parallel find algorithm (requires random access iterator). /** @brief Parallel std::search. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __pred Find predicate. * @return Place of finding in first sequences. */ template __RAIter1 __search_template(__RAIter1 __begin1, __RAIter1 __end1, __RAIter2 __begin2, __RAIter2 __end2, _Pred __pred) { typedef std::iterator_traits<__RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)); _DifferenceType __pattern_length = __end2 - __begin2; // Pattern too short. if(__pattern_length <= 0) return __end1; // Last point to start search. _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length; // Where is first occurrence of pattern? defaults to end. _DifferenceType __result = (__end1 - __begin1); _DifferenceType *__splitters; // Pattern too long. if (__input_length < 0) return __end1; omp_lock_t __result_lock; omp_init_lock(&__result_lock); _ThreadIndex __num_threads = std::max<_DifferenceType> (1, std::min<_DifferenceType>(__input_length, __get_max_threads())); _DifferenceType __advances[__pattern_length]; __calc_borders(__begin2, __pattern_length, __advances); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __splitters = new _DifferenceType[__num_threads + 1]; __equally_split(__input_length, __num_threads, __splitters); } _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __start = __splitters[__iam], __stop = __splitters[__iam + 1]; _DifferenceType __pos_in_pattern = 0; bool __found_pattern = false; while (__start <= __stop && !__found_pattern) { // Get new value of result. #pragma omp flush(__result) // No chance for this thread to find first occurrence. if (__result < __start) break; while (__pred(__begin1[__start + __pos_in_pattern], __begin2[__pos_in_pattern])) { ++__pos_in_pattern; if (__pos_in_pattern == __pattern_length) { // Found new candidate for result. omp_set_lock(&__result_lock); __result = std::min(__result, __start); omp_unset_lock(&__result_lock); __found_pattern = true; break; } } // Make safe jump. __start += (__pos_in_pattern - __advances[__pos_in_pattern]); __pos_in_pattern = (__advances[__pos_in_pattern] < 0 ? 0 : __advances[__pos_in_pattern]); } } //parallel omp_destroy_lock(&__result_lock); delete[] __splitters; // Return iterator on found element. return (__begin1 + __result); } } // end namespace #endif /* _GLIBCXX_PARALLEL_SEARCH_H */ PKgd1],mkk8/parallel/for_each.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/for_each.h * @brief Main interface for embarrassingly parallel functions. * * The explicit implementation are in other header files, like * workstealing.h, par_loop.h, omp_loop.h, and omp_loop_static.h. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_H #define _GLIBCXX_PARALLEL_FOR_EACH_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Chose the desired algorithm by evaluating @c __parallelism_tag. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __user_op A user-specified functor (comparator, predicate, * associative operator,...) * @param __functionality functor to @a process an element with * __user_op (depends on desired functionality, e. g. accumulate, * for_each,... * @param __reduction Reduction functor. * @param __reduction_start Initial value for reduction. * @param __output Output iterator. * @param __bound Maximum number of elements processed. * @param __parallelism_tag Parallelization method */ template _UserOp __for_each_template_random_access(_IIter __begin, _IIter __end, _UserOp __user_op, _Functionality& __functionality, _Red __reduction, _Result __reduction_start, _Result& __output, typename std::iterator_traits<_IIter>:: difference_type __bound, _Parallelism __parallelism_tag) { if (__parallelism_tag == parallel_unbalanced) return __for_each_template_random_access_ed (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else if (__parallelism_tag == parallel_omp_loop) return __for_each_template_random_access_omp_loop (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else if (__parallelism_tag == parallel_omp_loop_static) return __for_each_template_random_access_omp_loop (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else //e. g. parallel_balanced return __for_each_template_random_access_workstealing (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); } } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_H */ PKgd1]C8/parallel/quicksort.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/quicksort.h * @brief Implementation of a unbalanced parallel quicksort (in-place). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_QUICKSORT_H #define _GLIBCXX_PARALLEL_QUICKSORT_H 1 #include #include namespace __gnu_parallel { /** @brief Unbalanced quicksort divide step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __pivot_rank Desired __rank of the pivot. * @param __num_samples Choose pivot from that many samples. * @param __num_threads Number of threads that are allowed to work on * this part. */ template typename std::iterator_traits<_RAIter>::difference_type __parallel_sort_qs_divide(_RAIter __begin, _RAIter __end, _Compare __comp, typename std::iterator_traits <_RAIter>::difference_type __pivot_rank, typename std::iterator_traits <_RAIter>::difference_type __num_samples, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; __num_samples = std::min(__num_samples, __n); // Allocate uninitialized, to avoid default constructor. _ValueType* __samples = static_cast<_ValueType*> (::operator new(__num_samples * sizeof(_ValueType))); for (_DifferenceType __s = 0; __s < __num_samples; ++__s) { const unsigned long long __index = static_cast (__s) * __n / __num_samples; ::new(&(__samples[__s])) _ValueType(__begin[__index]); } __gnu_sequential::sort(__samples, __samples + __num_samples, __comp); _ValueType& __pivot = __samples[__pivot_rank * __num_samples / __n]; __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, __pivot); _DifferenceType __split = __parallel_partition(__begin, __end, __pred, __num_threads); for (_DifferenceType __s = 0; __s < __num_samples; ++__s) __samples[__s].~_ValueType(); ::operator delete(__samples); return __split; } /** @brief Unbalanced quicksort conquer step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template void __parallel_sort_qs_conquer(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (__num_threads <= 1) { __gnu_sequential::sort(__begin, __end, __comp); return; } _DifferenceType __n = __end - __begin, __pivot_rank; if (__n <= 1) return; _ThreadIndex __num_threads_left; if ((__num_threads % 2) == 1) __num_threads_left = __num_threads / 2 + 1; else __num_threads_left = __num_threads / 2; __pivot_rank = __n * __num_threads_left / __num_threads; _DifferenceType __split = __parallel_sort_qs_divide (__begin, __end, __comp, __pivot_rank, _Settings::get().sort_qs_num_samples_preset, __num_threads); #pragma omp parallel sections num_threads(2) { #pragma omp section __parallel_sort_qs_conquer(__begin, __begin + __split, __comp, __num_threads_left); #pragma omp section __parallel_sort_qs_conquer(__begin + __split, __end, __comp, __num_threads - __num_threads_left); } } /** @brief Unbalanced quicksort main call. * @param __begin Begin iterator of input sequence. * @param __end End iterator input sequence, ignored. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template void __parallel_sort_qs(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__n) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; // At least one element per processor. if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); __parallel_sort_qs_conquer( __begin, __begin + __n, __comp, __num_threads); } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_QUICKSORT_H */ PKgd1]8/parallel/omp_loop_static.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/omp_loop_static.h * @brief Parallelization of embarrassingly parallel execution by * means of an OpenMP for loop with static scheduling. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H #define _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H 1 #include #include #include namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using an OpenMP for loop with static scheduling. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, ...). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already processed * __elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_omp_loop_static(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef typename std::iterator_traits<_RAIter>::difference_type _DifferenceType; _DifferenceType __length = __end - __begin; _ThreadIndex __num_threads = std::min<_DifferenceType> (__get_max_threads(), __length); _Result *__thread_results; # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = new _Result[__num_threads]; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __thread_results[__i] = _Result(); } _ThreadIndex __iam = omp_get_thread_num(); #pragma omp for schedule(static, _Settings::get().workstealing_chunk_size) for (_DifferenceType __pos = 0; __pos < __length; ++__pos) __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos)); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __output = __r(__output, __thread_results[__i]); delete [] __thread_results; // Points to last element processed (needed as return value for // some algorithms like transform). __f.finish_iterator = __begin + __length; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H */ PKgd1]Td8/parallel/par_loop.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/par_loop.h * @brief Parallelization of embarrassingly parallel execution by * means of equal splitting. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_PAR_LOOP_H #define _GLIBCXX_PARALLEL_PAR_LOOP_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using hand-crafted parallelization by equal splitting * the work. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, ...) * @param __f Functor to "process" an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to "add" a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_ed(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; const _DifferenceType __length = __end - __begin; _Result *__thread_results; bool* __constructed; _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> (__get_max_threads(), __length); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = static_cast<_Result*> (::operator new(__num_threads * sizeof(_Result))); __constructed = new bool[__num_threads]; } _ThreadIndex __iam = omp_get_thread_num(); // Neutral element. _Result* __reduct; _DifferenceType __start = __equally_split_point(__length, __num_threads, __iam), __stop = __equally_split_point(__length, __num_threads, __iam + 1); if (__start < __stop) { __reduct = new _Result(__f(__o, __begin + __start)); ++__start; __constructed[__iam] = true; } else __constructed[__iam] = false; for (; __start < __stop; ++__start) *__reduct = __r(*__reduct, __f(__o, __begin + __start)); if (__constructed[__iam]) { ::new(&__thread_results[__iam]) _Result(*__reduct); delete __reduct; } } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) if (__constructed[__i]) { __output = __r(__output, __thread_results[__i]); __thread_results[__i].~_Result(); } // Points to last element processed (needed as return value for // some algorithms like transform). __f._M_finish_iterator = __begin + __length; ::operator delete(__thread_results); delete[] __constructed; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_PAR_LOOP_H */ PKgd1]WFo[q:q:8/parallel/partition.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/partition.h * @brief Parallel implementation of std::partition(), * std::nth_element(), and std::partial_sort(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_PARTITION_H #define _GLIBCXX_PARALLEL_PARTITION_H 1 #include #include #include #include #include /** @brief Decide whether to declare certain variables volatile. */ #define _GLIBCXX_VOLATILE volatile namespace __gnu_parallel { /** @brief Parallel implementation of std::partition. * @param __begin Begin iterator of input sequence to split. * @param __end End iterator of input sequence to split. * @param __pred Partition predicate, possibly including some kind * of pivot. * @param __num_threads Maximum number of threads to use for this task. * @return Number of elements not fulfilling the predicate. */ template typename std::iterator_traits<_RAIter>::difference_type __parallel_partition(_RAIter __begin, _RAIter __end, _Predicate __pred, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; _GLIBCXX_CALL(__n) const _Settings& __s = _Settings::get(); // shared _GLIBCXX_VOLATILE _DifferenceType __left = 0, __right = __n - 1, __dist = __n, __leftover_left, __leftover_right, __leftnew, __rightnew; // just 0 or 1, but int to allow atomic operations int* __reserved_left = 0, * __reserved_right = 0; _DifferenceType __chunk_size = __s.partition_chunk_size; //at least two chunks per thread if (__dist >= 2 * __num_threads * __chunk_size) # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __reserved_left = new int[__num_threads]; __reserved_right = new int[__num_threads]; if (__s.partition_chunk_share > 0.0) __chunk_size = std::max<_DifferenceType> (__s.partition_chunk_size, (double)__n * __s.partition_chunk_share / (double)__num_threads); else __chunk_size = __s.partition_chunk_size; } while (__dist >= 2 * __num_threads * __chunk_size) { # pragma omp single { _DifferenceType __num_chunks = __dist / __chunk_size; for (_ThreadIndex __r = 0; __r < __num_threads; ++__r) { __reserved_left [__r] = 0; // false __reserved_right[__r] = 0; // false } __leftover_left = 0; __leftover_right = 0; } //implicit barrier // Private. _DifferenceType __thread_left, __thread_left_border, __thread_right, __thread_right_border; __thread_left = __left + 1; // Just to satisfy the condition below. __thread_left_border = __thread_left - 1; __thread_right = __n - 1; // Just to satisfy the condition below. __thread_right_border = __thread_right + 1; bool __iam_finished = false; while (!__iam_finished) { if (__thread_left > __thread_left_border) { _DifferenceType __former_dist = __fetch_and_add(&__dist, -__chunk_size); if (__former_dist < __chunk_size) { __fetch_and_add(&__dist, __chunk_size); __iam_finished = true; break; } else { __thread_left = __fetch_and_add(&__left, __chunk_size); __thread_left_border = __thread_left + (__chunk_size - 1); } } if (__thread_right < __thread_right_border) { _DifferenceType __former_dist = __fetch_and_add(&__dist, -__chunk_size); if (__former_dist < __chunk_size) { __fetch_and_add(&__dist, __chunk_size); __iam_finished = true; break; } else { __thread_right = __fetch_and_add(&__right, -__chunk_size); __thread_right_border = __thread_right - (__chunk_size - 1); } } // Swap as usual. while (__thread_left < __thread_right) { while (__pred(__begin[__thread_left]) && __thread_left <= __thread_left_border) ++__thread_left; while (!__pred(__begin[__thread_right]) && __thread_right >= __thread_right_border) --__thread_right; if (__thread_left > __thread_left_border || __thread_right < __thread_right_border) // Fetch new chunk(__s). break; std::iter_swap(__begin + __thread_left, __begin + __thread_right); ++__thread_left; --__thread_right; } } // Now swap the leftover chunks to the right places. if (__thread_left <= __thread_left_border) # pragma omp atomic ++__leftover_left; if (__thread_right >= __thread_right_border) # pragma omp atomic ++__leftover_right; # pragma omp barrier _DifferenceType __leftold = __left, __leftnew = __left - __leftover_left * __chunk_size, __rightold = __right, __rightnew = __right + __leftover_right * __chunk_size; // <=> __thread_left_border + (__chunk_size - 1) >= __leftnew if (__thread_left <= __thread_left_border && __thread_left_border >= __leftnew) { // Chunk already in place, reserve spot. __reserved_left[(__left - (__thread_left_border + 1)) / __chunk_size] = 1; } // <=> __thread_right_border - (__chunk_size - 1) <= __rightnew if (__thread_right >= __thread_right_border && __thread_right_border <= __rightnew) { // Chunk already in place, reserve spot. __reserved_right[((__thread_right_border - 1) - __right) / __chunk_size] = 1; } # pragma omp barrier if (__thread_left <= __thread_left_border && __thread_left_border < __leftnew) { // Find spot and swap. _DifferenceType __swapstart = -1; for (int __r = 0; __r < __leftover_left; ++__r) if (__reserved_left[__r] == 0 && __compare_and_swap(&(__reserved_left[__r]), 0, 1)) { __swapstart = __leftold - (__r + 1) * __chunk_size; break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1); #endif std::swap_ranges(__begin + __thread_left_border - (__chunk_size - 1), __begin + __thread_left_border + 1, __begin + __swapstart); } if (__thread_right >= __thread_right_border && __thread_right_border > __rightnew) { // Find spot and swap _DifferenceType __swapstart = -1; for (int __r = 0; __r < __leftover_right; ++__r) if (__reserved_right[__r] == 0 && __compare_and_swap(&(__reserved_right[__r]), 0, 1)) { __swapstart = __rightold + __r * __chunk_size + 1; break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1); #endif std::swap_ranges(__begin + __thread_right_border, __begin + __thread_right_border + __chunk_size, __begin + __swapstart); } #if _GLIBCXX_PARALLEL_ASSERTIONS # pragma omp barrier # pragma omp single { for (_DifferenceType __r = 0; __r < __leftover_left; ++__r) _GLIBCXX_PARALLEL_ASSERT(__reserved_left[__r] == 1); for (_DifferenceType __r = 0; __r < __leftover_right; ++__r) _GLIBCXX_PARALLEL_ASSERT(__reserved_right[__r] == 1); } #endif __left = __leftnew; __right = __rightnew; __dist = __right - __left + 1; } # pragma omp flush(__left, __right) } // end "recursion" //parallel _DifferenceType __final_left = __left, __final_right = __right; while (__final_left < __final_right) { // Go right until key is geq than pivot. while (__pred(__begin[__final_left]) && __final_left < __final_right) ++__final_left; // Go left until key is less than pivot. while (!__pred(__begin[__final_right]) && __final_left < __final_right) --__final_right; if (__final_left == __final_right) break; std::iter_swap(__begin + __final_left, __begin + __final_right); ++__final_left; --__final_right; } // All elements on the left side are < piv, all elements on the // right are >= piv delete[] __reserved_left; delete[] __reserved_right; // Element "between" __final_left and __final_right might not have // been regarded yet if (__final_left < __n && !__pred(__begin[__final_left])) // Really swapped. return __final_left; else return __final_left + 1; } /** * @brief Parallel implementation of std::nth_element(). * @param __begin Begin iterator of input sequence. * @param __nth _Iterator of element that must be in position afterwards. * @param __end End iterator of input sequence. * @param __comp Comparator. */ template void __parallel_nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL(__end - __begin) _RAIter __split; _RandomNumber __rng; const _Settings& __s = _Settings::get(); _DifferenceType __minimum_length = std::max<_DifferenceType>(2, std::max(__s.nth_element_minimal_n, __s.partition_minimal_n)); // Break if input range to small. while (static_cast<_SequenceIndex>(__end - __begin) >= __minimum_length) { _DifferenceType __n = __end - __begin; _RAIter __pivot_pos = __begin + __rng(__n); // Swap __pivot_pos value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; // _Compare must have first_value_type, second_value_type, // result_type // _Compare == // __gnu_parallel::_Lexicographic > // __pivot_pos == std::pair* __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, leave pivot unchanged in last place. _RAIter __split_pos1, __split_pos2; __split_pos1 = __begin + __parallel_partition(__begin, __end - 1, __pred, __get_max_threads()); // Left side: < __pivot_pos; __right side: >= __pivot_pos // Swap pivot back to middle. if (__split_pos1 != __pivot_pos) std::iter_swap(__split_pos1, __pivot_pos); __pivot_pos = __split_pos1; // In case all elements are equal, __split_pos1 == 0 if ((__split_pos1 + 1 - __begin) < (__n >> 7) || (__end - __split_pos1) < (__n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not strictly larger than the pivot. __gnu_parallel::__unary_negate<__gnu_parallel:: __binder1st<_Compare, _ValueType, _ValueType, bool>, _ValueType> __pred(__gnu_parallel::__binder1st<_Compare, _ValueType, _ValueType, bool>(__comp, *__pivot_pos)); // Find other end of pivot-equal range. __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1, __end, __pred); } else // Only skip the pivot. __split_pos2 = __split_pos1 + 1; // Compare iterators. if (__split_pos2 <= __nth) __begin = __split_pos2; else if (__nth < __split_pos1) __end = __split_pos1; else break; } // Only at most _Settings::partition_minimal_n __elements __left. __gnu_sequential::nth_element(__begin, __nth, __end, __comp); } /** @brief Parallel implementation of std::partial_sort(). * @param __begin Begin iterator of input sequence. * @param __middle Sort until this position. * @param __end End iterator of input sequence. * @param __comp Comparator. */ template void __parallel_partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) { __parallel_nth_element(__begin, __middle, __end, __comp); std::sort(__begin, __middle, __comp); } } //namespace __gnu_parallel #undef _GLIBCXX_VOLATILE #endif /* _GLIBCXX_PARALLEL_PARTITION_H */ PKgd1]sALL8/parallel/numericfwd.hnu[// Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/numericfwd.h * This file is a GNU parallel extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PARALLEL_NUMERICFWD_H #define _GLIBCXX_PARALLEL_NUMERICFWD_H 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { template _Tp accumulate(_IIter, _IIter, _Tp); template _Tp accumulate(_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag); template _Tp accumulate(_IIter, _IIter, _Tp, __gnu_parallel::_Parallelism); template _Tp __accumulate_switch(_IIter, _IIter, _Tp, _Tag); template _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper); template _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::sequential_tag); template _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::_Parallelism); template _Tp __accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag); template _Tp __accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template _OIter adjacent_difference(_IIter, _IIter, _OIter); template _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper); template _OIter adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); template _OIter adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::_Parallelism); template _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::_Parallelism); template _OIter __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template _OIter __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, __gnu_parallel::sequential_tag); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, __gnu_parallel::_Parallelism); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, __gnu_parallel::sequential_tag); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1, BinaryFunction2, __gnu_parallel::_Parallelism); template _Tp __inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1, BinaryFunction2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism = __gnu_parallel::parallel_unbalanced); template _Tp __inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, _Tag1, _Tag2); template _OIter partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template _OIter partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); template _OIter partial_sum(_IIter, _IIter, _OIter __result); template _OIter partial_sum(_IIter, _IIter, _OIter, _BinaryOper); template _OIter __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template _OIter __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag); } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_NUMERICFWD_H */ PKgd1]qC888/parallel/algo.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algo.h * @brief Parallel STL function calls corresponding to the stl_algo.h header. * * The functions defined here mainly do case switches and * call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one function call, * are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_ALGO_H #define _GLIBCXX_PARALLEL_ALGO_H 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // Sequential fallback template inline _Function for_each(_IIter __begin, _IIter __end, _Function __f, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::for_each(__begin, __end, __f); } // Sequential fallback for input iterator case template inline _Function __for_each_switch(_IIter __begin, _IIter __end, _Function __f, _IteratorTag) { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _Function __for_each_switch(_RAIter __begin, _RAIter __end, _Function __f, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().for_each_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel::__for_each_selector<_RAIter> __functionality; return __gnu_parallel:: __for_each_template_random_access( __begin, __end, __f, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); } // Public interface template inline _Function for_each(_Iterator __begin, _Iterator __end, _Function __f, __gnu_parallel::_Parallelism __parallelism_tag) { return __for_each_switch(__begin, __end, __f, std::__iterator_category(__begin), __parallelism_tag); } template inline _Function for_each(_Iterator __begin, _Iterator __end, _Function __f) { return __for_each_switch(__begin, __end, __f, std::__iterator_category(__begin)); } // Sequential fallback template inline _IIter find(_IIter __begin, _IIter __end, const _Tp& __val, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Sequential fallback for input iterator case template inline _IIter __find_switch(_IIter __begin, _IIter __end, const _Tp& __val, _IteratorTag) { return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Parallel find for random access iterators template _RAIter __find_switch(_RAIter __begin, _RAIter __end, const _Tp& __val, random_access_iterator_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (_GLIBCXX_PARALLEL_CONDITION(true)) { __gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&>, _ValueType, const _Tp&, bool> __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val); return __gnu_parallel::__find_template( __begin, __end, __begin, __comp, __gnu_parallel::__find_if_selector()).first; } else return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Public interface template inline _IIter find(_IIter __begin, _IIter __end, const _Tp& __val) { return __find_switch(__begin, __end, __val, std::__iterator_category(__begin)); } // Sequential fallback template inline _IIter find_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Sequential fallback for input iterator case template inline _IIter __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, _IteratorTag) { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Parallel find_if for random access iterators template _RAIter __find_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) return __gnu_parallel::__find_template(__begin, __end, __begin, __pred, __gnu_parallel:: __find_if_selector()).first; else return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Public interface template inline _IIter find_if(_IIter __begin, _IIter __end, _Predicate __pred) { return __find_if_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2); } // Sequential fallback template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_first_of( __begin1, __end1, __begin2, __end2, __comp); } // Sequential fallback for input iterator type template inline _IIter __find_first_of_switch(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _IteratorTag1, _IteratorTag2) { return find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template inline _RAIter __find_first_of_switch(_RAIter __begin1, _RAIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, random_access_iterator_tag, _IteratorTag) { return __gnu_parallel:: __find_template(__begin1, __end1, __begin1, __comp, __gnu_parallel::__find_first_of_selector <_FIterator>(__begin2, __end2)).first; } // Sequential fallback for input iterator type template inline _IIter __find_first_of_switch(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2) { return find_first_of(__begin1, __end1, __begin2, __end2, __comp, __gnu_parallel::sequential_tag()); } // Public interface template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp) { return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface, insert default comparator template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2) { typedef typename std::iterator_traits<_IIter>::value_type _IValueType; typedef typename std::iterator_traits<_FIterator>::value_type _FValueType; return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::_EqualTo<_IValueType, _FValueType>()); } // Sequential fallback template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); } // Sequential fallback template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __unique_copy_switch(_IIter __begin, _IIter __last, _OutputIterator __out, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); } // Parallel unique_copy for random access iterators template RandomAccessOutputIterator __unique_copy_switch(_RAIter __begin, _RAIter __last, RandomAccessOutputIterator __out, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin) > __gnu_parallel::_Settings::get().unique_copy_minimal_n)) return __gnu_parallel::__parallel_unique_copy( __begin, __last, __out, __pred); else return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); } // Public interface template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter>::value_type _ValueType; return __unique_copy_switch( __begin1, __end1, __out, equal_to<_ValueType>(), std::__iterator_category(__begin1), std::__iterator_category(__out)); } // Public interface template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, _Predicate __pred) { return __unique_copy_switch( __begin1, __end1, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__out)); } // Sequential fallback template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_union( __begin1, __end1, __begin2, __end2, __out); } // Sequential fallback template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __set_union_switch( _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_union for random access iterators template _Output_RAIter __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_union_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_union_minimal_n)) return __gnu_parallel::__parallel_set_union( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_union_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_union_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback. template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2, __end2, __out); } // Sequential fallback. template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_intersection( __begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_intersection for random access iterators template _Output_RAIter __set_intersection_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_union_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_union_minimal_n)) return __gnu_parallel::__parallel_set_intersection( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_intersection( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_intersection_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_intersection_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __out); } // Sequential fallback template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __set_symmetric_difference_switch( _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_symmetric_difference for random access iterators template _Output_RAIter __set_symmetric_difference_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n)) return __gnu_parallel::__parallel_set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface. template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_symmetric_difference_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface. template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_symmetric_difference_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback. template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_difference( __begin1,__end1, __begin2, __end2, __out); } // Sequential fallback. template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_difference(__begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case. template inline _OutputIterator __set_difference_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_difference for random access iterators template _Output_RAIter __set_difference_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_difference_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_difference_minimal_n)) return __gnu_parallel::__parallel_set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_difference_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_difference_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); } // Sequential fallback template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); } // Parallel algorithm for random access iterators template _RAIter __adjacent_find_switch(_RAIter __begin, _RAIter __end, random_access_iterator_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (_GLIBCXX_PARALLEL_CONDITION(true)) { _RAIter __spot = __gnu_parallel:: __find_template( __begin, __end - 1, __begin, equal_to<_ValueType>(), __gnu_parallel::__adjacent_find_selector()) .first; if (__spot == (__end - 1)) return __end; else return __spot; } else return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template inline _FIterator __adjacent_find_switch(_FIterator __begin, _FIterator __end, _IteratorTag) { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); } // Public interface template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end) { return __adjacent_find_switch(__begin, __end, std::__iterator_category(__begin)); } // Sequential fallback for input iterator case template inline _FIterator __adjacent_find_switch(_FIterator __begin, _FIterator __end, _BinaryPredicate __pred, _IteratorTag) { return adjacent_find(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _RAIter __adjacent_find_switch(_RAIter __begin, _RAIter __end, _BinaryPredicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) return __gnu_parallel::__find_template(__begin, __end, __begin, __pred, __gnu_parallel:: __adjacent_find_selector()).first; else return adjacent_find(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, _BinaryPredicate __pred) { return __adjacent_find_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback template inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::count(__begin, __end, __value); } // Parallel code for random access iterators template typename iterator_traits<_RAIter>::difference_type __count_switch(_RAIter __begin, _RAIter __end, const _Tp& __value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef __gnu_parallel::_SequenceIndex _SequenceIndex; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().count_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { __gnu_parallel::__count_selector<_RAIter, _DifferenceType> __functionality; _DifferenceType __res = 0; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __value, __functionality, std::plus<_SequenceIndex>(), __res, __res, -1, __parallelism_tag); return __res; } else return count(__begin, __end, __value, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline typename iterator_traits<_IIter>::difference_type __count_switch(_IIter __begin, _IIter __end, const _Tp& __value, _IteratorTag) { return count(__begin, __end, __value, __gnu_parallel::sequential_tag()); } // Public interface. template inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value, __gnu_parallel::_Parallelism __parallelism_tag) { return __count_switch(__begin, __end, __value, std::__iterator_category(__begin), __parallelism_tag); } template inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value) { return __count_switch(__begin, __end, __value, std::__iterator_category(__begin)); } // Sequential fallback. template inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); } // Parallel count_if for random access iterators template typename iterator_traits<_RAIter>::difference_type __count_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef __gnu_parallel::_SequenceIndex _SequenceIndex; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().count_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _DifferenceType __res = 0; __gnu_parallel:: __count_if_selector<_RAIter, _DifferenceType> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __pred, __functionality, std::plus<_SequenceIndex>(), __res, __res, -1, __parallelism_tag); return __res; } else return count_if(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline typename iterator_traits<_IIter>::difference_type __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, _IteratorTag) { return count_if(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface. template inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::_Parallelism __parallelism_tag) { return __count_if_switch(__begin, __end, __pred, std::__iterator_category(__begin), __parallelism_tag); } template inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred) { return __count_if_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback. template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); } // Parallel algorithm for random access iterator template _RAIter1 __search_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, random_access_iterator_tag, random_access_iterator_tag) { typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().search_minimal_n)) return __gnu_parallel:: __search_template( __begin1, __end1, __begin2, __end2, __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>()); else return search(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template inline _FIterator1 __search_switch(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _IteratorTag1, _IteratorTag2) { return search(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Public interface. template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2) { return __search_switch(__begin1, __end1, __begin2, __end2, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface. template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search( __begin1, __end1, __begin2, __end2, __pred); } // Parallel algorithm for random access iterator. template _RAIter1 __search_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().search_minimal_n)) return __gnu_parallel::__search_template(__begin1, __end1, __begin2, __end2, __pred); else return search(__begin1, __end1, __begin2, __end2, __pred, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template inline _FIterator1 __search_switch(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2) { return search(__begin1, __end1, __begin2, __end2, __pred, __gnu_parallel::sequential_tag()); } // Public interface template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred) { return __search_switch(__begin1, __end1, __begin2, __end2, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Sequential fallback template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); } // Sequential fallback template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search_n( __begin, __end, __count, __val, __binary_pred); } // Public interface. template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::search_n(__begin, __end, __count, __val, __gnu_parallel::_EqualTo<_ValueType, _Tp>()); } // Parallel algorithm for random access iterators. template _RAIter __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().search_minimal_n)) { __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count); return __gnu_parallel::__search_template( __begin, __end, __ps.begin(), __ps.end(), __binary_pred); } else return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val, __binary_pred); } // Sequential fallback for input iterator case. template inline _FIterator __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, _IteratorTag) { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val, __binary_pred); } // Public interface. template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred) { return __search_n_switch(__begin, __end, __count, __val, __binary_pred, std::__iterator_category(__begin)); } // Sequential fallback. template inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); } // Parallel unary transform for random access iterators. template _RAIter2 __transform1_switch(_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().transform_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorPair<_RAIter1, _RAIter2, random_access_iterator_tag> _ItTrip; _ItTrip __begin_pair(__begin, __result), __end_pair(__end, __result + (__end - __begin)); __gnu_parallel::__transform1_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin_pair, __end_pair, __unary_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1, __parallelism_tag); return __functionality._M_finish_iterator; } else return transform(__begin, __end, __result, __unary_op, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline _RAIter2 __transform1_switch(_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, _IteratorTag1, _IteratorTag2) { return transform(__begin, __end, __result, __unary_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op, __gnu_parallel::_Parallelism __parallelism_tag) { return __transform1_switch(__begin, __end, __result, __unary_op, std::__iterator_category(__begin), std::__iterator_category(__result), __parallelism_tag); } template inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op) { return __transform1_switch(__begin, __end, __result, __unary_op, std::__iterator_category(__begin), std::__iterator_category(__result)); } // Sequential fallback template inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::transform(__begin1, __end1, __begin2, __result, __binary_op); } // Parallel binary transform for random access iterators. template _RAIter3 __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter3 __result, _BinaryOperation __binary_op, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( (__end1 - __begin1) >= __gnu_parallel::_Settings::get().transform_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorTriple<_RAIter1, _RAIter2, _RAIter3, random_access_iterator_tag> _ItTrip; _ItTrip __begin_triple(__begin1, __begin2, __result), __end_triple(__end1, __begin2 + (__end1 - __begin1), __result + (__end1 - __begin1)); __gnu_parallel::__transform2_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access(__begin_triple, __end_triple, __binary_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1, __parallelism_tag); return __functionality._M_finish_iterator; } else return transform(__begin1, __end1, __begin2, __result, __binary_op, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline _OutputIterator __transform2_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3) { return transform(__begin1, __end1, __begin2, __result, __binary_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { return __transform2_switch( __begin1, __end1, __begin2, __result, __binary_op, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result), __parallelism_tag); } template inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op) { return __transform2_switch( __begin1, __end1, __begin2, __result, __binary_op, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result)); } // Sequential fallback template inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); } // Sequential fallback for input iterator case template inline void __replace_switch(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, _IteratorTag) { replace(__begin, __end, __old_value, __new_value, __gnu_parallel::sequential_tag()); } // Parallel replace for random access iterators template inline void __replace_switch(_RAIter __begin, _RAIter __end, const _Tp& __old_value, const _Tp& __new_value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { // XXX parallel version is where? replace(__begin, __end, __old_value, __new_value, __gnu_parallel::sequential_tag()); } // Public interface template inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, __gnu_parallel::_Parallelism __parallelism_tag) { __replace_switch(__begin, __end, __old_value, __new_value, std::__iterator_category(__begin), __parallelism_tag); } template inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value) { __replace_switch(__begin, __end, __old_value, __new_value, std::__iterator_category(__begin)); } // Sequential fallback template inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); } // Sequential fallback for input iterator case template inline void __replace_if_switch(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, _IteratorTag) { replace_if(__begin, __end, __pred, __new_value, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template void __replace_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, const _Tp& __new_value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().replace_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel:: __replace_if_selector<_RAIter, _Predicate, _Tp> __functionality(__new_value); __gnu_parallel:: __for_each_template_random_access( __begin, __end, __pred, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else replace_if(__begin, __end, __pred, __new_value, __gnu_parallel::sequential_tag()); } // Public interface. template inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, __gnu_parallel::_Parallelism __parallelism_tag) { __replace_if_switch(__begin, __end, __pred, __new_value, std::__iterator_category(__begin), __parallelism_tag); } template inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value) { __replace_if_switch(__begin, __end, __pred, __new_value, std::__iterator_category(__begin)); } // Sequential fallback template inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::generate(__begin, __end, __gen); } // Sequential fallback for input iterator case. template inline void __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen, _IteratorTag) { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template void __generate_switch(_RAIter __begin, _RAIter __end, _Generator __gen, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().generate_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel::__generate_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gen, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); } // Public interface. template inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag) { __generate_switch(__begin, __end, __gen, std::__iterator_category(__begin), __parallelism_tag); } template inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen) { __generate_switch(__begin, __end, __gen, std::__iterator_category(__begin)); } // Sequential fallback. template inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); } // Sequential fallback for input iterator case. template inline _OutputIterator __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen, _IteratorTag) { return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template inline _RAIter __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { // XXX parallel version is where? return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag) { return __generate_n_switch(__begin, __n, __gen, std::__iterator_category(__begin), __parallelism_tag); } template inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen) { return __generate_n_switch(__begin, __n, __gen, std::__iterator_category(__begin)); } // Sequential fallback. template inline void random_shuffle(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::random_shuffle(__begin, __end); } // Sequential fallback. template inline void random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator& __rand, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); } /** @brief Functor wrapper for std::rand(). */ template struct _CRandNumber { int operator()(int __limit) { return rand() % __limit; } }; // Fill in random number generator. template inline void random_shuffle(_RAIter __begin, _RAIter __end) { _CRandNumber<> __r; // Parallelization still possible. __gnu_parallel::random_shuffle(__begin, __end, __r); } // Parallel algorithm for random access iterators. template void random_shuffle(_RAIter __begin, _RAIter __end, #if __cplusplus >= 201103L _RandomNumberGenerator&& __rand) #else _RandomNumberGenerator& __rand) #endif { if (__begin == __end) return; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n)) __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand); else __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand); } // Sequential fallback. template inline _FIterator partition(_FIterator __begin, _FIterator __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); } // Sequential fallback for input iterator case. template inline _FIterator __partition_switch(_FIterator __begin, _FIterator __end, _Predicate __pred, _IteratorTag) { return partition(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template _RAIter __partition_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partition_minimal_n)) { typedef typename std::iterator_traits<_RAIter>:: difference_type _DifferenceType; _DifferenceType __middle = __gnu_parallel:: __parallel_partition(__begin, __end, __pred, __gnu_parallel::__get_max_threads()); return __begin + __middle; } else return partition(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface. template inline _FIterator partition(_FIterator __begin, _FIterator __end, _Predicate __pred) { return __partition_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // sort interface // Sequential fallback template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::sort(__begin, __end); } // Sequential fallback template inline void sort(_RAIter __begin, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end, __comp); } // Public interface template void sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; if (__begin != __end) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::__parallel_sort( __begin, __end, __comp, __parallelism); else sort(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __gnu_parallel::default_parallel_tag()); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::default_parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_sampling_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_exact_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::balanced_quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface template void sort(_RAIter __begin, _RAIter __end, _Compare __comp) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag()); } // stable_sort interface // Sequential fallback template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::stable_sort(__begin, __end); } // Sequential fallback template inline void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); } // Public interface template void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (__begin != __end) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::__parallel_sort(__begin, __end, __comp, __parallelism); else stable_sort(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __gnu_parallel::default_parallel_tag()); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::default_parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::balanced_quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface template void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp) { stable_sort( __begin, __end, __comp, __gnu_parallel::default_parallel_tag()); } // Sequential fallback template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::merge( __begin1, __end1, __begin2, __end2, __result); } // Sequential fallback template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::merge( __begin1, __end1, __begin2, __end2, __result, __comp); } // Sequential fallback for input iterator case template inline _OutputIterator __merge_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2, __result, __comp); } // Parallel algorithm for random access iterators template _OutputIterator __merge_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().merge_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().merge_minimal_n))) return __gnu_parallel::__parallel_merge_advance( __begin1, __end1, __begin2, __end2, __result, (__end1 - __begin1) + (__end2 - __begin2), __comp); else return __gnu_parallel::__merge_advance( __begin1, __end1, __begin2, __end2, __result, (__end1 - __begin1) + (__end2 - __begin2), __comp); } // Public interface template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp) { return __merge_switch( __begin1, __end1, __begin2, __end2, __result, __comp, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result)); } // Public interface, insert default comparator template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2, __result, __gnu_parallel::_Less<_ValueType1, _ValueType2>()); } // Sequential fallback template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); } // Sequential fallback template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); } // Public interface template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().nth_element_minimal_n)) __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp); else nth_element(__begin, __nth, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; __gnu_parallel::nth_element(__begin, __nth, __end, std::less<_ValueType>()); } // Sequential fallback template inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); } // Sequential fallback template inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); } // Public interface, parallel algorithm for random access iterators template void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partial_sort_minimal_n)) __gnu_parallel:: __parallel_partial_sort(__begin, __middle, __end, __comp); else partial_sort(__begin, __middle, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; __gnu_parallel::partial_sort(__begin, __middle, __end, std::less<_ValueType>()); } // Sequential fallback template inline _FIterator max_element(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::max_element(__begin, __end); } // Sequential fallback template inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); } // Sequential fallback for input iterator case template inline _FIterator __max_element_switch(_FIterator __begin, _FIterator __end, _Compare __comp, _IteratorTag) { return max_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _RAIter __max_element_switch(_RAIter __begin, _RAIter __end, _Compare __comp, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().max_element_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _RAIter __res(__begin); __gnu_parallel::__identity_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gnu_parallel::_Nothing(), __functionality, __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp), __res, __res, -1, __parallelism_tag); return __res; } else return max_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline _FIterator max_element(_FIterator __begin, _FIterator __end, __gnu_parallel::_Parallelism __parallelism_tag) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return max_element(__begin, __end, std::less<_ValueType>(), __parallelism_tag); } template inline _FIterator max_element(_FIterator __begin, _FIterator __end) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::max_element(__begin, __end, std::less<_ValueType>()); } // Public interface template inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::_Parallelism __parallelism_tag) { return __max_element_switch(__begin, __end, __comp, std::__iterator_category(__begin), __parallelism_tag); } template inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp) { return __max_element_switch(__begin, __end, __comp, std::__iterator_category(__begin)); } // Sequential fallback template inline _FIterator min_element(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::min_element(__begin, __end); } // Sequential fallback template inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); } // Sequential fallback for input iterator case template inline _FIterator __min_element_switch(_FIterator __begin, _FIterator __end, _Compare __comp, _IteratorTag) { return min_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _RAIter __min_element_switch(_RAIter __begin, _RAIter __end, _Compare __comp, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().min_element_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _RAIter __res(__begin); __gnu_parallel::__identity_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gnu_parallel::_Nothing(), __functionality, __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp), __res, __res, -1, __parallelism_tag); return __res; } else return min_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline _FIterator min_element(_FIterator __begin, _FIterator __end, __gnu_parallel::_Parallelism __parallelism_tag) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return min_element(__begin, __end, std::less<_ValueType>(), __parallelism_tag); } template inline _FIterator min_element(_FIterator __begin, _FIterator __end) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::min_element(__begin, __end, std::less<_ValueType>()); } // Public interface template inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::_Parallelism __parallelism_tag) { return __min_element_switch(__begin, __end, __comp, std::__iterator_category(__begin), __parallelism_tag); } template inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp) { return __min_element_switch(__begin, __end, __comp, std::__iterator_category(__begin)); } } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_ALGO_H */ PKgd1]Yj%j%8/parallel/merge.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/merge.h * @brief Parallel implementation of std::merge(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MERGE_H #define _GLIBCXX_PARALLEL_MERGE_H 1 #include #include namespace __gnu_parallel { /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template _OutputIterator __merge_advance_usual(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { typedef _DifferenceTp _DifferenceType; while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) { // array1[__i1] < array0[i0] if (__comp(*__begin2, *__begin1)) *__target++ = *__begin2++; else *__target++ = *__begin1++; --__max_length; } if (__begin1 != __end1) { __target = std::copy(__begin1, __begin1 + __max_length, __target); __begin1 += __max_length; } else { __target = std::copy(__begin2, __begin2 + __max_length, __target); __begin2 += __max_length; } return __target; } /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * Specially designed code should allow the compiler to generate * conditional moves instead of branches. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template _OutputIterator __merge_advance_movc(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2; #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__max_length >= 0); #endif while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) { _RAIter1 __next1 = __begin1 + 1; _RAIter2 __next2 = __begin2 + 1; _ValueType1 __element1 = *__begin1; _ValueType2 __element2 = *__begin2; if (__comp(__element2, __element1)) { __element1 = __element2; __begin2 = __next2; } else __begin1 = __next1; *__target = __element1; ++__target; --__max_length; } if (__begin1 != __end1) { __target = std::copy(__begin1, __begin1 + __max_length, __target); __begin1 += __max_length; } else { __target = std::copy(__begin2, __begin2 + __max_length, __target); __begin2 += __max_length; } return __target; } /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * Static switch on whether to use the conditional-move variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template inline _OutputIterator __merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { _GLIBCXX_CALL(__max_length) return __merge_advance_movc(__begin1, __end1, __begin2, __end2, __target, __max_length, __comp); } /** @brief Merge routine fallback to sequential in case the iterators of the two input sequences are of different type. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template inline _RAIter3 __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, // different iterators, parallel implementation // not available _RAIter2 __end2, _RAIter3 __target, typename std::iterator_traits<_RAIter1>:: difference_type __max_length, _Compare __comp) { return __merge_advance(__begin1, __end1, __begin2, __end2, __target, __max_length, __comp); } /** @brief Parallel merge routine being able to merge only the @c * __max_length smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * The functionality is projected onto parallel_multiway_merge. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template inline _RAIter3 __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter1& __begin2, _RAIter1 __end2, _RAIter3 __target, typename std::iterator_traits<_RAIter1>:: difference_type __max_length, _Compare __comp) { typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; typedef typename std::iterator_traits<_RAIter1>:: difference_type _DifferenceType1 /* == difference_type2 */; typedef typename std::iterator_traits<_RAIter3>:: difference_type _DifferenceType3; typedef typename std::pair<_RAIter1, _RAIter1> _IteratorPair; _IteratorPair __seqs[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) }; _RAIter3 __target_end = parallel_multiway_merge < /* __stable = */ true, /* __sentinels = */ false> (__seqs, __seqs + 2, __target, multiway_merge_exact_splitting < /* __stable = */ true, _IteratorPair*, _Compare, _DifferenceType1>, __max_length, __comp, omp_get_max_threads()); return __target_end; } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MERGE_H */ PKgd1]{HPP8/parallel/numericnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/numeric * * @brief Parallel STL function calls corresponding to stl_numeric.h. * The functions defined here mainly do case switches and * call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one function call, * are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_NUMERIC_H #define _GLIBCXX_PARALLEL_NUMERIC_H 1 #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // Sequential fallback. template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init, __binary_op); } // Sequential fallback for input iterator case. template inline _Tp __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, _IteratorTag) { return accumulate(__begin, __end, __init, __gnu_parallel::sequential_tag()); } template inline _Tp __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, _IteratorTag) { return accumulate(__begin, __end, __init, __binary_op, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template _Tp __accumulate_switch(__RAIter __begin, __RAIter __end, _Tp __init, _BinaryOperation __binary_op, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().accumulate_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _Tp __res = __init; __gnu_parallel::__accumulate_selector<__RAIter> __my_selector; __gnu_parallel:: __for_each_template_random_access_ed(__begin, __end, __gnu_parallel::_Nothing(), __my_selector, __gnu_parallel:: __accumulate_binop_reduct <_BinaryOperation>(__binary_op), __res, __res, -1); return __res; } else return accumulate(__begin, __end, __init, __binary_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, __gnu_parallel::_Parallelism __parallelism_tag) { typedef std::iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::value_type _ValueType; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __gnu_parallel::_Plus<_Tp, _ValueType>(), _IteratorCategory(), __parallelism_tag); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init) { typedef std::iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::value_type _ValueType; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __gnu_parallel::_Plus<_Tp, _ValueType>(), _IteratorCategory()); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __binary_op, _IteratorCategory(), __parallelism_tag); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __binary_op, _IteratorCategory()); } // Sequential fallback. template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::inner_product( __first1, __last1, __first2, __init); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); } // Parallel algorithm for random access iterators. template _Tp __inner_product_switch(_RAIter1 __first1, _RAIter1 __last1, _RAIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION((__last1 - __first1) >= __gnu_parallel::_Settings::get(). accumulate_minimal_n && __gnu_parallel:: __is_parallel(__parallelism_tag))) { _Tp __res = __init; __gnu_parallel:: __inner_product_selector<_RAIter1, _RAIter2, _Tp> __my_selector(__first1, __first2); __gnu_parallel:: __for_each_template_random_access_ed( __first1, __last1, __binary_op2, __my_selector, __binary_op1, __res, __res, -1); return __res; } else return inner_product(__first1, __last1, __first2, __init, __gnu_parallel::sequential_tag()); } // No parallelism for input iterators. template inline _Tp __inner_product_switch(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, _IteratorTag1, _IteratorTag2) { return inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, __gnu_parallel::sequential_tag()); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, _IteratorCategory1(), _IteratorCategory2(), __parallelism_tag); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, _IteratorCategory1(), _IteratorCategory2()); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type _MultipliesResultType; return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), __gnu_parallel:: _Multiplies<_ValueType1, _ValueType2>(), __parallelism_tag); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type _MultipliesResultType; return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), __gnu_parallel:: _Multiplies<_ValueType1, _ValueType2>()); } // Sequential fallback. template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result); } // Sequential fallback. template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } // Sequential fallback for input iterator case. template inline _OutputIterator __partial_sum_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } // Parallel algorithm for random access iterators. template _OutputIterator __partial_sum_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partial_sum_minimal_n)) return __gnu_parallel::__parallel_partial_sum(__begin, __end, __result, __bin_op); else return partial_sum(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result) { typedef typename iterator_traits<_IIter>::value_type _ValueType; return __gnu_parallel::partial_sum(__begin, __end, __result, std::plus<_ValueType>()); } // Public interface template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __partial_sum_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory()); } // Sequential fallback. template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result); } // Sequential fallback. template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result, __bin_op); } // Sequential fallback for input iterator case. template inline _OutputIterator __adjacent_difference_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2) { return adjacent_difference(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template _OutputIterator __adjacent_difference_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorPair<_IIter, _OutputIterator, random_access_iterator_tag> _ItTrip; *__result = *__begin; _ItTrip __begin_pair(__begin + 1, __result + 1), __end_pair(__end, __result + (__end - __begin)); __gnu_parallel::__adjacent_difference_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access_ed( __begin_pair, __end_pair, __bin_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1); return __functionality._M_finish_iterator; } else return adjacent_difference(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>(), __parallelism_tag); } template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result) { typedef iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>()); } template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __adjacent_difference_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory(), __parallelism_tag); } template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __adjacent_difference_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory()); } } // end namespace } // end namespace #endif /* _GLIBCXX_NUMERIC_H */ PKgd1]q U0U08/parallel/base.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/base.h * @brief Sequential helper functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BASE_H #define _GLIBCXX_PARALLEL_BASE_H 1 #include #include #include #include #include #include // Parallel mode namespaces. /** * @namespace std::__parallel * @brief GNU parallel code, replaces standard behavior with parallel behavior. */ namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { } } /** * @namespace __gnu_parallel * @brief GNU parallel code for public use. */ namespace __gnu_parallel { // Import all the parallel versions of components in namespace std. using namespace std::__parallel; } /** * @namespace __gnu_sequential * @brief GNU sequential classes for public use. */ namespace __gnu_sequential { // Import whatever is the serial version. #ifdef _GLIBCXX_PARALLEL using namespace std::_GLIBCXX_STD_A; #else using namespace std; #endif } namespace __gnu_parallel { // NB: Including this file cannot produce (unresolved) symbols from // the OpenMP runtime unless the parallel mode is actually invoked // and active, which imples that the OpenMP runtime is actually // going to be linked in. inline _ThreadIndex __get_max_threads() { _ThreadIndex __i = omp_get_max_threads(); return __i > 1 ? __i : 1; } inline bool __is_parallel(const _Parallelism __p) { return __p != sequential; } /** @brief Calculates the rounded-down logarithm of @c __n for base 2. * @param __n Argument. * @return Returns 0 for any argument <1. */ template inline _Size __rd_log2(_Size __n) { _Size __k; for (__k = 0; __n > 1; __n >>= 1) ++__k; return __k; } /** @brief Encode two integers into one gnu_parallel::_CASable. * @param __a First integer, to be encoded in the most-significant @c * _CASable_bits/2 bits. * @param __b Second integer, to be encoded in the least-significant * @c _CASable_bits/2 bits. * @return value encoding @c __a and @c __b. * @see __decode2 */ inline _CASable __encode2(int __a, int __b) //must all be non-negative, actually { return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0); } /** @brief Decode two integers from one gnu_parallel::_CASable. * @param __x __gnu_parallel::_CASable to decode integers from. * @param __a First integer, to be decoded from the most-significant * @c _CASable_bits/2 bits of @c __x. * @param __b Second integer, to be encoded in the least-significant * @c _CASable_bits/2 bits of @c __x. * @see __encode2 */ inline void __decode2(_CASable __x, int& __a, int& __b) { __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask); __b = (int)((__x >> 0 ) & _CASable_mask); } //needed for parallel "numeric", even if "algorithm" not included /** @brief Equivalent to std::min. */ template inline const _Tp& min(const _Tp& __a, const _Tp& __b) { return (__a < __b) ? __a : __b; } /** @brief Equivalent to std::max. */ template inline const _Tp& max(const _Tp& __a, const _Tp& __b) { return (__a > __b) ? __a : __b; } /** @brief Constructs predicate for equality from strict weak * ordering predicate */ template class _EqualFromLess : public std::binary_function<_T1, _T2, bool> { private: _Compare& _M_comp; public: _EqualFromLess(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const _T1& __a, const _T2& __b) { return !_M_comp(__a, __b) && !_M_comp(__b, __a); } }; /** @brief Similar to std::unary_negate, * but giving the argument types explicitly. */ template class __unary_negate : public std::unary_function { protected: _Predicate _M_pred; public: explicit __unary_negate(const _Predicate& __x) : _M_pred(__x) { } bool operator()(const argument_type& __x) { return !_M_pred(__x); } }; /** @brief Similar to std::binder1st, * but giving the argument types explicitly. */ template class __binder1st : public std::unary_function<_SecondArgumentType, _ResultType> { protected: _Operation _M_op; _FirstArgumentType _M_value; public: __binder1st(const _Operation& __x, const _FirstArgumentType& __y) : _M_op(__x), _M_value(__y) { } _ResultType operator()(const _SecondArgumentType& __x) { return _M_op(_M_value, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements _ResultType operator()(_SecondArgumentType& __x) const { return _M_op(_M_value, __x); } }; /** * @brief Similar to std::binder2nd, but giving the argument types * explicitly. */ template class __binder2nd : public std::unary_function<_FirstArgumentType, _ResultType> { protected: _Operation _M_op; _SecondArgumentType _M_value; public: __binder2nd(const _Operation& __x, const _SecondArgumentType& __y) : _M_op(__x), _M_value(__y) { } _ResultType operator()(const _FirstArgumentType& __x) const { return _M_op(__x, _M_value); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements _ResultType operator()(_FirstArgumentType& __x) { return _M_op(__x, _M_value); } }; /** @brief Similar to std::equal_to, but allows two different types. */ template struct _EqualTo : std::binary_function<_T1, _T2, bool> { bool operator()(const _T1& __t1, const _T2& __t2) const { return __t1 == __t2; } }; /** @brief Similar to std::less, but allows two different types. */ template struct _Less : std::binary_function<_T1, _T2, bool> { bool operator()(const _T1& __t1, const _T2& __t2) const { return __t1 < __t2; } bool operator()(const _T2& __t2, const _T1& __t1) const { return __t2 < __t1; } }; // Partial specialization for one type. Same as std::less. template struct _Less<_Tp, _Tp> : public std::less<_Tp> { }; /** @brief Similar to std::plus, but allows two different types. */ template(0) + *static_cast<_Tp2*>(0))> struct _Plus : public std::binary_function<_Tp1, _Tp2, _Result> { _Result operator()(const _Tp1& __x, const _Tp2& __y) const { return __x + __y; } }; // Partial specialization for one type. Same as std::plus. template struct _Plus<_Tp, _Tp, _Tp> : public std::plus<_Tp> { }; /** @brief Similar to std::multiplies, but allows two different types. */ template(0) * *static_cast<_Tp2*>(0))> struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Result> { _Result operator()(const _Tp1& __x, const _Tp2& __y) const { return __x * __y; } }; // Partial specialization for one type. Same as std::multiplies. template struct _Multiplies<_Tp, _Tp, _Tp> : public std::multiplies<_Tp> { }; /** @brief _Iterator associated with __gnu_parallel::_PseudoSequence. * If features the usual random-access iterator functionality. * @param _Tp Sequence _M_value type. * @param _DifferenceTp Sequence difference type. */ template class _PseudoSequenceIterator { public: typedef _DifferenceTp _DifferenceType; _PseudoSequenceIterator(const _Tp& __val, _DifferenceType __pos) : _M_val(__val), _M_pos(__pos) { } // Pre-increment operator. _PseudoSequenceIterator& operator++() { ++_M_pos; return *this; } // Post-increment operator. _PseudoSequenceIterator operator++(int) { return _PseudoSequenceIterator(_M_pos++); } const _Tp& operator*() const { return _M_val; } const _Tp& operator[](_DifferenceType) const { return _M_val; } bool operator==(const _PseudoSequenceIterator& __i2) { return _M_pos == __i2._M_pos; } bool operator!=(const _PseudoSequenceIterator& __i2) { return _M_pos != __i2._M_pos; } _DifferenceType operator-(const _PseudoSequenceIterator& __i2) { return _M_pos - __i2._M_pos; } private: const _Tp& _M_val; _DifferenceType _M_pos; }; /** @brief Sequence that conceptually consists of multiple copies of the same element. * The copies are not stored explicitly, of course. * @param _Tp Sequence _M_value type. * @param _DifferenceTp Sequence difference type. */ template class _PseudoSequence { public: typedef _DifferenceTp _DifferenceType; // Better cast down to uint64_t, than up to _DifferenceTp. typedef _PseudoSequenceIterator<_Tp, uint64_t> iterator; /** @brief Constructor. * @param __val Element of the sequence. * @param __count Number of (virtual) copies. */ _PseudoSequence(const _Tp& __val, _DifferenceType __count) : _M_val(__val), _M_count(__count) { } /** @brief Begin iterator. */ iterator begin() const { return iterator(_M_val, 0); } /** @brief End iterator. */ iterator end() const { return iterator(_M_val, _M_count); } private: const _Tp& _M_val; _DifferenceType _M_count; }; /** @brief Compute the median of three referenced elements, according to @c __comp. * @param __a First iterator. * @param __b Second iterator. * @param __c Third iterator. * @param __comp Comparator. */ template _RAIter __median_of_three_iterators(_RAIter __a, _RAIter __b, _RAIter __c, _Compare __comp) { if (__comp(*__a, *__b)) if (__comp(*__b, *__c)) return __b; else if (__comp(*__a, *__c)) return __c; else return __a; else { // Just swap __a and __b. if (__comp(*__a, *__c)) return __a; else if (__comp(*__b, *__c)) return __c; else return __b; } } #if _GLIBCXX_PARALLEL_ASSERTIONS && defined(__glibcxx_assert_impl) #define _GLIBCXX_PARALLEL_ASSERT(_Condition) __glibcxx_assert_impl(_Condition) #else #define _GLIBCXX_PARALLEL_ASSERT(_Condition) #endif } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_BASE_H */ PKgd1]E\228/parallel/basic_iterator.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/basic_iterator.h * @brief Includes the original header files concerned with iterators * except for stream iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BASIC_ITERATOR_H #define _GLIBCXX_PARALLEL_BASIC_ITERATOR_H 1 #include #include #include #include #endif /* _GLIBCXX_PARALLEL_BASIC_ITERATOR_H */ PKgd1]qI8/parallel/omp_loop.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/omp_loop.h * @brief Parallelization of embarrassingly parallel execution by * means of an OpenMP for loop. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_OMP_LOOP_H #define _GLIBCXX_PARALLEL_OMP_LOOP_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using an OpenMP for loop. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, etc.). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_omp_loop(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef typename std::iterator_traits<_RAIter>::difference_type _DifferenceType; _DifferenceType __length = __end - __begin; _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> (__get_max_threads(), __length); _Result *__thread_results; # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = new _Result[__num_threads]; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __thread_results[__i] = _Result(); } _ThreadIndex __iam = omp_get_thread_num(); #pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size) for (_DifferenceType __pos = 0; __pos < __length; ++__pos) __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos)); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __output = __r(__output, __thread_results[__i]); delete [] __thread_results; // Points to last element processed (needed as return value for // some algorithms like transform). __f._M_finish_iterator = __begin + __length; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_OMP_LOOP_H */ PKgd1]8/parallel/types.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/types.h * @brief Basic types and typedefs. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_TYPES_H #define _GLIBCXX_PARALLEL_TYPES_H 1 #include #include #include namespace __gnu_parallel { // Enumerated types. /// Run-time equivalents for the compile-time tags. enum _Parallelism { /// Not parallel. sequential, /// Parallel unbalanced (equal-sized chunks). parallel_unbalanced, /// Parallel balanced (work-stealing). parallel_balanced, /// Parallel with OpenMP dynamic load-balancing. parallel_omp_loop, /// Parallel with OpenMP static load-balancing. parallel_omp_loop_static, /// Parallel with OpenMP taskqueue construct. parallel_taskqueue }; /// Strategies for run-time algorithm selection: // force_sequential, force_parallel, heuristic. enum _AlgorithmStrategy { heuristic, force_sequential, force_parallel }; /// Sorting algorithms: // multi-way mergesort, quicksort, load-balanced quicksort. enum _SortAlgorithm { MWMS, QS, QS_BALANCED }; /// Merging algorithms: // bubblesort-alike, loser-tree variants, enum __sentinel. enum _MultiwayMergeAlgorithm { LOSER_TREE }; /// Partial sum algorithms: recursive, linear. enum _PartialSumAlgorithm { RECURSIVE, LINEAR }; /// Sorting/merging algorithms: sampling, __exact. enum _SplittingAlgorithm { SAMPLING, EXACT }; /// Find algorithms: // growing blocks, equal-sized blocks, equal splitting. enum _FindAlgorithm { GROWING_BLOCKS, CONSTANT_SIZE_BLOCKS, EQUAL_SPLIT }; /** * @brief Unsigned integer to index __elements. * The total number of elements for each algorithm must fit into this type. */ typedef uint64_t _SequenceIndex; /** * @brief Unsigned integer to index a thread number. * The maximum thread number (for each processor) must fit into this type. */ typedef uint16_t _ThreadIndex; // XXX atomics interface? /// Longest compare-and-swappable integer type on this platform. typedef int64_t _CASable; /// Number of bits of _CASable. static const int _CASable_bits = std::numeric_limits<_CASable>::digits; /// ::_CASable with the right half of bits set to 1. static const _CASable _CASable_mask = ((_CASable(1) << (_CASable_bits / 2)) - 1); } #endif /* _GLIBCXX_PARALLEL_TYPES_H */ PKgd1]{ʌ%%8/parallel/workstealing.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/workstealing.h * @brief Parallelization of embarrassingly parallel execution by * means of work-stealing. * * Work stealing is described in * * R. D. Blumofe and C. E. Leiserson. * Scheduling multithreaded computations by work stealing. * Journal of the ACM, 46(5):720–748, 1999. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_WORKSTEALING_H #define _GLIBCXX_PARALLEL_WORKSTEALING_H 1 #include #include #include namespace __gnu_parallel { #define _GLIBCXX_JOB_VOLATILE volatile /** @brief One __job for a certain thread. */ template struct _Job { typedef _DifferenceTp _DifferenceType; /** @brief First element. * * Changed by owning and stealing thread. By stealing thread, * always incremented. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_first; /** @brief Last element. * * Changed by owning thread only. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_last; /** @brief Number of elements, i.e. @c _M_last-_M_first+1. * * Changed by owning thread only. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_load; }; /** @brief Work stealing algorithm for random access iterators. * * Uses O(1) additional memory. Synchronization at job lists is * done with atomic operations. * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __op User-supplied functor (comparator, predicate, adding * functor, ...). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_workstealing(_RAIter __begin, _RAIter __end, _Op __op, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; const _Settings& __s = _Settings::get(); _DifferenceType __chunk_size = static_cast<_DifferenceType>(__s.workstealing_chunk_size); // How many jobs? _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound; // To avoid false sharing in a cache line. const int __stride = (__s.cache_line_size * 10 / sizeof(_Job<_DifferenceType>) + 1); // Total number of threads currently working. _ThreadIndex __busy = 0; _Job<_DifferenceType> *__job; omp_lock_t __output_lock; omp_init_lock(&__output_lock); // Write base value to output. __output = __base; // No more threads than jobs, at least one thread. _ThreadIndex __num_threads = __gnu_parallel::max<_ThreadIndex> (1, __gnu_parallel::min<_DifferenceType>(__length, __get_max_threads())); # pragma omp parallel shared(__busy) num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); // Create job description array. __job = new _Job<_DifferenceType>[__num_threads * __stride]; } // Initialization phase. // Flags for every thread if it is doing productive work. bool __iam_working = false; // Thread id. _ThreadIndex __iam = omp_get_thread_num(); // This job. _Job<_DifferenceType>& __my_job = __job[__iam * __stride]; // Random number (for work stealing). _ThreadIndex __victim; // Local value for reduction. _Result __result = _Result(); // Number of elements to steal in one attempt. _DifferenceType __steal; // Every thread has its own random number generator // (modulo __num_threads). _RandomNumber __rand_gen(__iam, __num_threads); // This thread is currently working. # pragma omp atomic ++__busy; __iam_working = true; // How many jobs per thread? last thread gets the rest. __my_job._M_first = static_cast<_DifferenceType> (__iam * (__length / __num_threads)); __my_job._M_last = (__iam == (__num_threads - 1) ? (__length - 1) : ((__iam + 1) * (__length / __num_threads) - 1)); __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; // Init result with _M_first value (to have a base value for reduction) if (__my_job._M_first <= __my_job._M_last) { // Cannot use volatile variable directly. _DifferenceType __my_first = __my_job._M_first; __result = __f(__op, __begin + __my_first); ++__my_job._M_first; --__my_job._M_load; } _RAIter __current; # pragma omp barrier // Actual work phase // Work on own or stolen current start while (__busy > 0) { // Work until no productive thread left. # pragma omp flush(__busy) // Thread has own work to do while (__my_job._M_first <= __my_job._M_last) { // fetch-and-add call // Reserve current job block (size __chunk_size) in my queue. _DifferenceType __current_job = __fetch_and_add<_DifferenceType>(&(__my_job._M_first), __chunk_size); // Update _M_load, to make the three values consistent, // _M_first might have been changed in the meantime __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; for (_DifferenceType __job_counter = 0; __job_counter < __chunk_size && __current_job <= __my_job._M_last; ++__job_counter) { // Yes: process it! __current = __begin + __current_job; ++__current_job; // Do actual work. __result = __r(__result, __f(__op, __current)); } # pragma omp flush(__busy) } // After reaching this point, a thread's __job list is empty. if (__iam_working) { // This thread no longer has work. # pragma omp atomic --__busy; __iam_working = false; } _DifferenceType __supposed_first, __supposed_last, __supposed_load; do { // Find random nonempty deque (not own), do consistency check. __yield(); # pragma omp flush(__busy) __victim = __rand_gen(); __supposed_first = __job[__victim * __stride]._M_first; __supposed_last = __job[__victim * __stride]._M_last; __supposed_load = __job[__victim * __stride]._M_load; } while (__busy > 0 && ((__supposed_load <= 0) || ((__supposed_first + __supposed_load - 1) != __supposed_last))); if (__busy == 0) break; if (__supposed_load > 0) { // Has work and work to do. // Number of elements to steal (at least one). __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2; // Push __victim's current start forward. _DifferenceType __stolen_first = __fetch_and_add<_DifferenceType> (&(__job[__victim * __stride]._M_first), __steal); _DifferenceType __stolen_try = (__stolen_first + __steal - _DifferenceType(1)); __my_job._M_first = __stolen_first; __my_job._M_last = __gnu_parallel::min(__stolen_try, __supposed_last); __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; // Has potential work again. # pragma omp atomic ++__busy; __iam_working = true; # pragma omp flush(__busy) } # pragma omp flush(__busy) } // end while __busy > 0 // Add accumulated result to output. omp_set_lock(&__output_lock); __output = __r(__output, __result); omp_unset_lock(&__output_lock); } delete[] __job; // Points to last element processed (needed as return value for // some algorithms like transform) __f._M_finish_iterator = __begin + __length; omp_destroy_lock(&__output_lock); return __op; } } // end namespace #endif /* _GLIBCXX_PARALLEL_WORKSTEALING_H */ PKgd1]-7 7 !8/parallel/compiletime_settings.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/compiletime_settings.h * @brief Defines on options concerning debugging and performance, at * compile-time. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #include /** @brief Determine verbosity level of the parallel mode. * Level 1 prints a message each time a parallel-mode function is entered. */ #define _GLIBCXX_VERBOSE_LEVEL 0 /** @def _GLIBCXX_CALL * @brief Macro to produce log message when entering a function. * @param __n Input size. * @see _GLIBCXX_VERBOSE_LEVEL */ #if (_GLIBCXX_VERBOSE_LEVEL == 0) #define _GLIBCXX_CALL(__n) #endif #if (_GLIBCXX_VERBOSE_LEVEL == 1) #define _GLIBCXX_CALL(__n) \ printf(" %__s:\niam = %d, __n = %ld, __num_threads = %d\n", \ __PRETTY_FUNCTION__, omp_get_thread_num(), (__n), __get_max_threads()); #endif #ifndef _GLIBCXX_SCALE_DOWN_FPU /** @brief Use floating-point scaling instead of modulo for mapping * random numbers to a range. This can be faster on certain CPUs. */ #define _GLIBCXX_SCALE_DOWN_FPU 0 #endif #ifndef _GLIBCXX_PARALLEL_ASSERTIONS /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Should be switched on only locally. */ #define _GLIBCXX_PARALLEL_ASSERTIONS (_GLIBCXX_ASSERTIONS+0) #endif #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Consider the size of the L1 cache for * gnu_parallel::__parallel_random_shuffle(). */ #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 0 #endif #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Consider the size of the TLB for * gnu_parallel::__parallel_random_shuffle(). */ #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB 0 #endif PKgd1]~ 1228/parallel/partial_sum.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/partial_sum.h * @brief Parallel implementation of std::partial_sum(), i.e. prefix * sums. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_PARTIAL_SUM_H #define _GLIBCXX_PARALLEL_PARTIAL_SUM_H 1 #include #include #include #include #include namespace __gnu_parallel { // Problem: there is no 0-element given. /** @brief Base case prefix sum routine. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @param __value Start value. Must be passed since the neutral * element is unknown in general. * @return End iterator of output sequence. */ template _OutputIterator __parallel_partial_sum_basecase(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits <_IIter>::value_type __value) { if (__begin == __end) return __result; while (__begin != __end) { __value = __bin_op(__value, *__begin); *__result = __value; ++__result; ++__begin; } return __result; } /** @brief Parallel partial sum implementation, two-phase approach, no recursion. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @param __n Length of sequence. * @return End iterator of output sequence. */ template _OutputIterator __parallel_partial_sum_linear(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits<_IIter>::difference_type __n) { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (__begin == __end) return __result; _ThreadIndex __num_threads = std::min<_DifferenceType>(__get_max_threads(), __n - 1); if (__num_threads < 2) { *__result = *__begin; return __parallel_partial_sum_basecase(__begin + 1, __end, __result + 1, __bin_op, *__begin); } _DifferenceType* __borders; _ValueType* __sums; const _Settings& __s = _Settings::get(); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; if (__s.partial_sum_dilation == 1.0f) __equally_split(__n, __num_threads + 1, __borders); else { _DifferenceType __first_part_length = std::max<_DifferenceType>(1, __n / (1.0f + __s.partial_sum_dilation * __num_threads)); _DifferenceType __chunk_length = (__n - __first_part_length) / __num_threads; _DifferenceType __borderstart = __n - __num_threads * __chunk_length; __borders[0] = 0; for (_ThreadIndex __i = 1; __i < (__num_threads + 1); ++__i) { __borders[__i] = __borderstart; __borderstart += __chunk_length; } __borders[__num_threads + 1] = __n; } __sums = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * __num_threads)); _OutputIterator __target_end; } //single _ThreadIndex __iam = omp_get_thread_num(); if (__iam == 0) { *__result = *__begin; __parallel_partial_sum_basecase(__begin + 1, __begin + __borders[1], __result + 1, __bin_op, *__begin); ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1)); } else { ::new(&(__sums[__iam])) _ValueType(__gnu_parallel::accumulate( __begin + __borders[__iam] + 1, __begin + __borders[__iam + 1], *(__begin + __borders[__iam]), __bin_op, __gnu_parallel::sequential_tag())); } # pragma omp barrier # pragma omp single __parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads, __sums + 1, __bin_op, __sums[0]); # pragma omp barrier // Still same team. __parallel_partial_sum_basecase(__begin + __borders[__iam + 1], __begin + __borders[__iam + 2], __result + __borders[__iam + 1], __bin_op, __sums[__iam]); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __sums[__i].~_ValueType(); ::operator delete(__sums); delete[] __borders; return __result + __n; } /** @brief Parallel partial sum front-__end. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @return End iterator of output sequence. */ template _OutputIterator __parallel_partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op) { _GLIBCXX_CALL(__begin - __end) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; switch (_Settings::get().partial_sum_algorithm) { case LINEAR: // Need an initial offset. return __parallel_partial_sum_linear(__begin, __end, __result, __bin_op, __n); default: // Partial_sum algorithm not implemented. _GLIBCXX_PARALLEL_ASSERT(0); return __result + __n; } } } #endif /* _GLIBCXX_PARALLEL_PARTIAL_SUM_H */ PKgd1] 8B8B8/parallel/balanced_quicksort.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/balanced_quicksort.h * @brief Implementation of a dynamically load-balanced parallel quicksort. * * It works in-place and needs only logarithmic extra memory. * The algorithm is similar to the one proposed in * * P. Tsigas and Y. Zhang. * A simple, fast parallel implementation of quicksort and * its performance evaluation on SUN enterprise 10000. * In 11th Euromicro Conference on Parallel, Distributed and * Network-Based Processing, page 372, 2003. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H #define _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H 1 #include #include #include #include #include #include #include #if _GLIBCXX_PARALLEL_ASSERTIONS #include #ifdef _GLIBCXX_HAVE_UNISTD_H #include #endif #endif namespace __gnu_parallel { /** @brief Information local to one thread in the parallel quicksort run. */ template struct _QSBThreadLocal { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Continuous part of the sequence, described by an iterator pair. */ typedef std::pair<_RAIter, _RAIter> _Piece; /** @brief Initial piece to work on. */ _Piece _M_initial; /** @brief Work-stealing queue. */ _RestrictedBoundedConcurrentQueue<_Piece> _M_leftover_parts; /** @brief Number of threads involved in this algorithm. */ _ThreadIndex _M_num_threads; /** @brief Pointer to a counter of elements left over to sort. */ volatile _DifferenceType* _M_elements_leftover; /** @brief The complete sequence to sort. */ _Piece _M_global; /** @brief Constructor. * @param __queue_size size of the work-stealing queue. */ _QSBThreadLocal(int __queue_size) : _M_leftover_parts(__queue_size) { } }; /** @brief Balanced quicksort divide step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. * @pre @c (__end-__begin)>=1 */ template typename std::iterator_traits<_RAIter>::difference_type __qsb_divide(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_PARALLEL_ASSERT(__num_threads > 0); typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _RAIter __pivot_pos = __median_of_three_iterators(__begin, __begin + (__end - __begin) / 2, __end - 1, __comp); #if defined(_GLIBCXX_PARALLEL_ASSERTIONS) // Must be in between somewhere. _DifferenceType __n = __end - __begin; _GLIBCXX_PARALLEL_ASSERT((!__comp(*__pivot_pos, *__begin) && !__comp(*(__begin + __n / 2), *__pivot_pos)) || (!__comp(*__pivot_pos, *__begin) && !__comp(*(__end - 1), *__pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*__begin, *__pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*(__end - 1), *__pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*__begin, *__pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*(__begin + __n / 2), *__pivot_pos))); #endif // Swap pivot value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, returning __end - __begin - 1 in the worst case. _DifferenceType __split_pos = __parallel_partition(__begin, __end - 1, __pred, __num_threads); // Swap back pivot to middle. std::iter_swap(__begin + __split_pos, __pivot_pos); __pivot_pos = __begin + __split_pos; #if _GLIBCXX_PARALLEL_ASSERTIONS _RAIter __r; for (__r = __begin; __r != __pivot_pos; ++__r) _GLIBCXX_PARALLEL_ASSERT(__comp(*__r, *__pivot_pos)); for (; __r != __end; ++__r) _GLIBCXX_PARALLEL_ASSERT(!__comp(*__r, *__pivot_pos)); #endif return __split_pos; } /** @brief Quicksort conquer step. * @param __tls Array of thread-local storages. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __iam Number of the thread processing this function. * @param __num_threads * Number of threads that are allowed to work on this part. */ template void __qsb_conquer(_QSBThreadLocal<_RAIter>** __tls, _RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __iam, _ThreadIndex __num_threads, bool __parent_wait) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; if (__num_threads <= 1 || __n <= 1) { __tls[__iam]->_M_initial.first = __begin; __tls[__iam]->_M_initial.second = __end; __qsb_local_sort_with_helping(__tls, __comp, __iam, __parent_wait); return; } // Divide step. _DifferenceType __split_pos = __qsb_divide(__begin, __end, __comp, __num_threads); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(0 <= __split_pos && __split_pos < (__end - __begin)); #endif _ThreadIndex __num_threads_leftside = std::max<_ThreadIndex> (1, std::min<_ThreadIndex>(__num_threads - 1, __split_pos * __num_threads / __n)); # pragma omp atomic *__tls[__iam]->_M_elements_leftover -= (_DifferenceType)1; // Conquer step. # pragma omp parallel num_threads(2) { bool __wait; if(omp_get_num_threads() < 2) __wait = false; else __wait = __parent_wait; # pragma omp sections { # pragma omp section { __qsb_conquer(__tls, __begin, __begin + __split_pos, __comp, __iam, __num_threads_leftside, __wait); __wait = __parent_wait; } // The pivot_pos is left in place, to ensure termination. # pragma omp section { __qsb_conquer(__tls, __begin + __split_pos + 1, __end, __comp, __iam + __num_threads_leftside, __num_threads - __num_threads_leftside, __wait); __wait = __parent_wait; } } } } /** * @brief Quicksort step doing load-balanced local sort. * @param __tls Array of thread-local storages. * @param __comp Comparator. * @param __iam Number of the thread processing this function. */ template void __qsb_local_sort_with_helping(_QSBThreadLocal<_RAIter>** __tls, _Compare& __comp, _ThreadIndex __iam, bool __wait) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef std::pair<_RAIter, _RAIter> _Piece; _QSBThreadLocal<_RAIter>& __tl = *__tls[__iam]; _DifferenceType __base_case_n = _Settings::get().sort_qsb_base_case_maximal_n; if (__base_case_n < 2) __base_case_n = 2; _ThreadIndex __num_threads = __tl._M_num_threads; // Every thread has its own random number generator. _RandomNumber __rng(__iam + 1); _Piece __current = __tl._M_initial; _DifferenceType __elements_done = 0; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceType __total_elements_done = 0; #endif for (;;) { // Invariant: __current must be a valid (maybe empty) range. _RAIter __begin = __current.first, __end = __current.second; _DifferenceType __n = __end - __begin; if (__n > __base_case_n) { // Divide. _RAIter __pivot_pos = __begin + __rng(__n); // Swap __pivot_pos value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; __gnu_parallel::__binder2nd <_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, leave pivot unchanged in last place. _RAIter __split_pos1, __split_pos2; __split_pos1 = __gnu_sequential::partition(__begin, __end - 1, __pred); // Left side: < __pivot_pos; __right side: >= __pivot_pos. #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__begin <= __split_pos1 && __split_pos1 < __end); #endif // Swap pivot back to middle. if (__split_pos1 != __pivot_pos) std::iter_swap(__split_pos1, __pivot_pos); __pivot_pos = __split_pos1; // In case all elements are equal, __split_pos1 == 0. if ((__split_pos1 + 1 - __begin) < (__n >> 7) || (__end - __split_pos1) < (__n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not strictly larger than the pivot. __gnu_parallel::__unary_negate<__gnu_parallel::__binder1st <_Compare, _ValueType, _ValueType, bool>, _ValueType> __pred(__gnu_parallel::__binder1st <_Compare, _ValueType, _ValueType, bool> (__comp, *__pivot_pos)); // Find other end of pivot-equal range. __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1, __end, __pred); } else // Only skip the pivot. __split_pos2 = __split_pos1 + 1; // Elements equal to pivot are done. __elements_done += (__split_pos2 - __split_pos1); #if _GLIBCXX_PARALLEL_ASSERTIONS __total_elements_done += (__split_pos2 - __split_pos1); #endif // Always push larger part onto stack. if (((__split_pos1 + 1) - __begin) < (__end - (__split_pos2))) { // Right side larger. if ((__split_pos2) != __end) __tl._M_leftover_parts.push_front (std::make_pair(__split_pos2, __end)); //__current.first = __begin; //already set anyway __current.second = __split_pos1; continue; } else { // Left side larger. if (__begin != __split_pos1) __tl._M_leftover_parts.push_front(std::make_pair (__begin, __split_pos1)); __current.first = __split_pos2; //__current.second = __end; //already set anyway continue; } } else { __gnu_sequential::sort(__begin, __end, __comp); __elements_done += __n; #if _GLIBCXX_PARALLEL_ASSERTIONS __total_elements_done += __n; #endif // Prefer own stack, small pieces. if (__tl._M_leftover_parts.pop_front(__current)) continue; # pragma omp atomic *__tl._M_elements_leftover -= __elements_done; __elements_done = 0; #if _GLIBCXX_PARALLEL_ASSERTIONS double __search_start = omp_get_wtime(); #endif // Look for new work. bool __successfully_stolen = false; while (__wait && *__tl._M_elements_leftover > 0 && !__successfully_stolen #if _GLIBCXX_PARALLEL_ASSERTIONS // Possible dead-lock. && (omp_get_wtime() < (__search_start + 1.0)) #endif ) { _ThreadIndex __victim; __victim = __rng(__num_threads); // Large pieces. __successfully_stolen = (__victim != __iam) && __tls[__victim]->_M_leftover_parts.pop_back(__current); if (!__successfully_stolen) __yield(); #if !defined(__ICC) && !defined(__ECC) # pragma omp flush #endif } #if _GLIBCXX_PARALLEL_ASSERTIONS if (omp_get_wtime() >= (__search_start + 1.0)) { sleep(1); _GLIBCXX_PARALLEL_ASSERT(omp_get_wtime() < (__search_start + 1.0)); } #endif if (!__successfully_stolen) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(*__tl._M_elements_leftover == 0); #endif return; } } } } /** @brief Top-level quicksort routine. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template void __parallel_sort_qsb(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef std::pair<_RAIter, _RAIter> _Piece; typedef _QSBThreadLocal<_RAIter> _TLSType; _DifferenceType __n = __end - __begin; if (__n <= 1) return; // At least one element per processor. if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); // Initialize thread local storage _TLSType** __tls = new _TLSType*[__num_threads]; _DifferenceType __queue_size = (__num_threads * (_ThreadIndex)(__rd_log2(__n) + 1)); for (_ThreadIndex __t = 0; __t < __num_threads; ++__t) __tls[__t] = new _QSBThreadLocal<_RAIter>(__queue_size); // There can never be more than ceil(__rd_log2(__n)) ranges on the // stack, because // 1. Only one processor pushes onto the stack // 2. The largest range has at most length __n // 3. Each range is larger than half of the range remaining volatile _DifferenceType __elements_leftover = __n; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __tls[__i]->_M_elements_leftover = &__elements_leftover; __tls[__i]->_M_num_threads = __num_threads; __tls[__i]->_M_global = std::make_pair(__begin, __end); // Just in case nothing is left to assign. __tls[__i]->_M_initial = std::make_pair(__end, __end); } // Main recursion call. __qsb_conquer(__tls, __begin, __begin + __n, __comp, 0, __num_threads, true); #if _GLIBCXX_PARALLEL_ASSERTIONS // All stack must be empty. _Piece __dummy; for (_ThreadIndex __i = 1; __i < __num_threads; ++__i) _GLIBCXX_PARALLEL_ASSERT( !__tls[__i]->_M_leftover_parts.pop_back(__dummy)); #endif for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) delete __tls[__i]; delete[] __tls; } } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H */ PKgd1]3t8/parallel/multiway_merge.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/multiway_merge.h * @brief Implementation of sequential and parallel multiway merge. * * Explanations on the high-speed merging routines in the appendix of * * P. Sanders. * Fast priority queues for cached memory. * ACM Journal of Experimental Algorithmics, 5, 2000. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Manuel Holtgrewe. #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H #include #include #include #include #include #include #if _GLIBCXX_PARALLEL_ASSERTIONS #include #endif /** @brief Length of a sequence described by a pair of iterators. */ #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first) namespace __gnu_parallel { template _OutputIterator __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2, _OutputIterator, _DifferenceTp, _Compare); /** @brief _Iterator wrapper supporting an implicit supremum at the end * of the sequence, dominating all comparisons. * * The implicit supremum comes with a performance cost. * * Deriving from _RAIter is not possible since * _RAIter need not be a class. */ template class _GuardedIterator { private: /** @brief Current iterator __position. */ _RAIter _M_current; /** @brief End iterator of the sequence. */ _RAIter _M_end; /** @brief _Compare. */ _Compare& __comp; public: /** @brief Constructor. Sets iterator to beginning of sequence. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator provided for associated overloaded * compare operators. */ _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp) : _M_current(__begin), _M_end(__end), __comp(__comp) { } /** @brief Pre-increment operator. * @return This. */ _GuardedIterator<_RAIter, _Compare>& operator++() { ++_M_current; return *this; } /** @brief Dereference operator. * @return Referenced element. */ typename std::iterator_traits<_RAIter>::value_type& operator*() { return *_M_current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ operator _RAIter() { return _M_current; } /** @brief Compare two elements referenced by guarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c true if less. */ friend bool operator<(_GuardedIterator<_RAIter, _Compare>& __bi1, _GuardedIterator<_RAIter, _Compare>& __bi2) { if (__bi1._M_current == __bi1._M_end) // __bi1 is sup return __bi2._M_current == __bi2._M_end; // __bi2 is not sup if (__bi2._M_current == __bi2._M_end) // __bi2 is sup return true; return (__bi1.__comp)(*__bi1, *__bi2); // normal compare } /** @brief Compare two elements referenced by guarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c True if less equal. */ friend bool operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1, _GuardedIterator<_RAIter, _Compare>& __bi2) { if (__bi2._M_current == __bi2._M_end) // __bi1 is sup return __bi1._M_current != __bi1._M_end; // __bi2 is not sup if (__bi1._M_current == __bi1._M_end) // __bi2 is sup return false; return !(__bi1.__comp)(*__bi2, *__bi1); // normal compare } }; template class _UnguardedIterator { private: /** @brief Current iterator __position. */ _RAIter _M_current; /** @brief _Compare. */ _Compare& __comp; public: /** @brief Constructor. Sets iterator to beginning of sequence. * @param __begin Begin iterator of sequence. * @param __end Unused, only for compatibility. * @param __comp Unused, only for compatibility. */ _UnguardedIterator(_RAIter __begin, _RAIter /* __end */, _Compare& __comp) : _M_current(__begin), __comp(__comp) { } /** @brief Pre-increment operator. * @return This. */ _UnguardedIterator<_RAIter, _Compare>& operator++() { ++_M_current; return *this; } /** @brief Dereference operator. * @return Referenced element. */ typename std::iterator_traits<_RAIter>::value_type& operator*() { return *_M_current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ operator _RAIter() { return _M_current; } /** @brief Compare two elements referenced by unguarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c true if less. */ friend bool operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1, _UnguardedIterator<_RAIter, _Compare>& __bi2) { // Normal compare. return (__bi1.__comp)(*__bi1, *__bi2); } /** @brief Compare two elements referenced by unguarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c True if less equal. */ friend bool operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1, _UnguardedIterator<_RAIter, _Compare>& __bi2) { // Normal compare. return !(__bi1.__comp)(*__bi2, *__bi1); } }; /** @brief Highly efficient 3-way merging procedure. * * Merging is done with the algorithm implementation described by Peter * Sanders. Basically, the idea is to minimize the number of necessary * comparison after merging an element. The implementation trick * that makes this fast is that the order of the sequences is stored * in the instruction pointer (translated into labels in C++). * * This works well for merging up to 4 sequences. * * Note that making the merging stable does @a not come at a * performance hit. * * Whether the merging is done guarded or unguarded is selected by the * used iterator class. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template class iterator, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_3_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length); typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; if (__length == 0) return __target; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceTp __orig_length = __length; #endif iterator<_RAIter1, _Compare> __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp), __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp), __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp); if (__seq0 <= __seq1) { if (__seq1 <= __seq2) goto __s012; else if (__seq2 < __seq0) goto __s201; else goto __s021; } else { if (__seq1 <= __seq2) { if (__seq0 <= __seq2) goto __s102; else goto __s120; } else goto __s210; } #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \ __s ## __a ## __b ## __c : \ *__target = *__seq ## __a; \ ++__target; \ --__length; \ ++__seq ## __a; \ if (__length == 0) goto __finish; \ if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \ if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \ goto __s ## __b ## __c ## __a; _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < ); _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < ); _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < ); #undef _GLIBCXX_PARALLEL_MERGE_3_CASE __finish: ; #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( ((_RAIter1)__seq0 - __seqs_begin[0].first) + ((_RAIter1)__seq1 - __seqs_begin[1].first) + ((_RAIter1)__seq2 - __seqs_begin[2].first) == __orig_length); #endif __seqs_begin[0].first = __seq0; __seqs_begin[1].first = __seq1; __seqs_begin[2].first = __seq2; return __target; } /** * @brief Highly efficient 4-way merging procedure. * * Merging is done with the algorithm implementation described by Peter * Sanders. Basically, the idea is to minimize the number of necessary * comparison after merging an element. The implementation trick * that makes this fast is that the order of the sequences is stored * in the instruction pointer (translated into goto labels in C++). * * This works well for merging up to 4 sequences. * * Note that making the merging stable does @a not come at a * performance hit. * * Whether the merging is done guarded or unguarded is selected by the * used iterator class. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template class iterator, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_4_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length); typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; iterator<_RAIter1, _Compare> __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp), __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp), __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp), __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp); #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) { \ if (__seq ## __d < __seq ## __a) \ goto __s ## __d ## __a ## __b ## __c; \ if (__seq ## __d < __seq ## __b) \ goto __s ## __a ## __d ## __b ## __c; \ if (__seq ## __d < __seq ## __c) \ goto __s ## __a ## __b ## __d ## __c; \ goto __s ## __a ## __b ## __c ## __d; } if (__seq0 <= __seq1) { if (__seq1 <= __seq2) _GLIBCXX_PARALLEL_DECISION(0,1,2,3) else if (__seq2 < __seq0) _GLIBCXX_PARALLEL_DECISION(2,0,1,3) else _GLIBCXX_PARALLEL_DECISION(0,2,1,3) } else { if (__seq1 <= __seq2) { if (__seq0 <= __seq2) _GLIBCXX_PARALLEL_DECISION(1,0,2,3) else _GLIBCXX_PARALLEL_DECISION(1,2,0,3) } else _GLIBCXX_PARALLEL_DECISION(2,1,0,3) } #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d, \ __c0, __c1, __c2) \ __s ## __a ## __b ## __c ## __d: \ if (__length == 0) goto __finish; \ *__target = *__seq ## __a; \ ++__target; \ --__length; \ ++__seq ## __a; \ if (__seq ## __a __c0 __seq ## __b) \ goto __s ## __a ## __b ## __c ## __d; \ if (__seq ## __a __c1 __seq ## __c) \ goto __s ## __b ## __a ## __c ## __d; \ if (__seq ## __a __c2 __seq ## __d) \ goto __s ## __b ## __c ## __a ## __d; \ goto __s ## __b ## __c ## __d ## __a; _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < ); #undef _GLIBCXX_PARALLEL_MERGE_4_CASE #undef _GLIBCXX_PARALLEL_DECISION __finish: ; __seqs_begin[0].first = __seq0; __seqs_begin[1].first = __seq1; __seqs_begin[2].first = __seq2; __seqs_begin[3].first = __seq3; return __target; } /** @brief Multi-way merging procedure for a high branching factor, * guarded case. * * This merging variant uses a LoserTree class as selected by _LT. * * Stability is selected through the used LoserTree class _LT. * * At least one non-empty sequence is required. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template _RAIter3 multiway_merge_loser_tree(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); _LT __lt(__k, __comp); // Default value for potentially non-default-constructible types. _ValueType* __arbitrary_element = 0; for (_SeqNumber __t = 0; __t < __k; ++__t) { if(!__arbitrary_element && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0) __arbitrary_element = &(*__seqs_begin[__t].first); } for (_SeqNumber __t = 0; __t < __k; ++__t) { if (__seqs_begin[__t].first == __seqs_begin[__t].second) __lt.__insert_start(*__arbitrary_element, __t, true); else __lt.__insert_start(*__seqs_begin[__t].first, __t, false); } __lt.__init(); _SeqNumber __source; for (_DifferenceType __i = 0; __i < __length; ++__i) { //take out __source = __lt.__get_min_source(); *(__target++) = *(__seqs_begin[__source].first++); // Feed. if (__seqs_begin[__source].first == __seqs_begin[__source].second) __lt.__delete_min_insert(*__arbitrary_element, true); else // Replace from same __source. __lt.__delete_min_insert(*__seqs_begin[__source].first, false); } return __target; } /** @brief Multi-way merging procedure for a high branching factor, * unguarded case. * * Merging is done using the LoserTree class _LT. * * Stability is selected by the used LoserTrees. * * @pre No input will run out of elements during the merge. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template _RAIter3 multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _SeqNumber __k = __seqs_end - __seqs_begin; _LT __lt(__k, __sentinel, __comp); for (_SeqNumber __t = 0; __t < __k; ++__t) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first != __seqs_begin[__t].second); #endif __lt.__insert_start(*__seqs_begin[__t].first, __t, false); } __lt.__init(); _SeqNumber __source; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceType __i = 0; #endif _RAIter3 __target_end = __target + __length; while (__target < __target_end) { // Take out. __source = __lt.__get_min_source(); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k); _GLIBCXX_PARALLEL_ASSERT(__i == 0 || !__comp(*(__seqs_begin[__source].first), *(__target - 1))); #endif // Feed. *(__target++) = *(__seqs_begin[__source].first++); #if _GLIBCXX_PARALLEL_ASSERTIONS ++__i; #endif // Replace from same __source. __lt.__delete_min_insert(*__seqs_begin[__source].first, false); } return __target; } /** @brief Multi-way merging procedure for a high branching factor, * requiring sentinels to exist. * * @tparam UnguardedLoserTree _Loser Tree variant to use for the unguarded * merging. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template _RAIter3 multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef std::iterator_traits<_RAIterIterator> _TraitsType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _RAIter3 __target_end; for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) // Move the sequence ends to the sentinel. This has the // effect that the sentinel appears to be within the sequence. Then, // we can use the unguarded variant if we merge out as many // non-sentinel elements as we have. ++((*__s).second); __target_end = multiway_merge_loser_tree_unguarded (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length); _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp)); #endif // Restore the sequence ends so the sentinels are not contained in the // sequence any more (see comment in loop above). for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) --((*__s).second); return __target_end; } /** * @brief Traits for determining whether the loser tree should * use pointers or copies. * * The field "_M_use_pointer" is used to determine whether to use pointers * in he loser trees or whether to copy the values into the loser tree. * * The default behavior is to use pointers if the data type is 4 times as * big as the pointer to it. * * Specialize for your data type to customize the behavior. * * Example: * * template<> * struct _LoserTreeTraits * { static const bool _M_use_pointer = false; }; * * template<> * struct _LoserTreeTraits * { static const bool _M_use_pointer = true; }; * * @param _Tp type to give the loser tree traits for. */ template struct _LoserTreeTraits { /** * @brief True iff to use pointers instead of values in loser trees. * * The default behavior is to use pointers if the data type is four * times as big as the pointer to it. */ static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*)); }; /** * @brief Switch for 3-way merging with __sentinels turned off. * * Note that 3-way merging is always stable! */ template struct __multiway_merge_3_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_3_variant<_GuardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 3-way merging with __sentinels turned on. * * Note that 3-way merging is always stable! */ template struct __multiway_merge_3_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_3_variant<_UnguardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 4-way merging with __sentinels turned off. * * Note that 4-way merging is always stable! */ template struct __multiway_merge_4_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_4_variant<_GuardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 4-way merging with __sentinels turned on. * * Note that 4-way merging is always stable! */ template struct __multiway_merge_4_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_4_variant<_UnguardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for k-way merging with __sentinels turned on. */ template struct __multiway_merge_k_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; return multiway_merge_loser_tree_sentinel< typename __gnu_cxx::__conditional_type< _LoserTreeTraits<_ValueType>::_M_use_pointer, _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>, _LoserTreeUnguarded<__stable, _ValueType, _Compare> >::__type> (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); } }; /** * @brief Switch for k-way merging with __sentinels turned off. */ template struct __multiway_merge_k_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; return multiway_merge_loser_tree< typename __gnu_cxx::__conditional_type< _LoserTreeTraits<_ValueType>::_M_use_pointer, _LoserTreePointer<__stable, _ValueType, _Compare>, _LoserTree<__stable, _ValueType, _Compare> >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** @brief Sequential multi-way merging switch. * * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and * runtime settings. * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * @param __sentinel The sequences have __a __sentinel element. * @return End iterator of output sequence. */ template _RAIter3 __sequential_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; #if _GLIBCXX_PARALLEL_ASSERTIONS for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) { _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first, (*__s).second, __comp)); } #endif _DifferenceTp __total_length = 0; for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) __total_length += _GLIBCXX_PARALLEL_LENGTH(*__s); __length = std::min<_DifferenceTp>(__length, __total_length); if(__length == 0) return __target; _RAIter3 __return_target = __target; _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); switch (__k) { case 0: break; case 1: __return_target = std::copy(__seqs_begin[0].first, __seqs_begin[0].first + __length, __target); __seqs_begin[0].first += __length; break; case 2: __return_target = __merge_advance(__seqs_begin[0].first, __seqs_begin[0].second, __seqs_begin[1].first, __seqs_begin[1].second, __target, __length, __comp); break; case 3: __return_target = __multiway_merge_3_variant_sentinel_switch <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __length, __comp); break; case 4: __return_target = __multiway_merge_4_variant_sentinel_switch <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __length, __comp); break; default: __return_target = __multiway_merge_k_variant_sentinel_switch <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( __is_sorted(__target, __target + __length, __comp)); #endif return __return_target; } /** * @brief Stable sorting functor. * * Used to reduce code instanciation in multiway_merge_sampling_splitting. */ template struct _SamplingSorter { void operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp) { __gnu_sequential::stable_sort(__first, __last, __comp); } }; /** * @brief Non-__stable sorting functor. * * Used to reduce code instantiation in multiway_merge_sampling_splitting. */ template struct _SamplingSorter { void operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp) { __gnu_sequential::sort(__first, __last, __comp); } }; /** * @brief Sampling based splitting for parallel multiway-merge routine. */ template void multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector > *__pieces) { typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; // __k sequences. const _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); const _ThreadIndex __num_threads = omp_get_num_threads(); const _DifferenceType __num_samples = __gnu_parallel::_Settings::get().merge_oversampling * __num_threads; _ValueType* __samples = static_cast<_ValueType*> (::operator new(sizeof(_ValueType) * __k * __num_samples)); // Sample. for (_SeqNumber __s = 0; __s < __k; ++__s) for (_DifferenceType __i = 0; __i < __num_samples; ++__i) { _DifferenceType sample_index = static_cast<_DifferenceType> (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s]) * (double(__i + 1) / (__num_samples + 1)) * (double(__length) / __total_length)); new(&(__samples[__s * __num_samples + __i])) _ValueType(__seqs_begin[__s].first[sample_index]); } // Sort stable or non-stable, depending on value of template parameter // "__stable". _SamplingSorter<__stable, _ValueType*, _Compare>() (__samples, __samples + (__num_samples * __k), __comp); for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab) // For each slab / processor. for (_SeqNumber __seq = 0; __seq < __k; ++__seq) { // For each sequence. if (__slab > 0) __pieces[__slab][__seq].first = std::upper_bound (__seqs_begin[__seq].first, __seqs_begin[__seq].second, __samples[__num_samples * __k * __slab / __num_threads], __comp) - __seqs_begin[__seq].first; else // Absolute beginning. __pieces[__slab][__seq].first = 0; if ((__slab + 1) < __num_threads) __pieces[__slab][__seq].second = std::upper_bound (__seqs_begin[__seq].first, __seqs_begin[__seq].second, __samples[__num_samples * __k * (__slab + 1) / __num_threads], __comp) - __seqs_begin[__seq].first; else // Absolute end. __pieces[__slab][__seq].second = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]); } for (_SeqNumber __s = 0; __s < __k; ++__s) for (_DifferenceType __i = 0; __i < __num_samples; ++__i) __samples[__s * __num_samples + __i].~_ValueType(); ::operator delete(__samples); } /** * @brief Exact splitting for parallel multiway-merge routine. * * None of the passed sequences may be empty. */ template void multiway_merge_exact_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector > *__pieces) { typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; const bool __tight = (__total_length == __length); // __k sequences. const _SeqNumber __k = __seqs_end - __seqs_begin; const _ThreadIndex __num_threads = omp_get_num_threads(); // (Settings::multiway_merge_splitting // == __gnu_parallel::_Settings::EXACT). std::vector<_RAIter1>* __offsets = new std::vector<_RAIter1>[__num_threads]; std::vector > __se(__k); copy(__seqs_begin, __seqs_end, __se.begin()); _DifferenceType* __borders = new _DifferenceType[__num_threads + 1]; __equally_split(__length, __num_threads, __borders); for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s) { __offsets[__s].resize(__k); multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1], __offsets[__s].begin(), __comp); // Last one also needed and available. if (!__tight) { __offsets[__num_threads - 1].resize(__k); multiseq_partition(__se.begin(), __se.end(), _DifferenceType(__length), __offsets[__num_threads - 1].begin(), __comp); } } delete[] __borders; for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab) { // For each slab / processor. for (_SeqNumber __seq = 0; __seq < __k; ++__seq) { // For each sequence. if (__slab == 0) { // Absolute beginning. __pieces[__slab][__seq].first = 0; } else __pieces[__slab][__seq].first = __pieces[__slab - 1][__seq].second; if (!__tight || __slab < (__num_threads - 1)) __pieces[__slab][__seq].second = __offsets[__slab][__seq] - __seqs_begin[__seq].first; else { // __slab == __num_threads - 1 __pieces[__slab][__seq].second = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]); } } } delete[] __offsets; } /** @brief Parallel multi-way merge routine. * * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor * and runtime settings. * * Must not be called if the number of sequences is 1. * * @tparam _Splitter functor to split input (either __exact or sampling based) * @tparam __stable Stable merging incurs a performance penalty. * @tparam __sentinel Ignored. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * @return End iterator of output sequence. */ template _RAIter3 parallel_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _Splitter __splitter, _DifferenceTp __length, _Compare __comp, _ThreadIndex __num_threads) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1); #endif _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; // Leave only non-empty sequences. typedef std::pair<_RAIter1, _RAIter1> seq_type; seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin]; _SeqNumber __k = 0; _DifferenceType __total_length = 0; for (_RAIterIterator __raii = __seqs_begin; __raii != __seqs_end; ++__raii) { _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii); if(__seq_length > 0) { __total_length += __seq_length; __ne_seqs[__k++] = *__raii; } } _GLIBCXX_CALL(__total_length) __length = std::min<_DifferenceTp>(__length, __total_length); if (__total_length == 0 || __k == 0) { delete[] __ne_seqs; return __target; } std::vector >* __pieces; __num_threads = static_cast<_ThreadIndex> (std::min<_DifferenceType>(__num_threads, __total_length)); # pragma omp parallel num_threads (__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); // Thread __t will have to merge pieces[__iam][0..__k - 1] __pieces = new std::vector< std::pair<_DifferenceType, _DifferenceType> >[__num_threads]; for (_ThreadIndex __s = 0; __s < __num_threads; ++__s) __pieces[__s].resize(__k); _DifferenceType __num_samples = __gnu_parallel::_Settings::get().merge_oversampling * __num_threads; __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length, __comp, __pieces); } //single _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __target_position = 0; for (_SeqNumber __c = 0; __c < __k; ++__c) __target_position += __pieces[__iam][__c].first; seq_type* __chunks = new seq_type[__k]; for (_SeqNumber __s = 0; __s < __k; ++__s) __chunks[__s] = std::make_pair(__ne_seqs[__s].first + __pieces[__iam][__s].first, __ne_seqs[__s].first + __pieces[__iam][__s].second); if(__length > __target_position) __sequential_multiway_merge<__stable, __sentinels> (__chunks, __chunks + __k, __target + __target_position, *(__seqs_begin->second), __length - __target_position, __comp); delete[] __chunks; } // parallel #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( __is_sorted(__target, __target + __length, __comp)); #endif __k = 0; // Update ends of sequences. for (_RAIterIterator __raii = __seqs_begin; __raii != __seqs_end; ++__raii) { _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii); if(__length > 0) (*__raii).first += __pieces[__num_threads - 1][__k++].second; } delete[] __pieces; delete[] __ne_seqs; return __target + __length; } /** * @brief Multiway Merge Frontend. * * Merge the sequences specified by seqs_begin and __seqs_end into * __target. __seqs_begin and __seqs_end must point to a sequence of * pairs. These pairs must contain an iterator to the beginning * of a sequence in their first entry and an iterator the _M_end of * the same sequence in their second entry. * * Ties are broken arbitrarily. See stable_multiway_merge for a variant * that breaks ties by sequence number but is slower. * * The first entries of the pairs (i.e. the begin iterators) will be moved * forward. * * The output sequence has to provide enough space for all elements * that are written to it. * * This function will merge the input sequences: * * - not stable * - parallel, depending on the input size and Settings * - using sampling for splitting * - not using sentinels * * Example: * *
   *   int sequences[10][10];
   *   for (int __i = 0; __i < 10; ++__i)
   *     for (int __j = 0; __i < 10; ++__j)
   *       sequences[__i][__j] = __j;
   *
   *   int __out[33];
   *   std::vector > seqs;
   *   for (int __i = 0; __i < 10; ++__i)
   *     { seqs.push(std::make_pair(sequences[__i],
   *                                      sequences[__i] + 10)) }
   *
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less(), 33);
   * 
* * @see stable_multiway_merge * * @pre All input sequences must be sorted. * @pre Target must provide enough space to merge out length elements or * the number of elements in all sequences, whichever is smaller. * * @post [__target, return __value) contains merged __elements from the * input sequences. * @post return __value - __target = min(__length, number of elements in all * sequences). * * @tparam _RAIterPairIterator iterator over sequence * of pairs of iterators * @tparam _RAIterOut iterator over target sequence * @tparam _DifferenceTp difference type for the sequence * @tparam _Compare strict weak ordering type to compare elements * in sequences * * @param __seqs_begin __begin of sequence __sequence * @param __seqs_end _M_end of sequence __sequence * @param __target target sequence to merge to. * @param __comp strict weak ordering to use for element comparison. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * * @return _M_end iterator of output sequence */ // multiway_merge // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // stable_multiway_merge // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return stable_multiway_merge (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return stable_multiway_merge (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } /** * @brief Multiway Merge Frontend. * * Merge the sequences specified by seqs_begin and __seqs_end into * __target. __seqs_begin and __seqs_end must point to a sequence of * pairs. These pairs must contain an iterator to the beginning * of a sequence in their first entry and an iterator the _M_end of * the same sequence in their second entry. * * Ties are broken arbitrarily. See stable_multiway_merge for a variant * that breaks ties by sequence number but is slower. * * The first entries of the pairs (i.e. the begin iterators) will be moved * forward accordingly. * * The output sequence has to provide enough space for all elements * that are written to it. * * This function will merge the input sequences: * * - not stable * - parallel, depending on the input size and Settings * - using sampling for splitting * - using sentinels * * You have to take care that the element the _M_end iterator points to is * readable and contains a value that is greater than any other non-sentinel * value in all sequences. * * Example: * *
   *   int sequences[10][11];
   *   for (int __i = 0; __i < 10; ++__i)
   *     for (int __j = 0; __i < 11; ++__j)
   *       sequences[__i][__j] = __j; // __last one is sentinel!
   *
   *   int __out[33];
   *   std::vector > seqs;
   *   for (int __i = 0; __i < 10; ++__i)
   *     { seqs.push(std::make_pair(sequences[__i],
   *                                      sequences[__i] + 10)) }
   *
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less(), 33);
   * 
* * @pre All input sequences must be sorted. * @pre Target must provide enough space to merge out length elements or * the number of elements in all sequences, whichever is smaller. * @pre For each @c __i, @c __seqs_begin[__i].second must be the end * marker of the sequence, but also reference the one more __sentinel * element. * * @post [__target, return __value) contains merged __elements from the * input sequences. * @post return __value - __target = min(__length, number of elements in all * sequences). * * @see stable_multiway_merge_sentinels * * @tparam _RAIterPairIterator iterator over sequence * of pairs of iterators * @tparam _RAIterOut iterator over target sequence * @tparam _DifferenceTp difference type for the sequence * @tparam _Compare strict weak ordering type to compare elements * in sequences * * @param __seqs_begin __begin of sequence __sequence * @param __seqs_end _M_end of sequence __sequence * @param __target target sequence to merge to. * @param __comp strict weak ordering to use for element comparison. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * * @return _M_end iterator of output sequence */ // multiway_merge_sentinels // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge ( __seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // stable_multiway_merge_sentinels // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return stable_multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return stable_multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } }; // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */ PKgd1]1{PP8/parallel/find_selectors.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/find_selectors.h * @brief _Function objects representing different tasks to be plugged * into the parallel find algorithm. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1 #include #include #include namespace __gnu_parallel { /** @brief Base class of all __gnu_parallel::__find_template selectors. */ struct __generic_find_selector { }; /** * @brief Test predicate on a single element, used for std::find() * and std::find_if (). */ struct __find_if_selector : public __generic_find_selector { /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { return __pred(*__i1); } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return std::make_pair(find_if(__begin1, __end1, __pred, sequential_tag()), __begin2); } }; /** @brief Test predicate on two adjacent elements. */ struct __adjacent_find_selector : public __generic_find_selector { /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { // Passed end iterator is one short. return __pred(*__i1, *(__i1 + 1)); } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { // Passed end iterator is one short. _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1, __pred, sequential_tag()); if (__spot == (__end1 + 1)) __spot = __end1; return std::make_pair(__spot, __begin2); } }; /** @brief Test inverted predicate on a single element. */ struct __mismatch_selector : public __generic_find_selector { /** * @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { return !__pred(*__i1, *__i2); } /** * @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return mismatch(__begin1, __end1, __begin2, __pred, sequential_tag()); } }; /** @brief Test predicate on several elements. */ template struct __find_first_of_selector : public __generic_find_selector { _FIterator _M_begin; _FIterator _M_end; explicit __find_first_of_selector(_FIterator __begin, _FIterator __end) : _M_begin(__begin), _M_end(__end) { } /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { for (_FIterator __pos_in_candidates = _M_begin; __pos_in_candidates != _M_end; ++__pos_in_candidates) if (__pred(*__i1, *__pos_in_candidates)) return true; return false; } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return std::make_pair(find_first_of(__begin1, __end1, _M_begin, _M_end, __pred, sequential_tag()), __begin2); } }; } #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */ PKgd1]Ģ^^8/parallel/tags.hnu[// -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/tags.h * @brief Tags for compile-time selection. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_TAGS_H #define _GLIBCXX_PARALLEL_TAGS_H 1 #include #include namespace __gnu_parallel { /** @brief Forces sequential execution at compile time. */ struct sequential_tag { }; /** @brief Recommends parallel execution at compile time, * optionally using a user-specified number of threads. */ struct parallel_tag { private: _ThreadIndex _M_num_threads; public: /** @brief Default constructor. Use default number of threads. */ parallel_tag() { _M_num_threads = 0; } /** @brief Default constructor. Recommend number of threads to use. * @param __num_threads Desired number of threads. */ parallel_tag(_ThreadIndex __num_threads) { _M_num_threads = __num_threads; } /** @brief Find out desired number of threads. * @return Desired number of threads. */ _ThreadIndex __get_num_threads() { if(_M_num_threads == 0) return omp_get_max_threads(); else return _M_num_threads; } /** @brief Set the desired number of threads. * @param __num_threads Desired number of threads. */ void set_num_threads(_ThreadIndex __num_threads) { _M_num_threads = __num_threads; } }; /** @brief Recommends parallel execution using the default parallel algorithm. */ struct default_parallel_tag : public parallel_tag { default_parallel_tag() { } default_parallel_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Recommends parallel execution using dynamic load-balancing at compile time. */ struct balanced_tag : public parallel_tag { }; /** @brief Recommends parallel execution using static load-balancing at compile time. */ struct unbalanced_tag : public parallel_tag { }; /** @brief Recommends parallel execution using OpenMP dynamic load-balancing at compile time. */ struct omp_loop_tag : public parallel_tag { }; /** @brief Recommends parallel execution using OpenMP static load-balancing at compile time. */ struct omp_loop_static_tag : public parallel_tag { }; /** @brief Base class for for std::find() variants. */ struct find_tag { }; /** @brief Forces parallel merging * with exact splitting, at compile time. */ struct exact_tag : public parallel_tag { exact_tag() { } exact_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel merging * with exact splitting, at compile time. */ struct sampling_tag : public parallel_tag { sampling_tag() { } sampling_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * at compile time. */ struct multiway_mergesort_tag : public parallel_tag { multiway_mergesort_tag() { } multiway_mergesort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * with exact splitting at compile time. */ struct multiway_mergesort_exact_tag : public parallel_tag { multiway_mergesort_exact_tag() { } multiway_mergesort_exact_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * with splitting by sampling at compile time. */ struct multiway_mergesort_sampling_tag : public parallel_tag { multiway_mergesort_sampling_tag() { } multiway_mergesort_sampling_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using unbalanced quicksort * at compile time. */ struct quicksort_tag : public parallel_tag { quicksort_tag() { } quicksort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using balanced quicksort * at compile time. */ struct balanced_quicksort_tag : public parallel_tag { balanced_quicksort_tag() { } balanced_quicksort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Selects the growing block size variant for std::find(). @see _GLIBCXX_FIND_GROWING_BLOCKS */ struct growing_blocks_tag : public find_tag { }; /** @brief Selects the constant block size variant for std::find(). @see _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS */ struct constant_size_blocks_tag : public find_tag { }; /** @brief Selects the equal splitting variant for std::find(). @see _GLIBCXX_FIND_EQUAL_SPLIT */ struct equal_split_tag : public find_tag { }; } #endif /* _GLIBCXX_PARALLEL_TAGS_H */ PKgd1]V^nRR 8/valarraynu[// The template and inlines for the -*- C++ -*- valarray class. // Copyright (C) 1997-2018 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/valarray * This is a Standard C++ Library header. */ // Written by Gabriel Dos Reis #ifndef _GLIBCXX_VALARRAY #define _GLIBCXX_VALARRAY 1 #pragma GCC system_header #include #include #include #include #if __cplusplus >= 201103L #include #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template class _Expr; template class _ValArray; template class _Meta, class _Dom> struct _UnClos; template class _Meta1, template class _Meta2, class _Dom1, class _Dom2> class _BinClos; template class _Meta, class _Dom> class _SClos; template class _Meta, class _Dom> class _GClos; template class _Meta, class _Dom> class _IClos; template class _Meta, class _Dom> class _ValFunClos; template class _Meta, class _Dom> class _RefFunClos; template class valarray; // An array of type _Tp class slice; // BLAS-like slice out of an array template class slice_array; class gslice; // generalized slice out of an array template class gslice_array; template class mask_array; // masked array template class indirect_array; // indirected array _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup numeric_arrays Numeric Arrays * @ingroup numerics * * Classes and functions for representing and manipulating arrays of elements. * @{ */ /** * @brief Smart array designed to support numeric processing. * * A valarray is an array that provides constraints intended to allow for * effective optimization of numeric array processing by reducing the * aliasing that can result from pointer representations. It represents a * one-dimensional array from which different multidimensional subsets can * be accessed and modified. * * @tparam _Tp Type of object in the array. */ template class valarray { template struct _UnaryOp { typedef typename __fun<_Op, _Tp>::result_type __rt; typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; }; public: typedef _Tp value_type; // _lib.valarray.cons_ construct/destroy: /// Construct an empty array. valarray(); /// Construct an array with @a n elements. explicit valarray(size_t); /// Construct an array with @a n elements initialized to @a t. valarray(const _Tp&, size_t); /// Construct an array initialized to the first @a n elements of @a t. valarray(const _Tp* __restrict__, size_t); /// Copy constructor. valarray(const valarray&); #if __cplusplus >= 201103L /// Move constructor. valarray(valarray&&) noexcept; #endif /// Construct an array with the same size and values in @a sa. valarray(const slice_array<_Tp>&); /// Construct an array with the same size and values in @a ga. valarray(const gslice_array<_Tp>&); /// Construct an array with the same size and values in @a ma. valarray(const mask_array<_Tp>&); /// Construct an array with the same size and values in @a ia. valarray(const indirect_array<_Tp>&); #if __cplusplus >= 201103L /// Construct an array with an initializer_list of values. valarray(initializer_list<_Tp>); #endif template valarray(const _Expr<_Dom, _Tp>& __e); ~valarray() _GLIBCXX_NOEXCEPT; // _lib.valarray.assign_ assignment: /** * @brief Assign elements to an array. * * Assign elements of array to values in @a v. * * @param __v Valarray to get values from. */ valarray<_Tp>& operator=(const valarray<_Tp>& __v); #if __cplusplus >= 201103L /** * @brief Move assign elements to an array. * * Move assign elements of array to values in @a v. * * @param __v Valarray to get values from. */ valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept; #endif /** * @brief Assign elements to a value. * * Assign all elements of array to @a t. * * @param __t Value for elements. */ valarray<_Tp>& operator=(const _Tp& __t); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a sa. Results are undefined * if @a sa does not have the same size as this array. * * @param __sa Array slice to get values from. */ valarray<_Tp>& operator=(const slice_array<_Tp>& __sa); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a ga. Results are undefined * if @a ga does not have the same size as this array. * * @param __ga Array slice to get values from. */ valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a ma. Results are undefined * if @a ma does not have the same size as this array. * * @param __ma Array slice to get values from. */ valarray<_Tp>& operator=(const mask_array<_Tp>& __ma); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a ia. Results are undefined * if @a ia does not have the same size as this array. * * @param __ia Array slice to get values from. */ valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia); #if __cplusplus >= 201103L /** * @brief Assign elements to an initializer_list. * * Assign elements of array to values in @a __l. Results are undefined * if @a __l does not have the same size as this array. * * @param __l initializer_list to get values from. */ valarray& operator=(initializer_list<_Tp> __l); #endif template valarray<_Tp>& operator= (const _Expr<_Dom, _Tp>&); // _lib.valarray.access_ element access: /** * Return a reference to the i'th array element. * * @param __i Index of element to return. * @return Reference to the i'th element. */ _Tp& operator[](size_t __i); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 389. Const overload of valarray::operator[] returns by value. const _Tp& operator[](size_t) const; // _lib.valarray.sub_ subset operations: /** * @brief Return an array subset. * * Returns a new valarray containing the elements of the array * indicated by the slice argument. The new valarray has the same size * as the input slice. @see slice. * * @param __s The source slice. * @return New valarray containing elements in @a __s. */ _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const; /** * @brief Return a reference to an array subset. * * Returns a new valarray containing the elements of the array * indicated by the slice argument. The new valarray has the same size * as the input slice. @see slice. * * @param __s The source slice. * @return New valarray containing elements in @a __s. */ slice_array<_Tp> operator[](slice __s); /** * @brief Return an array subset. * * Returns a slice_array referencing the elements of the array * indicated by the slice argument. @see gslice. * * @param __s The source slice. * @return Slice_array referencing elements indicated by @a __s. */ _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const; /** * @brief Return a reference to an array subset. * * Returns a new valarray containing the elements of the array * indicated by the gslice argument. The new valarray has * the same size as the input gslice. @see gslice. * * @param __s The source gslice. * @return New valarray containing elements in @a __s. */ gslice_array<_Tp> operator[](const gslice& __s); /** * @brief Return an array subset. * * Returns a new valarray containing the elements of the array * indicated by the argument. The input is a valarray of bool which * represents a bitmask indicating which elements should be copied into * the new valarray. Each element of the array is added to the return * valarray if the corresponding element of the argument is true. * * @param __m The valarray bitmask. * @return New valarray containing elements indicated by @a __m. */ valarray<_Tp> operator[](const valarray& __m) const; /** * @brief Return a reference to an array subset. * * Returns a new mask_array referencing the elements of the array * indicated by the argument. The input is a valarray of bool which * represents a bitmask indicating which elements are part of the * subset. Elements of the array are part of the subset if the * corresponding element of the argument is true. * * @param __m The valarray bitmask. * @return New valarray containing elements indicated by @a __m. */ mask_array<_Tp> operator[](const valarray& __m); /** * @brief Return an array subset. * * Returns a new valarray containing the elements of the array * indicated by the argument. The elements in the argument are * interpreted as the indices of elements of this valarray to copy to * the return valarray. * * @param __i The valarray element index list. * @return New valarray containing elements in @a __s. */ _Expr<_IClos<_ValArray, _Tp>, _Tp> operator[](const valarray& __i) const; /** * @brief Return a reference to an array subset. * * Returns an indirect_array referencing the elements of the array * indicated by the argument. The elements in the argument are * interpreted as the indices of elements of this valarray to include * in the subset. The returned indirect_array refers to these * elements. * * @param __i The valarray element index list. * @return Indirect_array referencing elements in @a __i. */ indirect_array<_Tp> operator[](const valarray& __i); // _lib.valarray.unary_ unary operators: /// Return a new valarray by applying unary + to each element. typename _UnaryOp<__unary_plus>::_Rt operator+() const; /// Return a new valarray by applying unary - to each element. typename _UnaryOp<__negate>::_Rt operator-() const; /// Return a new valarray by applying unary ~ to each element. typename _UnaryOp<__bitwise_not>::_Rt operator~() const; /// Return a new valarray by applying unary ! to each element. typename _UnaryOp<__logical_not>::_Rt operator!() const; // _lib.valarray.cassign_ computed assignment: /// Multiply each element of array by @a t. valarray<_Tp>& operator*=(const _Tp&); /// Divide each element of array by @a t. valarray<_Tp>& operator/=(const _Tp&); /// Set each element e of array to e % @a t. valarray<_Tp>& operator%=(const _Tp&); /// Add @a t to each element of array. valarray<_Tp>& operator+=(const _Tp&); /// Subtract @a t to each element of array. valarray<_Tp>& operator-=(const _Tp&); /// Set each element e of array to e ^ @a t. valarray<_Tp>& operator^=(const _Tp&); /// Set each element e of array to e & @a t. valarray<_Tp>& operator&=(const _Tp&); /// Set each element e of array to e | @a t. valarray<_Tp>& operator|=(const _Tp&); /// Left shift each element e of array by @a t bits. valarray<_Tp>& operator<<=(const _Tp&); /// Right shift each element e of array by @a t bits. valarray<_Tp>& operator>>=(const _Tp&); /// Multiply elements of array by corresponding elements of @a v. valarray<_Tp>& operator*=(const valarray<_Tp>&); /// Divide elements of array by corresponding elements of @a v. valarray<_Tp>& operator/=(const valarray<_Tp>&); /// Modulo elements of array by corresponding elements of @a v. valarray<_Tp>& operator%=(const valarray<_Tp>&); /// Add corresponding elements of @a v to elements of array. valarray<_Tp>& operator+=(const valarray<_Tp>&); /// Subtract corresponding elements of @a v from elements of array. valarray<_Tp>& operator-=(const valarray<_Tp>&); /// Logical xor corresponding elements of @a v with elements of array. valarray<_Tp>& operator^=(const valarray<_Tp>&); /// Logical or corresponding elements of @a v with elements of array. valarray<_Tp>& operator|=(const valarray<_Tp>&); /// Logical and corresponding elements of @a v with elements of array. valarray<_Tp>& operator&=(const valarray<_Tp>&); /// Left shift elements of array by corresponding elements of @a v. valarray<_Tp>& operator<<=(const valarray<_Tp>&); /// Right shift elements of array by corresponding elements of @a v. valarray<_Tp>& operator>>=(const valarray<_Tp>&); template valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&); // _lib.valarray.members_ member functions: #if __cplusplus >= 201103L /// Swap. void swap(valarray<_Tp>& __v) noexcept; #endif /// Return the number of elements in array. size_t size() const; /** * @brief Return the sum of all elements in the array. * * Accumulates the sum of all elements into a Tp using +=. The order * of adding the elements is unspecified. */ _Tp sum() const; /// Return the minimum element using operator<(). _Tp min() const; /// Return the maximum element using operator<(). _Tp max() const; /** * @brief Return a shifted array. * * A new valarray is constructed as a copy of this array with elements * in shifted positions. For an element with index i, the new position * is i - n. The new valarray has the same size as the current one. * New elements without a value are set to 0. Elements whose new * position is outside the bounds of the array are discarded. * * Positive arguments shift toward index 0, discarding elements [0, n). * Negative arguments discard elements from the top of the array. * * @param __n Number of element positions to shift. * @return New valarray with elements in shifted positions. */ valarray<_Tp> shift (int __n) const; /** * @brief Return a rotated array. * * A new valarray is constructed as a copy of this array with elements * in shifted positions. For an element with index i, the new position * is (i - n) % size(). The new valarray has the same size as the * current one. Elements that are shifted beyond the array bounds are * shifted into the other end of the array. No elements are lost. * * Positive arguments shift toward index 0, wrapping around the top. * Negative arguments shift towards the top, wrapping around to 0. * * @param __n Number of element positions to rotate. * @return New valarray with elements in shifted positions. */ valarray<_Tp> cshift(int __n) const; /** * @brief Apply a function to the array. * * Returns a new valarray with elements assigned to the result of * applying func to the corresponding element of this array. The new * array has the same size as this one. * * @param func Function of Tp returning Tp to apply. * @return New valarray with transformed elements. */ _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const; /** * @brief Apply a function to the array. * * Returns a new valarray with elements assigned to the result of * applying func to the corresponding element of this array. The new * array has the same size as this one. * * @param func Function of const Tp& returning Tp to apply. * @return New valarray with transformed elements. */ _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const; /** * @brief Resize array. * * Resize this array to @a size and set all elements to @a c. All * references and iterators are invalidated. * * @param __size New array size. * @param __c New value for all elements. */ void resize(size_t __size, _Tp __c = _Tp()); private: size_t _M_size; _Tp* __restrict__ _M_data; friend class _Array<_Tp>; }; #if __cpp_deduction_guides >= 201606 template valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>; #endif template inline const _Tp& valarray<_Tp>::operator[](size_t __i) const { __glibcxx_requires_subscript(__i); return _M_data[__i]; } template inline _Tp& valarray<_Tp>::operator[](size_t __i) { __glibcxx_requires_subscript(__i); return _M_data[__i]; } // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ template inline valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {} template inline valarray<_Tp>::valarray(size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) { std::__valarray_default_construct(_M_data, _M_data + __n); } template inline valarray<_Tp>::valarray(const _Tp& __t, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } template inline valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) { __glibcxx_assert(__p != 0 || __n == 0); std::__valarray_copy_construct(__p, __p + __n, _M_data); } template inline valarray<_Tp>::valarray(const valarray<_Tp>& __v) : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); } #if __cplusplus >= 201103L template inline valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept : _M_size(__v._M_size), _M_data(__v._M_data) { __v._M_size = 0; __v._M_data = 0; } #endif template inline valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) { std::__valarray_copy_construct (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); } template inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) : _M_size(__ga._M_index.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) { std::__valarray_copy_construct (__ga._M_array, _Array(__ga._M_index), _Array<_Tp>(_M_data), _M_size); } template inline valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) { std::__valarray_copy_construct (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); } template inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) { std::__valarray_copy_construct (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); } #if __cplusplus >= 201103L template inline valarray<_Tp>::valarray(initializer_list<_Tp> __l) : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size())) { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); } #endif template template inline valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } template inline valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } template inline valarray<_Tp>& valarray<_Tp>::operator=(const valarray<_Tp>& __v) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 630. arrays of valarray. if (_M_size == __v._M_size) std::__valarray_copy(__v._M_data, _M_size, _M_data); else { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __v._M_size; _M_data = __valarray_get_storage<_Tp>(_M_size); std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); } return *this; } #if __cplusplus >= 201103L template inline valarray<_Tp>& valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __v._M_size; _M_data = __v._M_data; __v._M_size = 0; __v._M_data = 0; return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(initializer_list<_Tp> __l) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 630. arrays of valarray. if (_M_size == __l.size()) std::__valarray_copy(__l.begin(), __l.size(), _M_data); else { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __l.size(); _M_data = __valarray_get_storage<_Tp>(_M_size); std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size, _M_data); } return *this; } #endif template inline valarray<_Tp>& valarray<_Tp>::operator=(const _Tp& __t) { std::__valarray_fill(_M_data, _M_size, __t); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) { __glibcxx_assert(_M_size == __sa._M_sz); std::__valarray_copy(__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) { __glibcxx_assert(_M_size == __ga._M_index.size()); std::__valarray_copy(__ga._M_array, _Array(__ga._M_index), _Array<_Tp>(_M_data), _M_size); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) { __glibcxx_assert(_M_size == __ma._M_sz); std::__valarray_copy(__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) { __glibcxx_assert(_M_size == __ia._M_sz); std::__valarray_copy(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); return *this; } template template inline valarray<_Tp>& valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 630. arrays of valarray. if (_M_size == __e.size()) std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); else { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __e.size(); _M_data = __valarray_get_storage<_Tp>(_M_size); std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } return *this; } template inline _Expr<_SClos<_ValArray,_Tp>, _Tp> valarray<_Tp>::operator[](slice __s) const { typedef _SClos<_ValArray,_Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); } template inline slice_array<_Tp> valarray<_Tp>::operator[](slice __s) { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); } template inline _Expr<_GClos<_ValArray,_Tp>, _Tp> valarray<_Tp>::operator[](const gslice& __gs) const { typedef _GClos<_ValArray,_Tp> _Closure; return _Expr<_Closure, _Tp> (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); } template inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __gs) { return gslice_array<_Tp> (_Array<_Tp>(_M_data), __gs._M_index->_M_index); } template inline valarray<_Tp> valarray<_Tp>::operator[](const valarray& __m) const { size_t __s = 0; size_t __e = __m.size(); for (size_t __i=0; __i<__e; ++__i) if (__m[__i]) ++__s; return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array (__m))); } template inline mask_array<_Tp> valarray<_Tp>::operator[](const valarray& __m) { size_t __s = 0; size_t __e = __m.size(); for (size_t __i=0; __i<__e; ++__i) if (__m[__i]) ++__s; return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array(__m)); } template inline _Expr<_IClos<_ValArray,_Tp>, _Tp> valarray<_Tp>::operator[](const valarray& __i) const { typedef _IClos<_ValArray,_Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure(*this, __i)); } template inline indirect_array<_Tp> valarray<_Tp>::operator[](const valarray& __i) { return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), _Array(__i)); } #if __cplusplus >= 201103L template inline void valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept { std::swap(_M_size, __v._M_size); std::swap(_M_data, __v._M_data); } #endif template inline size_t valarray<_Tp>::size() const { return _M_size; } template inline _Tp valarray<_Tp>::sum() const { __glibcxx_assert(_M_size > 0); return std::__valarray_sum(_M_data, _M_data + _M_size); } template inline valarray<_Tp> valarray<_Tp>::shift(int __n) const { valarray<_Tp> __ret; if (_M_size == 0) return __ret; _Tp* __restrict__ __tmp_M_data = std::__valarray_get_storage<_Tp>(_M_size); if (__n == 0) std::__valarray_copy_construct(_M_data, _M_data + _M_size, __tmp_M_data); else if (__n > 0) // shift left { if (size_t(__n) > _M_size) __n = int(_M_size); std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, __tmp_M_data); std::__valarray_default_construct(__tmp_M_data + _M_size - __n, __tmp_M_data + _M_size); } else // shift right { if (-size_t(__n) > _M_size) __n = -int(_M_size); std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, __tmp_M_data - __n); std::__valarray_default_construct(__tmp_M_data, __tmp_M_data - __n); } __ret._M_size = _M_size; __ret._M_data = __tmp_M_data; return __ret; } template inline valarray<_Tp> valarray<_Tp>::cshift(int __n) const { valarray<_Tp> __ret; if (_M_size == 0) return __ret; _Tp* __restrict__ __tmp_M_data = std::__valarray_get_storage<_Tp>(_M_size); if (__n == 0) std::__valarray_copy_construct(_M_data, _M_data + _M_size, __tmp_M_data); else if (__n > 0) // cshift left { if (size_t(__n) > _M_size) __n = int(__n % _M_size); std::__valarray_copy_construct(_M_data, _M_data + __n, __tmp_M_data + _M_size - __n); std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, __tmp_M_data); } else // cshift right { if (-size_t(__n) > _M_size) __n = -int(-size_t(__n) % _M_size); std::__valarray_copy_construct(_M_data + _M_size + __n, _M_data + _M_size, __tmp_M_data); std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, __tmp_M_data - __n); } __ret._M_size = _M_size; __ret._M_data = __tmp_M_data; return __ret; } template inline void valarray<_Tp>::resize(size_t __n, _Tp __c) { // This complication is so to make valarray > work // even though it is not required by the standard. Nobody should // be saying valarray > anyway. See the specs. std::__valarray_destroy_elements(_M_data, _M_data + _M_size); if (_M_size != __n) { std::__valarray_release_memory(_M_data); _M_size = __n; _M_data = __valarray_get_storage<_Tp>(__n); } std::__valarray_fill_construct(_M_data, _M_data + __n, __c); } template inline _Tp valarray<_Tp>::min() const { __glibcxx_assert(_M_size > 0); return *std::min_element(_M_data, _M_data + _M_size); } template inline _Tp valarray<_Tp>::max() const { __glibcxx_assert(_M_size > 0); return *std::max_element(_M_data, _M_data + _M_size); } template inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> valarray<_Tp>::apply(_Tp func(_Tp)) const { typedef _ValFunClos<_ValArray, _Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure(*this, func)); } template inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> valarray<_Tp>::apply(_Tp func(const _Tp &)) const { typedef _RefFunClos<_ValArray, _Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure(*this, func)); } #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ template \ inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ valarray<_Tp>::operator _Op() const \ { \ typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(*this)); \ } _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) #undef _DEFINE_VALARRAY_UNARY_OPERATOR #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ template \ inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const _Tp &__t) \ { \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ return *this; \ } \ \ template \ inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ { \ __glibcxx_assert(_M_size == __v._M_size); \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ _Array<_Tp>(__v._M_data)); \ return *this; \ } _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ template template \ inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \ { \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ return *this; \ } _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ template \ inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \ typename __fun<_Name, _Tp>::result_type> \ operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ { \ __glibcxx_assert(__v.size() == __w.size()); \ typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ } \ \ template \ inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \ typename __fun<_Name, _Tp>::result_type> \ operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \ { \ typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ } \ \ template \ inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \ typename __fun<_Name, _Tp>::result_type> \ operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \ { \ typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \ } _DEFINE_BINARY_OPERATOR(+, __plus) _DEFINE_BINARY_OPERATOR(-, __minus) _DEFINE_BINARY_OPERATOR(*, __multiplies) _DEFINE_BINARY_OPERATOR(/, __divides) _DEFINE_BINARY_OPERATOR(%, __modulus) _DEFINE_BINARY_OPERATOR(^, __bitwise_xor) _DEFINE_BINARY_OPERATOR(&, __bitwise_and) _DEFINE_BINARY_OPERATOR(|, __bitwise_or) _DEFINE_BINARY_OPERATOR(<<, __shift_left) _DEFINE_BINARY_OPERATOR(>>, __shift_right) _DEFINE_BINARY_OPERATOR(&&, __logical_and) _DEFINE_BINARY_OPERATOR(||, __logical_or) _DEFINE_BINARY_OPERATOR(==, __equal_to) _DEFINE_BINARY_OPERATOR(!=, __not_equal_to) _DEFINE_BINARY_OPERATOR(<, __less) _DEFINE_BINARY_OPERATOR(>, __greater) _DEFINE_BINARY_OPERATOR(<=, __less_equal) _DEFINE_BINARY_OPERATOR(>=, __greater_equal) #undef _DEFINE_BINARY_OPERATOR #if __cplusplus >= 201103L /** * @brief Return an iterator pointing to the first element of * the valarray. * @param __va valarray. */ template inline _Tp* begin(valarray<_Tp>& __va) { return std::__addressof(__va[0]); } /** * @brief Return an iterator pointing to the first element of * the const valarray. * @param __va valarray. */ template inline const _Tp* begin(const valarray<_Tp>& __va) { return std::__addressof(__va[0]); } /** * @brief Return an iterator pointing to one past the last element of * the valarray. * @param __va valarray. */ template inline _Tp* end(valarray<_Tp>& __va) { return std::__addressof(__va[0]) + __va.size(); } /** * @brief Return an iterator pointing to one past the last element of * the const valarray. * @param __va valarray. */ template inline const _Tp* end(const valarray<_Tp>& __va) { return std::__addressof(__va[0]) + __va.size(); } #endif // C++11 // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GLIBCXX_VALARRAY */ PKgd1]XV 8/profile/setnu[// Profiling set/multiset implementation -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/set * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_SET #define _GLIBCXX_PROFILE_SET 1 #include #include #include #endif PKgd1]TDD8/profile/unordered_mapnu[// Profiling unordered_map/unordered_multimap implementation -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/unordered_map * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP #define _GLIBCXX_PROFILE_UNORDERED_MAP 1 #if __cplusplus < 201103L # include #else # include #include #include #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::unordered_map wrapper with performance instrumentation. template, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator > > class unordered_map : public _GLIBCXX_STD_BASE, public _Unordered_profile, true> { typedef typename _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::mapped_type mapped_type; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_map() = default; explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } 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()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_map(const unordered_map&) = default; unordered_map(const _Base& __x) : _Base(__x) { } unordered_map(unordered_map&&) = default; explicit unordered_map(const allocator_type& __a) : _Base(__a) { } unordered_map(const unordered_map& __umap, const allocator_type& __a) : _Base(__umap, __a) { } unordered_map(unordered_map&& __umap, const allocator_type& __a) : _Base(std::move(__umap._M_base()), __a) { } unordered_map(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_map(size_type __n, const allocator_type& __a) : unordered_map(__n, hasher(), key_equal(), __a) { } unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__n, __hf, key_equal(), __a) { } template unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__first, __last, __n, __hf, key_equal(), __a) { } unordered_map(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_map(__l, __n, hasher(), key_equal(), __a) { } unordered_map(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__l, __n, __hf, key_equal(), __a) { } unordered_map& operator=(const unordered_map&) = default; unordered_map& operator=(unordered_map&&) = default; unordered_map& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template std::pair emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } std::pair insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } template::value>::type> std::pair insert(_Pair&& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(std::forward<_Pair>(__obj)); this->_M_profile_resize(__old_size); return __res; } template::value>::type> iterator insert(const_iterator __iter, _Pair&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } // operator[] mapped_type& operator[](const _Key& __k) { size_type __old_size = _Base::bucket_count(); mapped_type& __res = _M_base()[__k]; this->_M_profile_resize(__old_size); return __res; } mapped_type& operator[](_Key&& __k) { size_type __old_size = _Base::bucket_count(); mapped_type& __res = _M_base()[std::move(__k)]; this->_M_profile_resize(__old_size); return __res; } void swap(unordered_map& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x._M_base()); this->_M_swap(__x); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__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 static_cast(__x) == __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 == __y); } #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE /// Class std::unordered_multimap wrapper with performance instrumentation. template, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator > > class unordered_multimap : public _GLIBCXX_STD_BASE, public _Unordered_profile, false> { typedef typename _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_multimap() = default; explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } 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()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_multimap(const unordered_multimap&) = default; unordered_multimap(const _Base& __x) : _Base(__x) { } unordered_multimap(unordered_multimap&&) = default; explicit unordered_multimap(const allocator_type& __a) : _Base(__a) { } unordered_multimap(const unordered_multimap& __ummap, const allocator_type& __a) : _Base(__ummap._M_base(), __a) { } unordered_multimap(unordered_multimap&& __ummap, const allocator_type& __a) : _Base(std::move(__ummap._M_base()), __a) { } unordered_multimap(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_multimap(size_type __n, const allocator_type& __a) : unordered_multimap(__n, hasher(), key_equal(), __a) { } unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__n, __hf, key_equal(), __a) { } template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multimap(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_multimap(__l, __n, hasher(), key_equal(), __a) { } unordered_multimap(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } unordered_multimap& operator=(const unordered_multimap&) = default; unordered_multimap& operator=(unordered_multimap&&) = default; unordered_multimap& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template iterator emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } iterator insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } template::value>::type> iterator insert(_Pair&& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(std::forward<_Pair>(__obj)); this->_M_profile_resize(__old_size); return __res; } template::value>::type> iterator insert(const_iterator __iter, _Pair&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } void swap(unordered_multimap& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x._M_base()); this->_M_swap(__x); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return static_cast(__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 == __y); } } // namespace __profile } // namespace std #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #endif // C++11 #endif PKgd1]ݏKK8/profile/multimap.hnu[// Profiling multimap implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/multimap.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MULTIMAP_H #define _GLIBCXX_PROFILE_MULTIMAP_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::multimap wrapper with performance instrumentation. template, typename _Allocator = std::allocator > > class multimap : public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Tp mapped_type; typedef std::pair value_type; typedef _Compare key_compare; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, multimap> iterator; typedef __iterator_tracker<_Base_const_iterator, multimap> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.1.1 construct/copy/destroy: #if __cplusplus < 201103L multimap() : _Base() { } multimap(const multimap& __x) : _Base(__x) { } ~multimap() { } #else multimap() = default; multimap(const multimap&) = default; multimap(multimap&&) = default; ~multimap() = default; #endif explicit multimap(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif multimap(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } #if __cplusplus >= 201103L multimap(initializer_list __l, const _Compare& __c = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__l, __c, __a) { } explicit multimap(const _Allocator& __a) : _Base(__a) { } multimap(const multimap& __x, const _Allocator& __a) : _Base(__x, __a) { } multimap(multimap&& __x, const _Allocator& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } multimap(initializer_list __l, const _Allocator& __a) : _Base(__l, __a) { } template multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __a) : _Base(__first, __last, __a) { } #endif multimap(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L multimap& operator=(const multimap& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else multimap& operator=(const multimap&) = default; multimap& operator=(multimap&&) = default; multimap& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif // modifiers: #if __cplusplus >= 201103L template iterator emplace(_Args&&... __args) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::emplace(std::forward<_Args>(__args)...), this); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif iterator insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(__x), this); } #if __cplusplus >= 201103L template::value>::type> iterator insert(_Pair&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(std::forward<_Pair>(__x)), this); } #endif #if __cplusplus >= 201103L void insert(std::initializer_list __list) { insert(__list.begin(), __list.end()); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const value_type& __x) #else insert(iterator __pos, const value_type& __x) #endif { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L template::value>::type> iterator insert(const_iterator __pos, _Pair&& __x) { size_type size_before = this->size(); auto __res = _Base::insert(__pos.base(), std::forward<_Pair>(__x)); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif template void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } iterator erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } else return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void swap(multimap& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { std::swap(this->_M_map2umap_info, __x._M_map2umap_info); _Base::swap(__x); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } // 23.3.1.3 multimap operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); template friend bool operator<(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); }; template inline bool operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template inline void swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif PKgd1](8/profile/impl/profiler_container_size.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_container_size.h * @brief Diagnostics for container sizes. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H #define _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H 1 #include #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A container size instrumentation line in the object table. */ class __container_size_info : public __object_info_base { public: __container_size_info(__stack_t __stack) : __object_info_base(__stack), _M_init(0), _M_max(0), _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0), _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0) { } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n", _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total, _M_item_min, _M_item_max, _M_item_total); } float __magnitude() const { return static_cast(_M_cost); } std::string __advice() const { std::stringstream __message; if (_M_init < _M_item_max) __message << "change initial container size from " << _M_init << " to " << _M_item_max; return __message.str(); } void __init(std::size_t __num) { _M_init = __num; _M_max = __num; } void __merge(const __container_size_info& __o) { __object_info_base::__merge(__o); _M_init = std::max(_M_init, __o._M_init); _M_max = std::max(_M_max, __o._M_max); _M_item_max = std::max(_M_item_max, __o._M_item_max); _M_min = std::min(_M_min, __o._M_min); _M_item_min = std::min(_M_item_min, __o._M_item_min); _M_total += __o._M_total; _M_item_total += __o._M_item_total; _M_count += __o._M_count; _M_cost += __o._M_cost; _M_resize += __o._M_resize; } // Call if a container is destructed or cleaned. void __destruct(std::size_t __num, std::size_t __inum) { _M_max = std::max(_M_max, __num); _M_item_max = std::max(_M_item_max, __inum); if (_M_min == 0) { _M_min = __num; _M_item_min = __inum; } else { _M_min = std::min(_M_min, __num); _M_item_min = std::min(_M_item_min, __inum); } _M_total += __num; _M_item_total += __inum; _M_count += 1; } // Estimate the cost of resize/rehash. float __resize_cost(std::size_t __from, std::size_t) { return __from; } // Call if container is resized. void __resize(std::size_t __from, std::size_t __to) { _M_cost += this->__resize_cost(__from, __to); _M_resize += 1; _M_max = std::max(_M_max, __to); } private: std::size_t _M_init; std::size_t _M_max; // range of # buckets std::size_t _M_min; std::size_t _M_total; std::size_t _M_item_min; // range of # items std::size_t _M_item_max; std::size_t _M_item_total; std::size_t _M_count; std::size_t _M_resize; std::size_t _M_cost; }; /** @brief A container size instrumentation line in the stack table. */ class __container_size_stack_info : public __container_size_info { public: __container_size_stack_info(const __container_size_info& __o) : __container_size_info(__o) { } }; /** @brief Container size instrumentation trace producer. */ class __trace_container_size : public __trace_base<__container_size_info, __container_size_stack_info> { public: ~__trace_container_size() { } __trace_container_size() : __trace_base<__container_size_info, __container_size_stack_info>() { }; // Insert a new node at construct with object, callstack and initial size. __container_size_info* __insert(__stack_t __stack, std::size_t __num) { __container_size_info* __ret = __add_object(__stack); if (__ret) __ret->__init(__num); return __ret; } // Call at destruction/clean to set container final size. void __destruct(__container_size_info* __obj_info, std::size_t __num, std::size_t __inum) { __obj_info->__destruct(__num, __inum); __retire_object(__obj_info); } }; } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */ PKgd1]ZDʩ.8/profile/impl/profiler_map_to_unordered_map.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_map_to_unordered_map.h * @brief Diagnostics for map to unordered_map. */ // Written by Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H #define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { inline int __log2(std::size_t __size) { for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0; -- __bit_count) if ((2 << __bit_count) & __size) return __bit_count; return 0; } inline float __map_insert_cost(std::size_t __size) { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value * static_cast(__log2(__size))); } inline float __map_erase_cost(std::size_t __size) { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value * static_cast(__log2(__size))); } inline float __map_find_cost(std::size_t __size) { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value * static_cast(__log2(__size))); } /** @brief A map-to-unordered_map instrumentation line in the object table. */ class __map2umap_info : public __object_info_base { public: __map2umap_info(__stack_t __stack) : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0) { } void __merge(const __map2umap_info& __o) { __object_info_base::__merge(__o); _M_insert += __o._M_insert; _M_erase += __o._M_erase; _M_find += __o._M_find; _M_iterate += __o._M_iterate; _M_umap_cost += __o._M_umap_cost; _M_map_cost += __o._M_map_cost; } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n", _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost, _M_umap_cost); } float __magnitude() const { return _M_map_cost - _M_umap_cost; } std::string __advice() const { return "prefer an unordered container"; } void __record_insert(std::size_t __size, std::size_t __count) { ++_M_insert; if (__count) { _M_map_cost += __count * __map_insert_cost(__size); _M_umap_cost += (__count * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value); } } void __record_erase(std::size_t __size, std::size_t __count) { ++_M_erase; if (__count) { _M_map_cost += __count * __map_erase_cost(__size); _M_umap_cost += (__count * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value); } } void __record_find(std::size_t __size) { ++_M_find; _M_map_cost += __map_find_cost(__size); _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value; } void __record_iterate(int __count) { __gnu_cxx::__atomic_add(&_M_iterate, __count); } void __set_iterate_costs() { _M_umap_cost += (_M_iterate * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value); _M_map_cost += (_M_iterate * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value); } private: std::size_t _M_insert; std::size_t _M_erase; std::size_t _M_find; mutable _Atomic_word _M_iterate; float _M_umap_cost; float _M_map_cost; }; /** @brief A map-to-unordered_map instrumentation line in the stack table. */ class __map2umap_stack_info : public __map2umap_info { public: __map2umap_stack_info(const __map2umap_info& __o) : __map2umap_info(__o) { } }; /** @brief Map-to-unordered_map instrumentation producer. */ class __trace_map2umap : public __trace_base<__map2umap_info, __map2umap_stack_info> { public: __trace_map2umap() : __trace_base<__map2umap_info, __map2umap_stack_info>() { __id = "ordered-to-unordered"; } // Call at destruction/clean to set container final size. void __destruct(__map2umap_info* __obj_info) { __obj_info->__set_iterate_costs(); __retire_object(__obj_info); } }; inline void __trace_map_to_unordered_map_init() { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); } inline void __trace_map_to_unordered_map_free() { delete _GLIBCXX_PROFILE_DATA(_S_map2umap); } inline void __trace_map_to_unordered_map_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); } inline __map2umap_info* __trace_map_to_unordered_map_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack()); } inline void __trace_map_to_unordered_map_insert(__map2umap_info* __info, std::size_t __size, std::size_t __count) { if (!__info) return; __info->__record_insert(__size, __count); } inline void __trace_map_to_unordered_map_erase(__map2umap_info* __info, std::size_t __size, std::size_t __count) { if (!__info) return; __info->__record_erase(__size, __count); } inline void __trace_map_to_unordered_map_find(__map2umap_info* __info, std::size_t __size) { if (!__info) return; __info->__record_find(__size); } inline void __trace_map_to_unordered_map_iterate(__map2umap_info* __info, int) { if (!__info) return; // We only collect if an iteration took place no matter in what side. __info->__record_iterate(1); } inline void __trace_map_to_unordered_map_invalidate(__map2umap_info* __info) { if (!__info) return; __info->__set_invalid(); } inline void __trace_map_to_unordered_map_destruct(__map2umap_info* __info) { if (!__info) return; _GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */ PKgd1]m8/profile/impl/profiler_node.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_node.h * @brief Data structures to represent a single profiling event. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_NODE_H #define _GLIBCXX_PROFILE_PROFILER_NODE_H 1 #include // FILE, fprintf #include #if defined _GLIBCXX_HAVE_EXECINFO_H #include #endif namespace __gnu_profile { typedef void* __instruction_address_t; typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt; typedef __stack_npt* __stack_t; std::size_t __stack_max_depth(); inline __stack_t __get_stack() { #if defined _GLIBCXX_HAVE_EXECINFO_H __try { std::size_t __max_depth = __stack_max_depth(); if (__max_depth == 0) return 0; __stack_npt __buffer(__max_depth); int __depth = backtrace(&__buffer[0], __max_depth); return new(std::nothrow) __stack_npt(__buffer.begin(), __buffer.begin() + __depth); } __catch(...) { return 0; } #else return 0; #endif } inline std::size_t __size(__stack_t __stack) { if (!__stack) return 0; else return __stack->size(); } // XXX inline void __write(FILE* __f, __stack_t __stack) { if (!__stack) return; __stack_npt::const_iterator __it; for (__it = __stack->begin(); __it != __stack->end(); ++__it) std::fprintf(__f, "%p ", *__it); } /** @brief Hash function for summary trace using call stack as index. */ class __stack_hash { public: std::size_t operator()(__stack_t __s) const { if (!__s) return 0; std::size_t __index = 0; __stack_npt::const_iterator __it; for (__it = __s->begin(); __it != __s->end(); ++__it) __index += reinterpret_cast(*__it); return __index; } bool operator() (__stack_t __stack1, __stack_t __stack2) const { if (!__stack1 && !__stack2) return true; if (!__stack1 || !__stack2) return false; if (__stack1->size() != __stack2->size()) return false; std::size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type); return __builtin_memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0; } }; /** @brief Base class for a line in the object table. */ class __object_info_base { public: __object_info_base(__stack_t __stack) : _M_stack(__stack), _M_valid(true) { } bool __is_valid() const { return _M_valid; } void __set_invalid() { _M_valid = false; } void __merge(const __object_info_base& __o) { _M_valid &= __o._M_valid; } __stack_t __stack() const { return _M_stack; } protected: __stack_t _M_stack; bool _M_valid; }; } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */ PKgd1]d;(8/profile/impl/profiler_list_to_vector.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_list_to_vector.h * @brief diagnostics for list to vector. */ // Written by Changhee Jung. #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 1 #include #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A list-to-vector instrumentation line in the object table. */ class __list2vector_info : public __object_info_base { public: __list2vector_info(__stack_t __stack) : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_max_size(0) { } void __merge(const __list2vector_info& __o) { __object_info_base::__merge(__o); _M_shift_count += __o._M_shift_count; _M_iterate += __o._M_iterate; _M_vector_cost += __o._M_vector_cost; _M_list_cost += __o._M_list_cost; _M_resize += __o._M_resize; _M_max_size = std::max( _M_max_size, __o._M_max_size); } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); } float __magnitude() const { return _M_list_cost - _M_vector_cost; } std::string __advice() const { std::stringstream __sstream; __sstream << "change std::list to std::vector and its initial size from 0 to " << _M_max_size; return __sstream.str(); } std::size_t __shift_count() { return _M_shift_count; } std::size_t __iterate() { return _M_iterate; } float __list_cost() { return _M_list_cost; } std::size_t __resize() { return _M_resize; } void __set_list_cost(float __lc) { _M_list_cost = __lc; } void __set_vector_cost(float __vc) { _M_vector_cost = __vc; } void __opr_insert(std::size_t __shift, std::size_t __size) { _M_shift_count += __shift; _M_max_size = std::max(_M_max_size, __size); } void __opr_iterate(int __num) { __gnu_cxx::__atomic_add(&_M_iterate, __num); } void __resize(std::size_t __from, std::size_t) { _M_resize += __from; } private: std::size_t _M_shift_count; mutable _Atomic_word _M_iterate; std::size_t _M_resize; float _M_list_cost; float _M_vector_cost; std::size_t _M_max_size; }; class __list2vector_stack_info : public __list2vector_info { public: __list2vector_stack_info(const __list2vector_info& __o) : __list2vector_info(__o) {} }; class __trace_list_to_vector : public __trace_base<__list2vector_info, __list2vector_stack_info> { public: __trace_list_to_vector() : __trace_base<__list2vector_info, __list2vector_stack_info>() { __id = "list-to-vector"; } ~__trace_list_to_vector() { } // Call at destruction/clean to set container final size. void __destruct(__list2vector_info* __obj_info) { float __vc = __vector_cost(__obj_info->__shift_count(), __obj_info->__iterate()); float __lc = __list_cost(__obj_info->__shift_count(), __obj_info->__iterate()); __obj_info->__set_vector_cost(__vc); __obj_info->__set_list_cost(__lc); __retire_object(__obj_info); } // Collect cost of operations. float __vector_cost(std::size_t __shift, std::size_t __iterate) { // The resulting vector will use a 'reserve' method. return (__shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value); } float __list_cost(std::size_t __shift, std::size_t __iterate) { return (__shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value); } }; inline void __trace_list_to_vector_init() { _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector(); } inline void __trace_list_to_vector_free() { delete _GLIBCXX_PROFILE_DATA(_S_list_to_vector); } inline void __trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_vector), __f, __warnings); } inline __list2vector_info* __trace_list_to_vector_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_list_to_vector) ->__add_object(__get_stack()); } inline void __trace_list_to_vector_insert(__list2vector_info* __obj_info, std::size_t __shift, std::size_t __size) { if (!__obj_info) return; __obj_info->__opr_insert(__shift, __size); } inline void __trace_list_to_vector_iterate(__list2vector_info* __obj_info, int) { if (!__obj_info) return; // We only collect if an iteration took place no matter in what side. __obj_info->__opr_iterate(1); } inline void __trace_list_to_vector_invalid_operator(__list2vector_info* __obj_info) { if (!__obj_info) return; __obj_info->__set_invalid(); } inline void __trace_list_to_vector_resize(__list2vector_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_list_to_vector_destruct(__list2vector_info* __obj_info) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj_info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */ PKgd1]$ (8/profile/impl/profiler_hashtable_size.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_hashtable_size.h * @brief Collection of hashtable size traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H #define _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" #include "profile/impl/profiler_state.h" #include "profile/impl/profiler_container_size.h" namespace __gnu_profile { /** @brief Hashtable size instrumentation trace producer. */ class __trace_hashtable_size : public __trace_container_size { public: __trace_hashtable_size() : __trace_container_size() { __id = "hashtable-size"; } }; inline void __trace_hashtable_size_init() { _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size(); } inline void __trace_hashtable_size_free() { delete _GLIBCXX_PROFILE_DATA(_S_hashtable_size); } inline void __trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_hashtable_size), __f, __warnings); } inline __container_size_info* __trace_hashtable_size_construct(std::size_t __num) { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_hashtable_size)-> __insert(__get_stack(), __num); } inline void __trace_hashtable_size_resize(__container_size_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_hashtable_size_destruct(__container_size_info* __obj_info, std::size_t __num, std::size_t __inum) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_hashtable_size)-> __destruct(__obj_info, __num, __inum); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H */ PKgd1]_;e e 8/profile/impl/profiler_algos.hnu[// -*- C++ -*- // // Copyright (C) 2010-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_algos.h * @brief Algorithms used by the profile extension. * * This file is needed to avoid including \ or \. * Including those files would result in recursive includes. * These implementations are oversimplified. In general, efficiency may be * sacrificed to minimize maintenance overhead. */ #ifndef _GLIBCXX_PROFILE_PROFILER_ALGOS_H #define _GLIBCXX_PROFILE_PROFILER_ALGOS_H 1 namespace __gnu_profile { /* Helper for __top_n. Insert in sorted vector, but not beyond Nth elem. */ template void __insert_top_n(_Container& __output, const typename _Container::value_type& __value, typename _Container::size_type __n) { typename _Container::iterator __it = __output.begin(); typename _Container::size_type __count = 0; // Skip up to N - 1 elements larger than VALUE. // XXX: Could do binary search for random iterators. while (true) { if (__count >= __n) // VALUE is not in top N. return; if (__it == __output.end()) break; if (*__it < __value) break; ++__it; ++__count; } __output.insert(__it, __value); } /* Copy the top N elements in INPUT, sorted in reverse order, to OUTPUT. */ template void __top_n(const _Container& __input, _Container& __output, typename _Container::size_type __n) { __output.clear(); typename _Container::const_iterator __it; for (__it = __input.begin(); __it != __input.end(); ++__it) __insert_top_n(__output, *__it, __n); } /* Simplified clone of std::for_each. */ template _Function __for_each(_InputIterator __first, _InputIterator __last, _Function __f) { for (; __first != __last; ++__first) __f(*__first); return __f; } /* Simplified clone of std::remove. */ template _ForwardIterator __remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { if(__first == __last) return __first; _ForwardIterator __result = __first; ++__first; for(; __first != __last; ++__first) if(!(*__first == __value)) { *__result = *__first; ++__result; } return __result; } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_ALGOS_H */ PKgd1]+^8/profile/impl/profiler_state.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_state.h * @brief Global profiler state. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_STATE_H #define _GLIBCXX_PROFILE_PROFILER_STATE_H 1 namespace __gnu_profile { enum __state_type { __ON, __OFF, __INVALID }; _GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID); inline bool __turn(__state_type __s) { __state_type inv(__INVALID); return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state), &inv, __s, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); } inline bool __turn_on() { return __turn(__ON); } inline bool __turn_off() { return __turn(__OFF); } inline bool __is_on() { return _GLIBCXX_PROFILE_DATA(__state) == __ON; } inline bool __is_off() { return _GLIBCXX_PROFILE_DATA(__state) == __OFF; } inline bool __is_invalid() { return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; } } // end namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */ PKgd1]<`(8/profile/impl/profiler_vector_to_list.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_vector_to_list.h * @brief diagnostics for vector to list. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H #define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A vector-to-list instrumentation line in the object table. */ class __vector2list_info : public __object_info_base { public: __vector2list_info(__stack_t __stack) : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), _M_vector_cost(0) { } void __merge(const __vector2list_info& __o) { __object_info_base::__merge(__o); _M_shift_count += __o._M_shift_count; _M_iterate += __o._M_iterate; _M_vector_cost += __o._M_vector_cost; _M_list_cost += __o._M_list_cost; _M_resize += __o._M_resize; } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); } float __magnitude() const { return _M_vector_cost - _M_list_cost; } std::string __advice() const { return "change std::vector to std::list"; } std::size_t __shift_count() { return _M_shift_count; } std::size_t __iterate() { return _M_iterate; } float __list_cost() { return _M_list_cost; } std::size_t __resize() { return _M_resize; } void __set_list_cost(float __lc) { _M_list_cost = __lc; } void __set_vector_cost(float __vc) { _M_vector_cost = __vc; } void __opr_insert(std::size_t __pos, std::size_t __num) { _M_shift_count += __num - __pos; } void __opr_iterate(int __num) { __gnu_cxx::__atomic_add(&_M_iterate, __num); } void __resize(std::size_t __from, std::size_t) { _M_resize += __from; } private: std::size_t _M_shift_count; mutable _Atomic_word _M_iterate; std::size_t _M_resize; float _M_list_cost; float _M_vector_cost; }; /** @brief A vector-to-list instrumentation line in the stack table. */ class __vector2list_stack_info : public __vector2list_info { public: __vector2list_stack_info(const __vector2list_info& __o) : __vector2list_info(__o) { } }; /** @brief Vector-to-list instrumentation producer. */ class __trace_vector_to_list : public __trace_base<__vector2list_info, __vector2list_stack_info> { public: __trace_vector_to_list() : __trace_base<__vector2list_info, __vector2list_stack_info>() { __id = "vector-to-list"; } ~__trace_vector_to_list() { } // Call at destruction/clean to set container final size. void __destruct(__vector2list_info* __obj_info) { float __vc = __vector_cost(__obj_info->__shift_count(), __obj_info->__iterate(), __obj_info->__resize()); float __lc = __list_cost(__obj_info->__shift_count(), __obj_info->__iterate(), __obj_info->__resize()); __obj_info->__set_vector_cost(__vc); __obj_info->__set_list_cost(__lc); __retire_object(__obj_info); } // Collect cost of operations. float __vector_cost(std::size_t __shift, std::size_t __iterate, std::size_t __resize) { return (__shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value + __resize * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value); } float __list_cost(std::size_t __shift, std::size_t __iterate, std::size_t __resize) { return (__shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value + __resize * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value); } }; inline void __trace_vector_to_list_init() { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); } inline void __trace_vector_to_list_free() { delete _GLIBCXX_PROFILE_DATA(_S_vector_to_list); } inline void __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_to_list), __f, __warnings); } inline __vector2list_info* __trace_vector_to_list_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_vector_to_list) ->__add_object(__get_stack()); } inline void __trace_vector_to_list_insert(__vector2list_info* __obj_info, std::size_t __pos, std::size_t __num) { if (!__obj_info) return; __obj_info->__opr_insert(__pos, __num); } inline void __trace_vector_to_list_iterate(__vector2list_info* __obj_info, int) { if (!__obj_info) return; // We only collect if an iteration took place no matter in what side. __obj_info->__opr_iterate(1); } inline void __trace_vector_to_list_invalid_operator(__vector2list_info* __obj_info) { if (!__obj_info) return; __obj_info->__set_invalid(); } inline void __trace_vector_to_list_resize(__vector2list_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_vector_to_list_destruct(__vector2list_info* __obj_info) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj_info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */ PKgd1]fڸ<<#8/profile/impl/profiler_hash_func.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_hash_func.h * @brief Data structures to represent profiling traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H #define _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A hash performance instrumentation line in the object table. */ class __hashfunc_info : public __object_info_base { public: __hashfunc_info(__stack_t __stack) : __object_info_base(__stack), _M_longest_chain(0), _M_accesses(0), _M_hops(0) { } void __merge(const __hashfunc_info& __o) { __object_info_base::__merge(__o); _M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain); _M_accesses += __o._M_accesses; _M_hops += __o._M_hops; } void __destruct(std::size_t __chain, std::size_t __accesses, std::size_t __hops) { _M_longest_chain = std::max(_M_longest_chain, __chain); _M_accesses += __accesses; _M_hops += __hops; } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); } float __magnitude() const { return static_cast(_M_hops); } std::string __advice() const { return "change hash function"; } private: std::size_t _M_longest_chain; std::size_t _M_accesses; std::size_t _M_hops; }; /** @brief A hash performance instrumentation line in the stack table. */ class __hashfunc_stack_info : public __hashfunc_info { public: __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) { } }; /** @brief Hash performance instrumentation producer. */ class __trace_hash_func : public __trace_base<__hashfunc_info, __hashfunc_stack_info> { public: __trace_hash_func() : __trace_base<__hashfunc_info, __hashfunc_stack_info>() { __id = "hash-distr"; } ~__trace_hash_func() {} // Call at destruction/clean to set container final size. void __destruct(__hashfunc_info* __obj_info, std::size_t __chain, std::size_t __accesses, std::size_t __hops) { if (!__obj_info) return; __obj_info->__destruct(__chain, __accesses, __hops); __retire_object(__obj_info); } }; inline void __trace_hash_func_init() { _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); } inline void __trace_hash_func_free() { delete _GLIBCXX_PROFILE_DATA(_S_hash_func); } inline void __trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_hash_func), __f, __warnings); } inline __hashfunc_info* __trace_hash_func_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_hash_func)->__add_object(__get_stack()); } inline void __trace_hash_func_destruct(__hashfunc_info* __obj_info, std::size_t __chain, std::size_t __accesses, std::size_t __hops) { _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj_info, __chain, __accesses, __hops); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */ PKgd1]UQQ8/profile/impl/profiler_trace.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_trace.h * @brief Data structures to represent profiling traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_TRACE_H #define _GLIBCXX_PROFILE_PROFILER_TRACE_H 1 #include // fopen, fclose, fprintf, FILE #include #include // atof, atoi, strtol, getenv, atexit, abort #if __cplusplus >= 201103L #include #define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_C::unordered_map #else #include #define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map #endif #include #include #include #include #include #include "profile/impl/profiler_algos.h" #include "profile/impl/profiler_state.h" #include "profile/impl/profiler_node.h" namespace __gnu_profile { /** @brief Internal environment. Values can be set one of two ways: 1. In config file "var = value". The default config file path is libstdcxx-profile.conf. 2. By setting process environment variables. For instance, in a Bash shell you can set the unit cost of iterating through a map like this: export __map_iterate_cost_factor=5.0. If a value is set both in the input file and through an environment variable, the environment value takes precedence. */ typedef _GLIBCXX_IMPL_UNORDERED_MAP __env_t; _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env); /** @brief Master lock. */ _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_mutex); /** @brief Representation of a warning. */ struct __warning_data { float __magnitude; __stack_t __context; const char* __warning_id; std::string __warning_message; __warning_data() : __magnitude(0.0), __context(0), __warning_id(0) { } __warning_data(float __m, __stack_t __c, const char* __id, const std::string& __msg) : __magnitude(__m), __context(__c), __warning_id(__id), __warning_message(__msg) { } bool operator<(const __warning_data& __other) const { return __magnitude < __other.__magnitude; } }; typedef std::_GLIBCXX_STD_C::vector<__warning_data> __warning_vector_t; // Defined in profiler_.h. class __trace_hash_func; class __trace_hashtable_size; class __trace_map2umap; class __trace_vector_size; class __trace_vector_to_list; class __trace_list_to_slist; class __trace_list_to_vector; void __trace_vector_size_init(); void __trace_hashtable_size_init(); void __trace_hash_func_init(); void __trace_vector_to_list_init(); void __trace_list_to_slist_init(); void __trace_list_to_vector_init(); void __trace_map_to_unordered_map_init(); void __trace_vector_size_report(FILE*, __warning_vector_t&); void __trace_hashtable_size_report(FILE*, __warning_vector_t&); void __trace_hash_func_report(FILE*, __warning_vector_t&); void __trace_vector_to_list_report(FILE*, __warning_vector_t&); void __trace_list_to_slist_report(FILE*, __warning_vector_t&); void __trace_list_to_vector_report(FILE*, __warning_vector_t&); void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&); void __trace_vector_size_free(); void __trace_hashtable_size_free(); void __trace_hash_func_free(); void __trace_vector_to_list_free(); void __trace_list_to_slist_free(); void __trace_list_to_vector_free(); void __trace_map_to_unordered_map_free(); struct __cost_factor { const char* __env_var; float __value; }; typedef std::_GLIBCXX_STD_C::vector<__cost_factor*> __cost_factor_vector; _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor, {"__vector_shift_cost_factor", 1.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor, {"__vector_iterate_cost_factor", 1.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor, {"__vector_resize_cost_factor", 1.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor, {"__list_shift_cost_factor", 0.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor, {"__list_iterate_cost_factor", 10.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor, {"__list_resize_cost_factor", 0.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor, {"__map_insert_cost_factor", 1.5}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor, {"__map_erase_cost_factor", 1.5}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor, {"__map_find_cost_factor", 1}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor, {"__map_iterate_cost_factor", 2.3}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor, {"__umap_insert_cost_factor", 12.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor, {"__umap_erase_cost_factor", 12.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor, {"__umap_find_cost_factor", 10.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor, {"__umap_iterate_cost_factor", 1.7}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0); _GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name, _GLIBCXX_PROFILE_TRACE_PATH_ROOT); _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_warn_count, _GLIBCXX_PROFILE_MAX_WARN_COUNT); _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_stack_depth, _GLIBCXX_PROFILE_MAX_STACK_DEPTH); _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_mem, _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC); inline std::size_t __stack_max_depth() { return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth); } inline std::size_t __max_mem() { return _GLIBCXX_PROFILE_DATA(_S_max_mem); } /** @brief Base class for all trace producers. */ template class __trace_base { public: // Do not pick the initial size too large, as we don't know which // diagnostics are more active. __trace_base() : __objects_byte_size(0), __stack_table(10000), __stack_table_byte_size(0), __id(0) { } ~__trace_base() { for (typename __stack_table_t::iterator __it = __stack_table.begin(); __it != __stack_table.end(); ++__it) delete __it->first; } __object_info* __add_object(__stack_t __stack); void __retire_object(__object_info* __info); void __write(FILE* __f); void __collect_warnings(__warning_vector_t& __warnings); void __free(); private: __gnu_cxx::__mutex __trace_mutex; typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash, __stack_hash> __stack_table_t; std::size_t __objects_byte_size; __stack_table_t __stack_table; std::size_t __stack_table_byte_size; protected: const char* __id; }; template __object_info* __trace_base<__object_info, __stack_info>:: __add_object(__stack_t __stack) { // If we have no backtrace information no need to collect data. if (!__stack) return 0; __gnu_cxx::__scoped_lock __lock(this->__trace_mutex); if (__max_mem() != 0 && __objects_byte_size >= __max_mem()) { delete __stack; return 0; } __object_info* __ret = new(std::nothrow) __object_info(__stack); if (!__ret) { delete __stack; return 0; } __objects_byte_size += sizeof(__object_info); return __ret; } template void __trace_base<__object_info, __stack_info>:: __retire_object(__object_info* __obj_info) { if (!__obj_info) return; __gnu_cxx::__scoped_lock __lock(this->__trace_mutex); const __object_info& __info = *__obj_info; __stack_t __stack = __info.__stack(); typename __stack_table_t::iterator __stack_it = __stack_table.find(__stack); if (__stack_it == __stack_table.end()) { // First occurrence of this call context. if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) { __stack_table_byte_size += (sizeof(__instruction_address_t) * __size(__stack) + sizeof(__stack) + sizeof(__stack_info)); __stack_table.insert(make_pair(__stack, __stack_info(__info))); } else delete __stack; } else { // Merge object info into info summary for this call context. __stack_it->second.__merge(__info); delete __stack; } delete __obj_info; __objects_byte_size -= sizeof(__object_info); } template void __trace_base<__object_info, __stack_info>:: __write(FILE* __f) { for (typename __stack_table_t::iterator __it = __stack_table.begin(); __it != __stack_table.end(); ++__it) if (__it->second.__is_valid()) { std::fprintf(__f, __id); std::fprintf(__f, "|"); __gnu_profile::__write(__f, __it->first); std::fprintf(__f, "|"); __it->second.__write(__f); } } template void __trace_base<__object_info, __stack_info>:: __collect_warnings(__warning_vector_t& __warnings) { for (typename __stack_table_t::iterator __it = __stack_table.begin(); __it != __stack_table.end(); ++__it) __warnings.push_back(__warning_data(__it->second.__magnitude(), __it->first, __id, __it->second.__advice())); } template inline void __trace_report(__trace_base<__object_info, __stack_info>* __cont, FILE* __f, __warning_vector_t& __warnings) { if (__cont) { __cont->__collect_warnings(__warnings); __cont->__write(__f); } } inline std::size_t __env_to_size_t(const char* __env_var, std::size_t __default_value) { char* __env_value = std::getenv(__env_var); if (__env_value) { errno = 0; long __converted_value = std::strtol(__env_value, 0, 10); if (errno || __converted_value < 0) { std::fprintf(stderr, "Bad value for environment variable '%s'.\n", __env_var); std::abort(); } else return static_cast(__converted_value); } else return __default_value; } inline void __set_max_stack_trace_depth() { _GLIBCXX_PROFILE_DATA(_S_max_stack_depth) = __env_to_size_t(_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR, _GLIBCXX_PROFILE_DATA(_S_max_stack_depth)); } inline void __set_max_mem() { _GLIBCXX_PROFILE_DATA(_S_max_mem) = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, _GLIBCXX_PROFILE_DATA(_S_max_mem)); } inline int __log_magnitude(float __f) { const float __log_base = 10.0; int __result = 0; int __sign = 1; if (__f < 0) { __f = -__f; __sign = -1; } while (__f > __log_base) { ++__result; __f /= 10.0; } return __sign * __result; } inline FILE* __open_output_file(const char* __extension) { // The path is made of _S_trace_file_name + "." + extension. std::size_t __root_len = __builtin_strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name)); std::size_t __ext_len = __builtin_strlen(__extension); char* __file_name = new char[__root_len + 1 + __ext_len + 1]; __builtin_memcpy(__file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name), __root_len); *(__file_name + __root_len) = '.'; __builtin_memcpy(__file_name + __root_len + 1, __extension, __ext_len + 1); FILE* __out_file = std::fopen(__file_name, "w"); if (!__out_file) { std::fprintf(stderr, "Could not open trace file '%s'.\n", __file_name); std::abort(); } delete[] __file_name; return __out_file; } struct __warn { FILE* __file; __warn(FILE* __f) { __file = __f; } void operator()(const __warning_data& __info) { std::fprintf(__file, __info.__warning_id); std::fprintf(__file, ": improvement = %d", __log_magnitude(__info.__magnitude)); std::fprintf(__file, ": call stack = "); __gnu_profile::__write(__file, __info.__context); std::fprintf(__file, ": advice = %s\n", __info.__warning_message.c_str()); } }; /** @brief Final report method, registered with @b atexit. * * This can also be called directly by user code, including signal handlers. * It is protected against deadlocks by the reentrance guard in profiler.h. * However, when called from a signal handler that triggers while within * __gnu_profile (under the guarded zone), no output will be produced. */ inline void __report() { __gnu_cxx::__scoped_lock __lock(_GLIBCXX_PROFILE_DATA(__global_mutex)); __warning_vector_t __warnings, __top_warnings; FILE* __raw_file = __open_output_file("raw"); __trace_vector_size_report(__raw_file, __warnings); __trace_hashtable_size_report(__raw_file, __warnings); __trace_hash_func_report(__raw_file, __warnings); __trace_vector_to_list_report(__raw_file, __warnings); __trace_list_to_slist_report(__raw_file, __warnings); __trace_list_to_vector_report(__raw_file, __warnings); __trace_map_to_unordered_map_report(__raw_file, __warnings); std::fclose(__raw_file); // Sort data by magnitude, keeping just top N. std::size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count), __warnings.size()); __top_n(__warnings, __top_warnings, __cutoff); FILE* __warn_file = __open_output_file("txt"); __for_each(__top_warnings.begin(), __top_warnings.end(), __warn(__warn_file)); std::fclose(__warn_file); } inline void __report_and_free() { __report(); __trace_map_to_unordered_map_free(); __trace_list_to_vector_free(); __trace_list_to_slist_free(); __trace_vector_to_list_free(); __trace_hash_func_free(); __trace_hashtable_size_free(); __trace_vector_size_free(); delete _GLIBCXX_PROFILE_DATA(__cost_factors); } inline void __set_trace_path() { char* __env_trace_file_name = std::getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR); if (__env_trace_file_name) _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name; // Make sure early that we can create the trace file. std::fclose(__open_output_file("txt")); } inline void __set_max_warn_count() { char* __env_max_warn_count_str = std::getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR); if (__env_max_warn_count_str) _GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast(std::atoi(__env_max_warn_count_str)); } inline void __read_cost_factors() { std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name)); __conf_file_name += ".conf"; std::ifstream __conf_file(__conf_file_name.c_str()); if (__conf_file.is_open()) { std::string __line; while (std::getline(__conf_file, __line)) { std::string::size_type __i = __line.find_first_not_of(" \t\n\v"); if (__line.length() <= 0 || __line[__i] == '#') // Skip empty lines or comments. continue; } // Trim. __line.erase(__remove(__line.begin(), __line.end(), ' '), __line.end()); std::string::size_type __pos = __line.find("="); std::string __factor_name = __line.substr(0, __pos); std::string::size_type __end = __line.find_first_of(";\n"); std::string __factor_value = __line.substr(__pos + 1, __end - __pos); _GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value; } } struct __cost_factor_writer { FILE* __file; __cost_factor_writer(FILE* __f) : __file(__f) { } void operator() (const __cost_factor* __factor) { std::fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value); } }; inline void __write_cost_factors() { FILE* __file = __open_output_file("conf.out"); __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(), _GLIBCXX_PROFILE_DATA(__cost_factors)->end(), __cost_factor_writer(__file)); std::fclose(__file); } struct __cost_factor_setter { void operator()(__cost_factor* __factor) { // Look it up in the process environment first. const char* __env_value = std::getenv(__factor->__env_var); if (!__env_value) { // Look it up in the config file. __env_t::iterator __it = _GLIBCXX_PROFILE_DATA(__env).find(__factor->__env_var); if (__it != _GLIBCXX_PROFILE_DATA(__env).end()) __env_value = __it->second.c_str(); } if (__env_value) __factor->__value = std::atof(__env_value); } }; inline void __set_cost_factors() { __cost_factor_vector* __factors = new __cost_factor_vector; _GLIBCXX_PROFILE_DATA(__cost_factors) = __factors; __factors->push_back(&_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_find_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor)); __for_each(__factors->begin(), __factors->end(), __cost_factor_setter()); } inline void __profcxx_init_unconditional() { __gnu_cxx::__scoped_lock __lock(_GLIBCXX_PROFILE_DATA(__global_mutex)); if (__is_invalid()) { __set_max_warn_count(); if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) __turn_off(); else { __set_max_stack_trace_depth(); __set_max_mem(); __set_trace_path(); __read_cost_factors(); __set_cost_factors(); __write_cost_factors(); __trace_vector_size_init(); __trace_hashtable_size_init(); __trace_hash_func_init(); __trace_vector_to_list_init(); __trace_list_to_slist_init(); __trace_list_to_vector_init(); __trace_map_to_unordered_map_init(); std::atexit(__report_and_free); __turn_on(); } } } /** @brief This function must be called by each instrumentation point. * * The common path is inlined fully. */ inline bool __profcxx_init() { if (__is_invalid()) __profcxx_init_unconditional(); return __is_on(); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */ PKgd1]@GVV'8/profile/impl/profiler_list_to_slist.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_list_to_slist.h * @brief Diagnostics for list to slist. */ // Written by Changhee Jung. #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { class __list2slist_info : public __object_info_base { public: __list2slist_info(__stack_t __stack) : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { } // XXX: the magnitude should be multiplied with a constant factor F, // where F is 1 when the malloc size class of list nodes is different // from the malloc size class of slist nodes. When they fall into the same // class, the only slist benefit is from having to set fewer links, so // the factor F should be much smaller, closer to 0 than to 1. // This could be implemented by passing the size classes in the config // file. For now, we always assume F to be 1. float __magnitude() const { if (!_M_rewind) return _M_operations; else return 0; } void __write(FILE* __f) const { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); } std::string __advice() const { return "change std::list to std::forward_list"; } void __opr_rewind() { _M_rewind = true; __set_invalid(); } void __record_operation() { ++_M_operations; } bool __has_rewind() { return _M_rewind; } private: bool _M_rewind; std::size_t _M_operations; }; class __list2slist_stack_info : public __list2slist_info { public: __list2slist_stack_info(const __list2slist_info& __o) : __list2slist_info(__o) { } }; class __trace_list_to_slist : public __trace_base<__list2slist_info, __list2slist_stack_info> { public: ~__trace_list_to_slist() { } __trace_list_to_slist() : __trace_base<__list2slist_info, __list2slist_stack_info>() { __id = "list-to-slist"; } void __destruct(__list2slist_info* __obj_info) { __retire_object(__obj_info); } }; inline void __trace_list_to_slist_init() { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); } inline void __trace_list_to_slist_free() { delete _GLIBCXX_PROFILE_DATA(_S_list_to_slist); } inline void __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_slist), __f, __warnings); } inline __list2slist_info* __trace_list_to_slist_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__add_object(__get_stack()); } inline void __trace_list_to_slist_rewind(__list2slist_info* __obj_info) { if (!__obj_info) return; __obj_info->__opr_rewind(); } inline void __trace_list_to_slist_operation(__list2slist_info* __obj_info) { if (!__obj_info) return; __obj_info->__record_operation(); } inline void __trace_list_to_slist_destruct(__list2slist_info* __obj_info) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj_info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */ PKgd1]2yd6d68/profile/impl/profiler.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler.h * @brief Interface of the profiling runtime library. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_H #define _GLIBCXX_PROFILE_PROFILER_H 1 #include // Mechanism to define data with inline linkage. #define _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__type, __name) \ inline __type& \ __get_##__name() \ { \ static __type __name; \ return __name; \ } #define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \ inline __type& __get_##__name() { \ static __type __name(__initial_value); \ return __name; \ } #define _GLIBCXX_PROFILE_DATA(__name) \ __get_##__name() namespace __gnu_profile { /** @brief Reentrance guard. * * Mechanism to protect all __gnu_profile operations against recursion, * multithreaded and exception reentrance. */ struct __reentrance_guard { static bool __get_in() { if (__inside() == true) return false; else { __inside() = true; return true; } } static bool& __inside() { static __thread bool _S_inside(false); return _S_inside; } __reentrance_guard() { } ~__reentrance_guard() { __inside() = false; } }; // Forward declarations of implementation functions. // Don't use any __gnu_profile:: in user code. // Instead, use the __profcxx... macros, which offer guarded access. class __container_size_info; class __hashfunc_info; class __map2umap_info; class __vector2list_info; class __list2slist_info; class __list2vector_info; bool __turn_on(); bool __turn_off(); bool __is_invalid(); bool __is_on(); bool __is_off(); void __report(); __container_size_info* __trace_hashtable_size_construct(std::size_t); void __trace_hashtable_size_resize(__container_size_info*, std::size_t, std::size_t); void __trace_hashtable_size_destruct(__container_size_info*, std::size_t, std::size_t); __hashfunc_info* __trace_hash_func_construct(); void __trace_hash_func_destruct(__hashfunc_info*, std::size_t, std::size_t, std::size_t); __container_size_info* __trace_vector_size_construct(std::size_t); void __trace_vector_size_resize(__container_size_info*, std::size_t, std::size_t); void __trace_vector_size_destruct(__container_size_info*, std::size_t, std::size_t); __vector2list_info* __trace_vector_to_list_construct(); void __trace_vector_to_list_insert(__vector2list_info*, std::size_t, std::size_t); void __trace_vector_to_list_iterate(__vector2list_info*, int); void __trace_vector_to_list_invalid_operator(__vector2list_info*); void __trace_vector_to_list_resize(__vector2list_info*, std::size_t, std::size_t); void __trace_vector_to_list_destruct(__vector2list_info*); __list2slist_info* __trace_list_to_slist_construct(); void __trace_list_to_slist_rewind(__list2slist_info*); void __trace_list_to_slist_operation(__list2slist_info*); void __trace_list_to_slist_destruct(__list2slist_info*); __list2vector_info* __trace_list_to_vector_construct(); void __trace_list_to_vector_insert(__list2vector_info*, std::size_t, std::size_t); void __trace_list_to_vector_iterate(__list2vector_info*, int); void __trace_list_to_vector_invalid_operator(__list2vector_info*); void __trace_list_to_vector_resize(__list2vector_info*, std::size_t, std::size_t); void __trace_list_to_vector_destruct(__list2vector_info*); __map2umap_info* __trace_map_to_unordered_map_construct(); void __trace_map_to_unordered_map_invalidate(__map2umap_info*); void __trace_map_to_unordered_map_insert(__map2umap_info*, std::size_t, std::size_t); void __trace_map_to_unordered_map_erase(__map2umap_info*, std::size_t, std::size_t); void __trace_map_to_unordered_map_iterate(__map2umap_info*, std::size_t); void __trace_map_to_unordered_map_find(__map2umap_info*, std::size_t); void __trace_map_to_unordered_map_destruct(__map2umap_info*); } // namespace __gnu_profile // Master switch turns on all diagnostics that are not explicitly turned off. #ifdef _GLIBCXX_PROFILE #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL #endif #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE #endif #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL #endif #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE #endif #ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH #define _GLIBCXX_PROFILE_INEFFICIENT_HASH #endif #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST #define _GLIBCXX_PROFILE_VECTOR_TO_LIST #endif #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST #define _GLIBCXX_PROFILE_LIST_TO_SLIST #endif #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR #define _GLIBCXX_PROFILE_LIST_TO_VECTOR #endif #ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP #endif #endif // Expose global management routines to user code. #ifdef _GLIBCXX_PROFILE #define __profcxx_report() __gnu_profile::__report() #define __profcxx_turn_on() __gnu_profile::__turn_on() #define __profcxx_turn_off() __gnu_profile::__turn_off() #define __profcxx_is_invalid() __gnu_profile::__is_invalid() #define __profcxx_is_on() __gnu_profile::__is_on() #define __profcxx_is_off() __gnu_profile::__is_off() #else #define __profcxx_report() #define __profcxx_turn_on() #define __profcxx_turn_off() #define __profcxx_is_invalid() #define __profcxx_is_on() #define __profcxx_is_off() #endif // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE. #if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \ || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE)) #define __profcxx_hashtable_size_construct(__x...) \ __gnu_profile::__trace_hashtable_size_construct(__x) #define __profcxx_hashtable_size_resize(__x...) \ __gnu_profile::__trace_hashtable_size_resize(__x) #define __profcxx_hashtable_size_destruct(__x...) \ __gnu_profile::__trace_hashtable_size_destruct(__x) #else #define __profcxx_hashtable_size_construct(__x...) 0 #define __profcxx_hashtable_size_resize(__x...) #define __profcxx_hashtable_size_destruct(__x...) #endif // Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE. #if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \ || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE)) #define __profcxx_vector_size_construct(__x...) \ __gnu_profile::__trace_vector_size_construct(__x) #define __profcxx_vector_size_resize(__x...) \ __gnu_profile::__trace_vector_size_resize(__x) #define __profcxx_vector_size_destruct(__x...) \ __gnu_profile::__trace_vector_size_destruct(__x) #else #define __profcxx_vector_size_construct(__x...) 0 #define __profcxx_vector_size_resize(__x...) #define __profcxx_vector_size_destruct(__x...) #endif // Turn on/off instrumentation for INEFFICIENT_HASH. #if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH) #define __profcxx_hash_func_construct(__x...) \ __gnu_profile::__trace_hash_func_construct(__x) #define __profcxx_hash_func_destruct(__x...) \ __gnu_profile::__trace_hash_func_destruct(__x) #else #define __profcxx_hash_func_construct(__x...) 0 #define __profcxx_hash_func_destruct(__x...) #endif // Turn on/off instrumentation for VECTOR_TO_LIST. #if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST) #define __profcxx_vector2list_construct(__x...) \ __gnu_profile::__trace_vector_to_list_construct(__x) #define __profcxx_vector2list_insert(__x...) \ __gnu_profile::__trace_vector_to_list_insert(__x) #define __profcxx_vector2list_iterate(__x...) \ __gnu_profile::__trace_vector_to_list_iterate(__x) #define __profcxx_vector2list_invalid_operator(__x...) \ __gnu_profile::__trace_vector_to_list_invalid_operator(__x) #define __profcxx_vector2list_resize(__x...) \ __gnu_profile::__trace_vector_to_list_resize(__x) #define __profcxx_vector2list_destruct(__x...) \ __gnu_profile::__trace_vector_to_list_destruct(__x) #else #define __profcxx_vector2list_construct(__x...) 0 #define __profcxx_vector2list_insert(__x...) #define __profcxx_vector2list_iterate(__x...) #define __profcxx_vector2list_invalid_operator(__x...) #define __profcxx_vector2list_resize(__x...) #define __profcxx_vector2list_destruct(__x...) #endif // Turn on/off instrumentation for LIST_TO_VECTOR. #if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR) #define __profcxx_list2vector_construct(__x...) \ __gnu_profile::__trace_list_to_vector_construct(__x) #define __profcxx_list2vector_insert(__x...) \ __gnu_profile::__trace_list_to_vector_insert(__x) #define __profcxx_list2vector_iterate(__x...) \ __gnu_profile::__trace_list_to_vector_iterate(__x) #define __profcxx_list2vector_invalid_operator(__x...) \ __gnu_profile::__trace_list_to_vector_invalid_operator(__x) #define __profcxx_list2vector_destruct(__x...) \ __gnu_profile::__trace_list_to_vector_destruct(__x) #else #define __profcxx_list2vector_construct(__x...) 0 #define __profcxx_list2vector_insert(__x...) #define __profcxx_list2vector_iterate(__x...) #define __profcxx_list2vector_invalid_operator(__x...) #define __profcxx_list2vector_destruct(__x...) #endif // Turn on/off instrumentation for LIST_TO_SLIST. #if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST) #define __profcxx_list2slist_construct(__x...) \ __gnu_profile::__trace_list_to_slist_construct(__x) #define __profcxx_list2slist_rewind(__x...) \ __gnu_profile::__trace_list_to_slist_rewind(__x) #define __profcxx_list2slist_operation(__x...) \ __gnu_profile::__trace_list_to_slist_operation(__x) #define __profcxx_list2slist_destruct(__x...) \ __gnu_profile::__trace_list_to_slist_destruct(__x) #else #define __profcxx_list2slist_construct(__x...) 0 #define __profcxx_list2slist_rewind(__x...) #define __profcxx_list2slist_operation(__x...) #define __profcxx_list2slist_destruct(__x...) #endif // Turn on/off instrumentation for MAP_TO_UNORDERED_MAP. #if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP) #define __profcxx_map2umap_construct(__x...) \ __gnu_profile::__trace_map_to_unordered_map_construct(__x) #define __profcxx_map2umap_insert(__x...) \ __gnu_profile::__trace_map_to_unordered_map_insert(__x) #define __profcxx_map2umap_erase(__x...) \ __gnu_profile::__trace_map_to_unordered_map_erase(__x) #define __profcxx_map2umap_iterate(__x...) \ __gnu_profile::__trace_map_to_unordered_map_iterate(__x) #define __profcxx_map2umap_invalidate(__x...) \ __gnu_profile::__trace_map_to_unordered_map_invalidate(__x) #define __profcxx_map2umap_find(__x...) \ __gnu_profile::__trace_map_to_unordered_map_find(__x) #define __profcxx_map2umap_destruct(__x...) \ __gnu_profile::__trace_map_to_unordered_map_destruct(__x) #else #define __profcxx_map2umap_construct(__x...) 0 #define __profcxx_map2umap_insert(__x...) #define __profcxx_map2umap_erase(__x...) #define __profcxx_map2umap_iterate(__x...) #define __profcxx_map2umap_invalidate(__x...) #define __profcxx_map2umap_find(__x...) #define __profcxx_map2umap_destruct(__x...) #endif // Set default values for compile-time customizable variables. #ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile" #endif #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR #define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT" #endif #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \ "_GLIBCXX_PROFILE_MAX_WARN_COUNT" #endif #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10 #endif #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32 #endif #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \ "_GLIBCXX_PROFILE_MAX_STACK_DEPTH" #endif #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC (1 << 28) #endif #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \ "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC" #endif // Instrumentation hook implementations. #include "profile/impl/profiler_hash_func.h" #include "profile/impl/profiler_hashtable_size.h" #include "profile/impl/profiler_map_to_unordered_map.h" #include "profile/impl/profiler_vector_size.h" #include "profile/impl/profiler_vector_to_list.h" #include "profile/impl/profiler_list_to_slist.h" #include "profile/impl/profiler_list_to_vector.h" #endif // _GLIBCXX_PROFILE_PROFILER_H PKgd1], (p p %8/profile/impl/profiler_vector_size.hnu[// -*- C++ -*- // // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_vector_size.h * @brief Collection of vector size traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H #define _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" #include "profile/impl/profiler_state.h" #include "profile/impl/profiler_container_size.h" namespace __gnu_profile { /** @brief Hashtable size instrumentation trace producer. */ class __trace_vector_size : public __trace_container_size { public: __trace_vector_size() : __trace_container_size() { __id = "vector-size"; } }; inline void __trace_vector_size_init() { _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size(); } inline void __trace_vector_size_free() { delete _GLIBCXX_PROFILE_DATA(_S_vector_size); } inline void __trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_size), __f, __warnings); } inline __container_size_info* __trace_vector_size_construct(std::size_t __num) { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_vector_size)-> __insert(__get_stack(), __num); } inline void __trace_vector_size_resize(__container_size_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_vector_size_destruct(__container_size_info* __obj_info, std::size_t __num, std::size_t __inum) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_vector_size)-> __destruct(__obj_info, __num, __inum); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H */ PKgd1]wޜ##8/profile/unordered_base.hnu[// Profiling unordered containers implementation details -*- C++ -*- // Copyright (C) 2013-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/unordered_base.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_UNORDERED #define _GLIBCXX_PROFILE_UNORDERED 1 namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template struct _Bucket_index_helper; template struct _Bucket_index_helper<_UnorderedCont, _Value, true> { static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __node) { return __node->_M_hash_code % __uc.bucket_count(); } }; template struct _Bucket_index_helper<_UnorderedCont, _Value, false> { static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __node) { return __uc.bucket(__node->_M_v()); } }; template struct _Bucket_index_helper<_UnorderedCont, std::pair, false> { typedef std::pair _Value; static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __node) { return __uc.bucket(__node->_M_v().first); } }; template std::size_t __get_bucket_index(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, _Cache_hash_code>* __node) { using __bucket_index_helper = _Bucket_index_helper<_UnorderedCont, _Value, _Cache_hash_code>; return __bucket_index_helper::bucket(__uc, __node); } template struct _Equal_helper; template struct _Equal_helper<_UnorderedCont, _Value, true> { static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __lhs, const __detail::_Hash_node<_Value, true>* __rhs) { return __lhs->_M_hash_code == __rhs->_M_hash_code && __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); } }; template struct _Equal_helper<_UnorderedCont, _Value, false> { static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __lhs, const __detail::_Hash_node<_Value, false>* __rhs) { return __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); } }; template struct _Equal_helper<_UnorderedCont, std::pair, true> { typedef std::pair _Value; static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __lhs, const __detail::_Hash_node<_Value, true>* __rhs) { return __lhs->_M_hash_code == __rhs->_M_hash_code && __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); } }; template struct _Equal_helper<_UnorderedCont, std::pair, false> { typedef std::pair _Value; static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __lhs, const __detail::_Hash_node<_Value, false>* __rhs) { return __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); } }; template bool __are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, _Cache_hash_code>* __lhs, const __detail::_Hash_node<_Value, _Cache_hash_code>* __rhs) { using __equal_helper = _Equal_helper<_UnorderedCont, _Value, _Cache_hash_code>; return __equal_helper::are_equal(__uc, __lhs, __rhs); } template class _Unordered_profile { _UnorderedCont& _M_conjure() { return *(static_cast<_UnorderedCont*>(this)); } using __unique_keys = std::integral_constant; protected: _Unordered_profile() noexcept { _M_profile_construct(); } _Unordered_profile(const _Unordered_profile&) noexcept : _Unordered_profile() { } _Unordered_profile(_Unordered_profile&& __other) noexcept : _Unordered_profile() { _M_swap(__other); } ~_Unordered_profile() { _M_profile_destruct(); } _Unordered_profile& operator=(const _Unordered_profile&) noexcept { // Assignment just reset profiling. _M_profile_destruct(); _M_profile_construct(); } _Unordered_profile& operator=(_Unordered_profile&& __other) noexcept { // Take profiling of the moved instance... _M_swap(__other); // ...and then reset other instance profiling. __other._M_profile_destruct(); __other._M_profile_construct(); } void _M_profile_construct() noexcept { auto& __uc = _M_conjure(); _M_size_info = __profcxx_hashtable_size_construct(__uc.bucket_count()); _M_hashfunc_info = __profcxx_hash_func_construct(); } void _M_profile_destruct() noexcept { auto& __uc = _M_conjure(); __profcxx_hashtable_size_destruct(_M_size_info, __uc.bucket_count(), __uc.size()); _M_size_info = 0; if (!_M_hashfunc_info) return; _M_profile_destruct(__unique_keys()); _M_hashfunc_info = 0; } void _M_swap(_Unordered_profile& __other) noexcept { std::swap(_M_size_info, __other._M_size_info); std::swap(_M_hashfunc_info, __other._M_hashfunc_info); } void _M_profile_resize(std::size_t __old_size) { auto __new_size = _M_conjure().bucket_count(); if (__old_size != __new_size) __profcxx_hashtable_size_resize(_M_size_info, __old_size, __new_size); } __gnu_profile::__container_size_info* _M_size_info; __gnu_profile::__hashfunc_info* _M_hashfunc_info; private: void _M_profile_destruct(std::true_type); void _M_profile_destruct(std::false_type); }; template void _Unordered_profile<_UnorderedCont, _Unique_keys>:: _M_profile_destruct(std::true_type) { auto& __uc = _M_conjure(); std::size_t __hops = 0, __lc = 0, __chain = 0; auto __it = __uc.begin(); while (__it != __uc.end()) { auto __bkt = __get_bucket_index(__uc, __it._M_cur); auto __lit = __uc.begin(__bkt); auto __lend = __uc.end(__bkt); for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) ++__chain; if (__chain) { ++__chain; __lc = __lc > __chain ? __lc : __chain; __hops += __chain * (__chain - 1) / 2; __chain = 0; } } __profcxx_hash_func_destruct(_M_hashfunc_info, __lc, __uc.size(), __hops); } template void _Unordered_profile<_UnorderedCont, _Unique_keys>:: _M_profile_destruct(std::false_type) { auto& __uc = _M_conjure(); std::size_t __hops = 0, __lc = 0, __chain = 0, __unique_size = 0; auto __it = __uc.begin(); while (__it != __uc.end()) { auto __bkt = __get_bucket_index(__uc, __it._M_cur); auto __lit = __uc.begin(__bkt); auto __lend = __uc.end(__bkt); auto __pit = __it; ++__unique_size; for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) { if (!__are_equal(__uc, __pit._M_cur, __it._M_cur)) { ++__chain; ++__unique_size; __pit = __it; } } if (__chain) { ++__chain; __lc = __lc > __chain ? __lc : __chain; __hops += __chain * (__chain - 1) / 2; __chain = 0; } } __profcxx_hash_func_destruct(_M_hashfunc_info, __lc, __unique_size, __hops); } } // namespace __profile } // namespace std #endif PKgd1])wR%R%8/profile/iterator_tracker.hnu[// Profiling iterator implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/iterator_tracker.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_ITERATOR_TRACKER #define _GLIBCXX_PROFILE_ITERATOR_TRACKER 1 #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class __iterator_tracker { typedef __iterator_tracker _Self; // The underlying iterator _Iterator _M_current; // The underlying data structure const _Sequence* _M_ds; typedef std::iterator_traits<_Iterator> _Traits; public: typedef _Iterator _Base_iterator; typedef typename _Traits::iterator_category iterator_category; typedef typename _Traits::value_type value_type; typedef typename _Traits::difference_type difference_type; typedef typename _Traits::reference reference; typedef typename _Traits::pointer pointer; __iterator_tracker() _GLIBCXX_NOEXCEPT : _M_current(), _M_ds(0) { } __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) _GLIBCXX_NOEXCEPT : _M_current(__i), _M_ds(__seq) { } __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT : _M_current(__x._M_current), _M_ds(__x._M_ds) { } template __iterator_tracker(const __iterator_tracker<_MutableIterator, typename __gnu_cxx::__enable_if <(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } _Iterator base() const _GLIBCXX_NOEXCEPT { return _M_current; } /** * @brief Conversion to underlying non-debug iterator to allow * better interaction with non-profile containers. */ operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; } pointer operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; } __iterator_tracker& operator++() _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(); ++_M_current; return *this; } __iterator_tracker operator++(int) _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(); __iterator_tracker __tmp(*this); ++_M_current; return __tmp; } __iterator_tracker& operator--() _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(1); --_M_current; return *this; } __iterator_tracker operator--(int) _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(1); __iterator_tracker __tmp(*this); --_M_current; return __tmp; } __iterator_tracker& operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT { _M_current = __x._M_current; _M_ds = __x._M_ds; return *this; } reference operator*() const _GLIBCXX_NOEXCEPT { return *_M_current; } // ------ Random access iterator requirements ------ reference operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT { return _M_current[__n]; } __iterator_tracker& operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _M_current += __n; return *this; } __iterator_tracker operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT { __iterator_tracker __tmp(*this); __tmp += __n; return __tmp; } __iterator_tracker& operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _M_current += -__n; return *this; } __iterator_tracker operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT { __iterator_tracker __tmp(*this); __tmp -= __n; return __tmp; } const _Sequence* _M_get_sequence() const { return static_cast(_M_ds); } }; template inline bool operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template inline bool operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template inline bool operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template inline bool operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template inline bool operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template inline bool operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template inline bool operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template inline bool operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template inline bool operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template inline bool operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template inline bool operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } template inline bool operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template inline __iterator_tracker<_Iterator, _Sequence> operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type __n, const __iterator_tracker<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT { return __i + __n; } } // namespace __profile } // namespace std #endif PKgd1]b'RFF8/profile/set.hnu[// Profiling set implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/set.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_SET_H #define _GLIBCXX_PROFILE_SET_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::set wrapper with performance instrumentation. template, typename _Allocator = std::allocator<_Key> > class set : public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, set> iterator; typedef __iterator_tracker<_Base_const_iterator, set> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.3.1 construct/copy/destroy: #if __cplusplus < 201103L set() : _Base() { } set(const set& __x) : _Base(__x) { } ~set() { } #else set() = default; set(const set&) = default; set(set&&) = default; ~set() = default; #endif explicit set(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif set(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } #if __cplusplus >= 201103L set(initializer_list __l, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__l, __comp, __a) { } explicit set(const _Allocator& __a) : _Base(__a) { } set(const set& __x, const _Allocator& __a) : _Base(__x, __a) { } set(set&& __x, const _Allocator& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } set(initializer_list __l, const _Allocator& __a) : _Base(__l, __a) { } template set(_InputIterator __first, _InputIterator __last, const _Allocator& __a) : _Base(__first, __last, __a) { } #endif set(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L set& operator=(const set& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else set& operator=(const set&) = default; set& operator=(set&&) = default; set& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif void swap(set& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } // modifiers: #if __cplusplus >= 201103L template std::pair emplace(_Args&&... __args) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); auto __base_ret = _Base::emplace(std::forward<_Args>(__args)...); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif std::pair insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); std::pair<_Base_iterator, bool> __base_ret = _Base::insert(__x); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #if __cplusplus >= 201103L std::pair insert(value_type&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); std::pair<_Base_iterator, bool> __base_ret = _Base::insert(std::move(__x)); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #endif iterator insert(const_iterator __pos, const value_type& __x) { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, value_type&& __x) { return iterator(_Base::insert(__pos.base(), std::move(__x)), this); } #endif template void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L void insert(initializer_list __l) { insert(__l.begin(), __l.end()); } #endif #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif // set operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::lower_bound(__x), this); } const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); template friend bool operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); }; template inline bool operator==(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template void swap(set<_Key, _Compare, _Allocator>& __x, set<_Key, _Compare, _Allocator>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { return __x.swap(__y); } } // namespace __profile } // namespace std #endif PKgd1]%8/profile/bitsetnu[// Profiling bitset implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/bitset * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_BITSET #define _GLIBCXX_PROFILE_BITSET #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::bitset wrapper with performance instrumentation, none at the /// moment. template class bitset : public _GLIBCXX_STD_C::bitset<_Nb> { typedef _GLIBCXX_STD_C::bitset<_Nb> _Base; public: // 23.3.5.1 constructors: #if __cplusplus < 201103L bitset() : _Base() { } #else constexpr bitset() = default; #endif #if __cplusplus >= 201103L constexpr bitset(unsigned long long __val) noexcept #else bitset(unsigned long __val) #endif : _Base(__val) { } template explicit bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __pos = 0, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos)) : _Base(__str, __pos, __n) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. template bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __pos, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __n, _CharT __zero, _CharT __one = _CharT('1')) : _Base(__str, __pos, __n, __zero, __one) { } bitset(const _Base& __x) : _Base(__x) { } #if __cplusplus >= 201103L template explicit bitset(const _CharT* __str, typename std::basic_string<_CharT>::size_type __n = std::basic_string<_CharT>::npos, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) : _Base(__str, __n, __zero, __one) { } #endif // 23.3.5.2 bitset operations: bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { _M_base() &= __rhs; return *this; } bitset<_Nb>& operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { _M_base() |= __rhs; return *this; } bitset<_Nb>& operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { _M_base() ^= __rhs; return *this; } bitset<_Nb>& operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT { _M_base() <<= __pos; return *this; } bitset<_Nb>& operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT { _M_base() >>= __pos; return *this; } bitset<_Nb>& set() _GLIBCXX_NOEXCEPT { _Base::set(); return *this; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 186. bitset::set() second parameter should be bool bitset<_Nb>& set(size_t __pos, bool __val = true) { _Base::set(__pos, __val); return *this; } bitset<_Nb>& reset() _GLIBCXX_NOEXCEPT { _Base::reset(); return *this; } bitset<_Nb>& reset(size_t __pos) { _Base::reset(__pos); return *this; } bitset<_Nb> operator~() const _GLIBCXX_NOEXCEPT { return bitset(~_M_base()); } bitset<_Nb>& flip() _GLIBCXX_NOEXCEPT { _Base::flip(); return *this; } bitset<_Nb>& flip(size_t __pos) { _Base::flip(__pos); return *this; } bool operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return _M_base() == __rhs; } bool operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return _M_base() != __rhs; } bitset<_Nb> operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(_M_base() << __pos); } bitset<_Nb> operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(_M_base() >> __pos); } _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { return bitset<_Nb>(__x) &= __y; } template bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { return bitset<_Nb>(__x) |= __y; } template bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { return bitset<_Nb>(__x) ^= __y; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) { return __is >> __x._M_base(); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) { return __os << __x._M_base(); } } // namespace __profile #if __cplusplus >= 201103L // DR 1182. /// std::hash specialization for bitset. template struct hash<__profile::bitset<_Nb>> : public __hash_base> { size_t operator()(const __profile::bitset<_Nb>& __b) const noexcept { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); } }; #endif } // namespace std #endif PKgd1]>{38/profile/dequenu[// Profiling deque implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/deque * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_DEQUE #define _GLIBCXX_PROFILE_DEQUE 1 #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::deque wrapper with performance instrumentation. template > class deque : public _GLIBCXX_STD_C::deque<_Tp, _Allocator> { typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base; public: typedef typename _Base::size_type size_type; typedef typename _Base::value_type value_type; // 23.2.1.1 construct/copy/destroy: #if __cplusplus < 201103L deque() : _Base() { } deque(const deque& __x) : _Base(__x) { } ~deque() { } #else deque() = default; deque(const deque&) = default; deque(deque&&) = default; deque(const deque& __d, const _Allocator& __a) : _Base(__d, __a) { } deque(deque&& __d, const _Allocator& __a) : _Base(std::move(__d), __a) { } ~deque() = default; deque(initializer_list __l, const _Allocator& __a = _Allocator()) : _Base(__l, __a) { } #endif explicit deque(const _Allocator& __a) : _Base(__a) { } #if __cplusplus >= 201103L explicit deque(size_type __n, const _Allocator& __a = _Allocator()) : _Base(__n, __a) { } deque(size_type __n, const _Tp& __value, const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #else explicit deque(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #endif #if __cplusplus >= 201103L template> #else template #endif deque(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__first, __last, __a) { } deque(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L deque& operator=(const deque& __x) { _M_base() = __x; return *this; } #else deque& operator=(const deque&) = default; deque& operator=(deque&&) = default; deque& operator=(initializer_list __l) { _M_base() = __l; return *this; } #endif void swap(deque& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); } _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template inline bool operator==(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif PKgd1]9U3 8/profile/mapnu[// Profiling map/multimap implementation -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/map * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MAP #define _GLIBCXX_PROFILE_MAP 1 #include #include #include #endif PKgd1]kJ > >8/profile/vectornu[// Profiling vector implementation -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/vector * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_VECTOR #define _GLIBCXX_PROFILE_VECTOR 1 #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class _Vector_profile_pre { _Vector& _M_conjure() { return *static_cast<_Vector*>(this); } public: #if __cplusplus >= 201103L _Vector_profile_pre() = default; _Vector_profile_pre(const _Vector_profile_pre&) = default; _Vector_profile_pre(_Vector_profile_pre&&) = default; _Vector_profile_pre& operator=(const _Vector_profile_pre&) { _M_conjure()._M_profile_destruct(); } _Vector_profile_pre& operator=(_Vector_profile_pre&&) noexcept { _M_conjure()._M_profile_destruct(); } #endif }; template class _Vector_profile_post { _Vector& _M_conjure() { return *static_cast<_Vector*>(this); } protected: __gnu_profile::__container_size_info* _M_size_info; __gnu_profile::__vector2list_info* _M_vect2list_info; _Vector_profile_post() _GLIBCXX_NOEXCEPT { _M_profile_construct(); } #if __cplusplus >= 201103L _Vector_profile_post(const _Vector_profile_post&) noexcept : _Vector_profile_post() { } _Vector_profile_post(_Vector_profile_post&& __other) noexcept : _Vector_profile_post() { _M_swap(__other); } _Vector_profile_post& operator=(const _Vector_profile_post&) noexcept { _M_profile_construct(); } _Vector_profile_post& operator=(_Vector_profile_post&& __other) noexcept { _M_swap(__other); __other._M_profile_construct(); } #endif ~_Vector_profile_post() { _M_conjure()._M_profile_destruct(); } public: void _M_profile_construct() _GLIBCXX_NOEXCEPT { _M_size_info = __profcxx_vector_size_construct(_M_conjure().capacity()); _M_vect2list_info = __profcxx_vector2list_construct(); } void _M_profile_destruct() _GLIBCXX_NOEXCEPT { __profcxx_vector2list_destruct(_M_vect2list_info); _M_vect2list_info = 0; __profcxx_vector_size_destruct(_M_size_info, _M_conjure().capacity(), _M_conjure().size()); _M_size_info = 0; } void _M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT { std::swap(_M_size_info, __other._M_size_info); std::swap(_M_vect2list_info, __other._M_vect2list_info); } }; template > class vector : public _Vector_profile_pre >, public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, public _Vector_profile_post > { typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, vector> iterator; typedef __iterator_tracker<_Base_const_iterator, vector> const_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; typedef _Tp value_type; typedef _Allocator allocator_type; typedef typename _Base::pointer pointer; typedef typename _Base::const_pointer const_pointer; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } // 23.2.4.1 construct/copy/destroy: #if __cplusplus < 201103L vector() { } vector(const vector& __x) : _Base(__x) { } #else vector() = default; vector(const vector&) = default; vector(vector&&) = default; #endif explicit vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L explicit vector(size_type __n, const _Allocator& __a = _Allocator()) : _Base(__n, __a) { } vector(size_type __n, const _Tp& __value, const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #else explicit vector(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #endif #if __cplusplus >= 201103L template> #else template #endif vector(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__first, __last, __a) { } /// Construction from a normal-mode vector vector(const _Base& __x) : _Base(__x) { } #if __cplusplus >= 201103L vector(const _Base& __x, const _Allocator& __a) : _Base(__x, __a) { } vector(vector&& __x, const _Allocator& __a) : _Base(std::move(__x), __a) { } vector(initializer_list __l, const allocator_type& __a = allocator_type()) : _Base(__l, __a) { } #endif #if __cplusplus < 201103L vector& operator=(const vector& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else vector& operator=(const vector&) = default; vector& operator=(vector&&) = default; vector& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators: iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::begin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::end(), this); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif // 23.2.4.2 capacity: #if __cplusplus >= 201103L void resize(size_type __sz) { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); _M_profile_resize(this->capacity(), __sz); _Base::resize(__sz); } void resize(size_type __sz, const _Tp& __c) { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); _M_profile_resize(this->capacity(), __sz); _Base::resize(__sz, __c); } #else void resize(size_type __sz, _Tp __c = _Tp()) { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); _M_profile_resize(this->capacity(), __sz); _Base::resize(__sz, __c); } #endif // element access: reference operator[](size_type __n) _GLIBCXX_NOEXCEPT { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); return _M_base()[__n]; } const_reference operator[](size_type __n) const _GLIBCXX_NOEXCEPT { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); return _M_base()[__n]; } // 23.2.4.3 modifiers: void push_back(const _Tp& __x) { size_type __old_size = this->capacity(); _Base::push_back(__x); _M_profile_resize(__old_size, this->capacity()); } #if __cplusplus >= 201103L void push_back(_Tp&& __x) { size_type __old_size = this->capacity(); _Base::push_back(std::move(__x)); _M_profile_resize(__old_size, this->capacity()); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const _Tp& __x) #else insert(iterator __pos, const _Tp& __x) #endif { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::begin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos.base(), __x); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, _Tp&& __x) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::cbegin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos.base(), __x); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } template iterator emplace(const_iterator __pos, _Args&&... __args) { _Base_iterator __res = _Base::emplace(__pos.base(), std::forward<_Args>(__args)...); return iterator(__res, this); } iterator insert(const_iterator __pos, initializer_list __l) { return this->insert(__pos, __l.begin(), __l.end()); } #endif void swap(vector& __x) #if __cplusplus >= 201103L noexcept( noexcept(declval<_Base>().swap(__x)) ) #endif { _Base::swap(__x); this->_M_swap(__x); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, size_type __n, const _Tp& __x) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::cbegin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos, __n, __x); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } #else void insert(iterator __pos, size_type __n, const _Tp& __x) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::begin(), this->size()); size_type __old_size = this->capacity(); _Base::insert(__pos, __n, __x); _M_profile_resize(__old_size, this->capacity()); } #endif #if __cplusplus >= 201103L template> iterator insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::cbegin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos, __first, __last); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } #else template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::begin(), this->size()); size_type __old_size = this->capacity(); _Base::insert(__pos, __first, __last); _M_profile_resize(__old_size, this->capacity()); } #endif iterator #if __cplusplus >= 201103L erase(const_iterator __pos) #else erase(iterator __pos) #endif { return iterator(_Base::erase(__pos.base()), this); } iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) #else erase(iterator __first, iterator __last) #endif { return iterator(_Base::erase(__first.base(), __last.base()), this); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } inline void _M_profile_iterate(int __rewind = 0) const { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); } private: void _M_profile_resize(size_type __old_size, size_type __new_size) { if (__old_size < __new_size) { __profcxx_vector_size_resize(this->_M_size_info, this->size(), __new_size); __profcxx_vector2list_resize(this->_M_vect2list_info, this->size(), __new_size); } } }; template inline bool operator==(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile #if __cplusplus >= 201103L // DR 1182. /// std::hash specialization for vector. template struct hash<__profile::vector> : public __hash_base> { size_t operator()(const __profile::vector& __b) const noexcept { return std::hash<_GLIBCXX_STD_C::vector>()(__b._M_base()); } }; #endif } // namespace std #endif PKgd1]8/profile/forward_listnu[// -*- C++ -*- // Copyright (C) 2010-2018 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 profile/forward_list * This file is a GNU debug extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_FORWARD_LIST #define _GLIBCXX_PROFILE_FORWARD_LIST 1 #if __cplusplus < 201103L # include #else #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::forward_list wrapper with performance instrumentation. template > class forward_list : public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> { typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base; public: typedef typename _Base::size_type size_type; typedef typename _Base::const_iterator const_iterator; // 23.2.3.1 construct/copy/destroy: forward_list() = default; explicit forward_list(const _Alloc& __al) noexcept : _Base(__al) { } forward_list(const forward_list& __list, const _Alloc& __al) : _Base(__list, __al) { } forward_list(forward_list&& __list, const _Alloc& __al) : _Base(std::move(__list), __al) { } explicit forward_list(size_type __n, const _Alloc& __al = _Alloc()) : _Base(__n, __al) { } forward_list(size_type __n, const _Tp& __value, const _Alloc& __al = _Alloc()) : _Base(__n, __value, __al) { } template> forward_list(_InputIterator __first, _InputIterator __last, const _Alloc& __al = _Alloc()) : _Base(__first, __last, __al) { } forward_list(const forward_list&) = default; forward_list(forward_list&&) = default; forward_list(std::initializer_list<_Tp> __il, const _Alloc& __al = _Alloc()) : _Base(__il, __al) { } ~forward_list() = default; forward_list& operator=(const forward_list&) = default; forward_list& operator=(forward_list&&) = default; forward_list& operator=(std::initializer_list<_Tp> __il) { _M_base() = __il; return *this; } void swap(forward_list& __fl) noexcept( noexcept(declval<_Base&>().swap(__fl)) ) { _Base::swap(__fl); } void splice_after(const_iterator __pos, forward_list&& __fl) { _Base::splice_after(__pos, std::move(__fl)); } void splice_after(const_iterator __pos, forward_list& __list) { _Base::splice_after(__pos, __list); } void splice_after(const_iterator __pos, forward_list&& __list, const_iterator __i) { _Base::splice_after(__pos, std::move(__list), __i); } void splice_after(const_iterator __pos, forward_list& __list, const_iterator __i) { _Base::splice_after(__pos, __list, __i); } void splice_after(const_iterator __pos, forward_list&& __list, const_iterator __before, const_iterator __last) { _Base::splice_after(__pos, std::move(__list), __before, __last); } void splice_after(const_iterator __pos, forward_list& __list, const_iterator __before, const_iterator __last) { _Base::splice_after(__pos, __list, __before, __last); } void merge(forward_list&& __list) { _Base::merge(std::move(__list)); } void merge(forward_list& __list) { _Base::merge(__list); } template void merge(forward_list&& __list, _Comp __comp) { _Base::merge(std::move(__list), __comp); } template void merge(forward_list& __list, _Comp __comp) { _Base::merge(__list, __comp); } _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } }; template inline bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return __lx._M_base() == __ly._M_base(); } template inline bool operator<(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return __lx._M_base() < __ly._M_base(); } template inline bool operator!=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__lx == __ly); } /// Based on operator< template inline bool operator>(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return (__ly < __lx); } /// Based on operator< template inline bool operator>=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__lx < __ly); } /// Based on operator< template inline bool operator<=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__ly < __lx); } /// See std::forward_list::swap(). template inline void swap(forward_list<_Tp, _Alloc>& __lx, forward_list<_Tp, _Alloc>& __ly) noexcept(noexcept(__lx.swap(__ly))) { __lx.swap(__ly); } } // namespace __profile } // namespace std #endif // C++11 #endif PKgd1]4FԄNN8/profile/map.hnu[// Profiling map implementation -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/map.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MAP_H #define _GLIBCXX_PROFILE_MAP_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::map wrapper with performance instrumentation. template, typename _Allocator = std::allocator > > class map : public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Tp mapped_type; typedef typename _Base::value_type value_type; typedef _Compare key_compare; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, map> iterator; typedef __iterator_tracker<_Base_const_iterator, map> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.1.1 construct/copy/destroy: #if __cplusplus < 201103L map() : _Base() { } map(const map& __x) : _Base(__x) { } ~map() { } #else map() = default; map(const map&) = default; map(map&&) = default; ~map() = default; #endif explicit map(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif map(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } map(const _Base& __x) : _Base(__x) { } #if __cplusplus >= 201103L map(initializer_list __l, const _Compare& __c = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__l, __c, __a) { } explicit map(const _Allocator& __a) : _Base(__a) { } map(const map& __x, const _Allocator& __a) : _Base(__x, __a) { } map(map&& __x, const _Allocator& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } map(initializer_list __l, const _Allocator& __a) : _Base(__l, __a) { } template map(_InputIterator __first, _InputIterator __last, const _Allocator& __a) : _Base(__first, __last, __a) { } #endif #if __cplusplus < 201103L map& operator=(const map& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else map& operator=(const map&) = default; map& operator=(map&&) = default; map& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif // 23.3.1.2 element access: mapped_type& operator[](const key_type& __k) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::operator[](__k); } #if __cplusplus >= 201103L mapped_type& operator[](key_type&& __k) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::operator[](std::move(__k)); } #endif mapped_type& at(const key_type& __k) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::at(__k); } const mapped_type& at(const key_type& __k) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::at(__k); } // modifiers: #if __cplusplus >= 201103L template std::pair emplace(_Args&&... __args) { // The cost is the same whether or not the element is inserted so we // always report insertion of 1 element. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); auto __base_ret = _Base::emplace(std::forward<_Args>(__args)...); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif std::pair insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); std::pair<_Base_iterator, bool> __base_ret = _Base::insert(__x); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #if __cplusplus >= 201103L template::value>::type> std::pair insert(_Pair&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); auto __base_ret= _Base::insert(std::forward<_Pair>(__x)); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #endif #if __cplusplus >= 201103L void insert(std::initializer_list __list) { insert(__list.begin(), __list.end()); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const value_type& __x) #else insert(iterator __pos, const value_type& __x) #endif { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L template::value>::type> iterator insert(const_iterator __pos, _Pair&& __x) { size_type size_before = this->size(); auto __res = _Base::insert(__pos.base(), std::forward<_Pair>(__x)); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif template void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } iterator erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } else return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void swap(map& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } // 23.3.1.3 map operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); template friend bool operator<(const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); }; template inline bool operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template inline void swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs, map<_Key, _Tp, _Compare, _Allocator>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif PKgd1])??8/profile/unordered_setnu[// Profiling unordered_set/unordered_multiset implementation -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/unordered_set * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_UNORDERED_SET #define _GLIBCXX_PROFILE_UNORDERED_SET 1 #if __cplusplus < 201103L # include #else # include #include #include #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /** @brief Unordered_set wrapper with performance instrumentation. */ template, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator<_Key> > class unordered_set : public _GLIBCXX_STD_BASE, public _Unordered_profile, true> { typedef _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_set() = default; explicit unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } 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()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_set(const unordered_set&) = default; unordered_set(const _Base& __x) : _Base(__x) { } unordered_set(unordered_set&&) = default; explicit unordered_set(const allocator_type& __a) : _Base(__a) { } unordered_set(const unordered_set& __uset, const allocator_type& __a) : _Base(__uset._M_base(), __a) { } unordered_set(unordered_set&& __uset, const allocator_type& __a) : _Base(std::move(__uset._M_base()), __a) { } unordered_set(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_set(size_type __n, const allocator_type& __a) : unordered_set(__n, hasher(), key_equal(), __a) { } unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__n, __hf, key_equal(), __a) { } template unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) { } unordered_set(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_set(__l, __n, hasher(), key_equal(), __a) { } unordered_set(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__l, __n, __hf, key_equal(), __a) { } unordered_set& operator=(const unordered_set&) = default; unordered_set& operator=(unordered_set&&) = default; unordered_set& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void swap(unordered_set& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template std::pair emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } std::pair insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } std::pair insert(value_type&& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(std::move(__obj)); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, value_type&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::move(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) { return static_cast(__x) == __y; } template inline bool operator!=(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc> /** @brief Unordered_multiset wrapper with performance instrumentation. */ template, typename _Pred = std::equal_to<_Value>, typename _Alloc = std::allocator<_Value> > class unordered_multiset : public _GLIBCXX_STD_BASE, public _Unordered_profile, false> { typedef _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_multiset() = default; explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } 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()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_multiset(const unordered_multiset&) = default; unordered_multiset(const _Base& __x) : _Base(__x) { } unordered_multiset(unordered_multiset&&) = default; explicit unordered_multiset(const allocator_type& __a) : _Base(__a) { } unordered_multiset(const unordered_multiset& __umset, const allocator_type& __a) : _Base(__umset._M_base(), __a) { } unordered_multiset(unordered_multiset&& __umset, const allocator_type& __a) : _Base(std::move(__umset._M_base()), __a) { } unordered_multiset(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_multiset(size_type __n, const allocator_type& __a) : unordered_multiset(__n, hasher(), key_equal(), __a) { } unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__n, __hf, key_equal(), __a) { } template unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multiset(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_multiset(__l, __n, hasher(), key_equal(), __a) { } unordered_multiset(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } unordered_multiset& operator=(const unordered_multiset&) = default; unordered_multiset& operator=(unordered_multiset&&) = default; unordered_multiset& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void swap(unordered_multiset& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template iterator emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } iterator insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } iterator insert(value_type&& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(std::move(__obj)); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, value_type&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::move(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) { return static_cast(__x) == __y; } template inline bool operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } } // namespace __profile } // namespace std #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #endif // C++11 #endif PKgd1]j&\"\"8/profile/arraynu[// Profile array implementation -*- C++ -*- // Copyright (C) 2012-2018 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 profile/array * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_PROFILE_ARRAY #define _GLIBCXX_PROFILE_ARRAY 1 #pragma GCC system_header #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template struct array { typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef value_type* iterator; typedef const value_type* const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; // Support for zero-sized arrays mandatory. typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type; typename _AT_Type::_Type _M_elems; // No explicit construct/copy/destroy for aggregate type. // DR 776. void fill(const value_type& __u) { std::fill_n(begin(), size(), __u); } void swap(array& __other) noexcept(_AT_Type::_Is_nothrow_swappable::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. _GLIBCXX17_CONSTEXPR iterator begin() noexcept { return iterator(data()); } _GLIBCXX17_CONSTEXPR const_iterator begin() const noexcept { return const_iterator(data()); } _GLIBCXX17_CONSTEXPR iterator end() noexcept { return iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR const_iterator end() const noexcept { return const_iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR reverse_iterator rend() noexcept { return reverse_iterator(begin()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } _GLIBCXX17_CONSTEXPR const_iterator cbegin() const noexcept { return const_iterator(data()); } _GLIBCXX17_CONSTEXPR const_iterator cend() const noexcept { return const_iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } // Capacity. constexpr size_type size() const noexcept { return _Nm; } constexpr size_type max_size() const noexcept { return _Nm; } constexpr bool empty() const noexcept { return size() == 0; } // Element access. reference operator[](size_type __n) noexcept { return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference operator[](size_type __n) const noexcept { return _AT_Type::_S_ref(_M_elems, __n); } _GLIBCXX17_CONSTEXPR reference at(size_type __n) { if (__n >= _Nm) std::__throw_out_of_range_fmt(__N("array::at: __n " "(which is %zu) >= _Nm " "(which is %zu)"), __n, _Nm); return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference at(size_type __n) const { // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " ">= _Nm (which is %zu)"), __n, _Nm), _AT_Type::_S_ref(_M_elems, 0)); } _GLIBCXX17_CONSTEXPR reference front() noexcept { return *begin(); } constexpr const_reference front() const noexcept { return _AT_Type::_S_ref(_M_elems, 0); } _GLIBCXX17_CONSTEXPR reference back() noexcept { return _Nm ? *(end() - 1) : *end(); } constexpr const_reference back() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) : _AT_Type::_S_ref(_M_elems, 0); } _GLIBCXX17_CONSTEXPR pointer data() noexcept { return _AT_Type::_S_ptr(_M_elems); } _GLIBCXX17_CONSTEXPR const_pointer data() const noexcept { return _AT_Type::_S_ptr(_M_elems); } }; // Array comparisons. template inline bool operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return std::equal(__one.begin(), __one.end(), __two.begin()); } template inline bool operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one == __two); } template inline bool operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) { return std::lexicographical_compare(__a.begin(), __a.end(), __b.begin(), __b.end()); } template inline bool operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return __two < __one; } template inline bool operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one > __two); } template inline bool operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one < __two); } // Specialized algorithms. template inline void swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) noexcept(noexcept(__one.swap(__two))) { __one.swap(__two); } template constexpr _Tp& get(array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } template constexpr _Tp&& get(array<_Tp, _Nm>&& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); return std::move(__profile::get<_Int>(__arr)); } template constexpr const _Tp& get(const array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } } // namespace __profile _GLIBCXX_BEGIN_NAMESPACE_VERSION // Tuple interface to class template array. /// tuple_size template struct tuple_size> : public integral_constant { }; /// tuple_element template struct tuple_element<_Int, std::__profile::array<_Tp, _Nm>> { static_assert(_Int < _Nm, "index is out of bounds"); typedef _Tp type; }; template struct __is_tuple_like_impl> : true_type { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _GLIBCXX_PROFILE_ARRAY PKgd1]y(AA8/profile/listnu[// Profiling list implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/list * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_LIST #define _GLIBCXX_PROFILE_LIST 1 #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class _List_profile { _List& _M_conjure() { return *static_cast<_List*>(this); } public: __gnu_profile::__list2slist_info* _M_list2slist_info; __gnu_profile::__list2vector_info* _M_list2vector_info; _List_profile() _GLIBCXX_NOEXCEPT { _M_profile_construct(); } void _M_profile_construct() _GLIBCXX_NOEXCEPT { _M_list2slist_info = __profcxx_list2slist_construct(); _M_list2vector_info = __profcxx_list2vector_construct(); } void _M_profile_destruct() _GLIBCXX_NOEXCEPT { __profcxx_list2vector_destruct(_M_list2vector_info); _M_list2vector_info = 0; __profcxx_list2slist_destruct(_M_list2slist_info); _M_list2slist_info = 0; } void _M_swap(_List_profile& __other) { std::swap(_M_list2slist_info, __other._M_list2slist_info); std::swap(_M_list2vector_info, __other._M_list2vector_info); } #if __cplusplus >= 201103L _List_profile(const _List_profile&) noexcept : _List_profile() { } _List_profile(_List_profile&& __other) noexcept : _List_profile() { _M_swap(__other); } _List_profile& operator=(const _List_profile&) noexcept { _M_profile_destruct(); _M_profile_construct(); } _List_profile& operator=(_List_profile&& __other) noexcept { _M_swap(__other); __other._M_profile_destruct(); __other._M_profile_construct(); } #endif ~_List_profile() { _M_profile_destruct(); } }; /** @brief List wrapper with performance instrumentation. */ template > class list : public _GLIBCXX_STD_C::list<_Tp, _Allocator>, public _List_profile > { typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base; public: typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker iterator; typedef __iterator_tracker const_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; typedef _Tp value_type; typedef _Allocator allocator_type; typedef typename _Base::pointer pointer; typedef typename _Base::const_pointer const_pointer; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; // 23.2.2.1 construct/copy/destroy: #if __cplusplus < 201103L list() { } list(const list& __x) : _Base(__x) { } ~list() { } #else list() = default; list(const list&) = default; list(list&&) = default; ~list() = default; list(initializer_list __l, const allocator_type& __a = allocator_type()) : _Base(__l, __a) { } list(const list& __x, const allocator_type& __a) : _Base(__x, __a) { } list(list&& __x, const allocator_type& __a) : _Base(std::move(__x), __a) { } #endif explicit list(const _Allocator& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L explicit list(size_type __n, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { } list(size_type __n, const _Tp& __value, const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #else explicit list(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #endif #if __cplusplus >= 201103L template> #else template #endif list(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__first, __last, __a) { } list(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L list& operator=(const list& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else list& operator=(const list&) = default; list& operator=(list&&) = default; list& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators: iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return const_iterator(_Base::end(), this); } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif // 23.2.2.2 capacity: reference back() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return _Base::back(); } const_reference back() const _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return _Base::back(); } // 23.2.2.3 modifiers: void push_front(const value_type& __x) { __profcxx_list2vector_invalid_operator(this->_M_list2vector_info); __profcxx_list2slist_operation(this->_M_list2slist_info); _Base::push_front(__x); } void pop_front() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_operation(this->_M_list2slist_info); _Base::pop_front(); } void pop_back() _GLIBCXX_NOEXCEPT { _Base::pop_back(); __profcxx_list2slist_rewind(this->_M_list2slist_info); } #if __cplusplus >= 201103L template iterator emplace(const_iterator __position, _Args&&... __args) { return iterator(_Base::emplace(__position.base(), std::forward<_Args>(__args)...), this); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const _Tp& __x) #else insert(iterator __pos, const _Tp& __x) #endif { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __x), this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, _Tp&& __x) { _M_profile_insert(__pos, this->size()); return iterator(_Base::emplace(__pos.base(), std::move(__x)), this); } iterator insert(const_iterator __pos, initializer_list __l) { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __l), this); } #endif #if __cplusplus >= 201103L iterator insert(const_iterator __pos, size_type __n, const _Tp& __x) { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __n, __x), this); } #else void insert(iterator __pos, size_type __n, const _Tp& __x) { _M_profile_insert(__pos, this->size()); _Base::insert(__pos.base(), __n, __x); } #endif #if __cplusplus >= 201103L template> iterator insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __first, __last), this); } #else template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { _M_profile_insert(__pos, this->size()); _Base::insert(__pos.base(), __first, __last); } #endif iterator #if __cplusplus >= 201103L erase(const_iterator __pos) noexcept #else erase(iterator __pos) #endif { return iterator(_Base::erase(__pos.base()), this); } iterator #if __cplusplus >= 201103L erase(const_iterator __pos, const_iterator __last) noexcept #else erase(iterator __pos, iterator __last) #endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 151. can't currently clear() empty container return iterator(_Base::erase(__pos.base(), __last.base()), this); } void swap(list& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } // 23.2.2.4 list operations: void #if __cplusplus >= 201103L splice(const_iterator __pos, list&& __x) noexcept #else splice(iterator __pos, list& __x) #endif { this->splice(__pos, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); } #if __cplusplus >= 201103L void splice(const_iterator __pos, list& __x) noexcept { this->splice(__pos, std::move(__x)); } void splice(const_iterator __pos, list& __x, const_iterator __i) { this->splice(__pos, std::move(__x), __i); } #endif void #if __cplusplus >= 201103L splice(const_iterator __pos, list&& __x, const_iterator __i) noexcept #else splice(iterator __pos, list& __x, iterator __i) #endif { // We used to perform the splice_alloc check: not anymore, redundant // after implementing the relevant bits of N1599. // _GLIBCXX_RESOLVE_LIB_DEFECTS _Base::splice(__pos.base(), _GLIBCXX_MOVE(__x._M_base()), __i.base()); } void #if __cplusplus >= 201103L splice(const_iterator __pos, list&& __x, const_iterator __first, const_iterator __last) noexcept #else splice(iterator __pos, list& __x, iterator __first, iterator __last) #endif { _Base::splice(__pos.base(), _GLIBCXX_MOVE(__x._M_base()), __first.base(), __last.base()); } #if __cplusplus >= 201103L void splice(const_iterator __pos, list& __x, const_iterator __first, const_iterator __last) noexcept { this->splice(__pos, std::move(__x), __first, __last); } #endif void remove(const _Tp& __value) { for (iterator __x = begin(); __x != end(); ) { if (*__x == __value) __x = erase(__x); else ++__x; } } template void remove_if(_Predicate __pred) { for (iterator __x = begin(); __x != end(); ) { __profcxx_list2slist_operation(this->_M_list2slist_info); if (__pred(*__x)) __x = erase(__x); else ++__x; } } void unique() { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { __profcxx_list2slist_operation(this->_M_list2slist_info); if (*__first == *__next) erase(__next); else __first = __next; __next = __first; } } template void unique(_BinaryPredicate __binary_pred) { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { __profcxx_list2slist_operation(this->_M_list2slist_info); if (__binary_pred(*__first, *__next)) erase(__next); else __first = __next; __next = __first; } } void #if __cplusplus >= 201103L merge(list&& __x) #else merge(list& __x) #endif { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); } #if __cplusplus >= 201103L void merge(list& __x) { this->merge(std::move(__x)); } #endif template void #if __cplusplus >= 201103L merge(list&& __x, _Compare __comp) #else merge(list& __x, _Compare __comp) #endif { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); } #if __cplusplus >= 201103L template void merge(list& __x, _Compare __comp) { this->merge(std::move(__x), __comp); } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } void _M_profile_iterate(int __rewind = 0) const { __profcxx_list2slist_operation(this->_M_list2slist_info); __profcxx_list2vector_iterate(this->_M_list2vector_info, __rewind); if (__rewind) __profcxx_list2slist_rewind(this->_M_list2slist_info); } private: size_type _M_profile_insert(const_iterator __pos, size_type __size) { size_type __shift = 0; typename _Base::const_iterator __it = __pos.base(); for (; __it != _Base::end(); ++__it) __shift++; __profcxx_list2slist_rewind(this->_M_list2slist_info); __profcxx_list2slist_operation(this->_M_list2slist_info); __profcxx_list2vector_insert(this->_M_list2vector_info, __shift, __size); } }; template inline bool operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif PKgd1]i 8/profile/ordered_base.hnu[// Profiling unordered containers implementation details -*- C++ -*- // Copyright (C) 2014-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/ordered_base.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_ORDERED #define _GLIBCXX_PROFILE_ORDERED 1 namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class _Ordered_profile { public: void _M_profile_iterate(int __rewind = 0) const { __profcxx_map2umap_iterate(this->_M_map2umap_info, __rewind); } protected: _Ordered_profile() _GLIBCXX_NOEXCEPT { _M_profile_construct(); } #if __cplusplus >= 201103L _Ordered_profile(const _Ordered_profile&) noexcept : _Ordered_profile() { } _Ordered_profile(_Ordered_profile&& __other) noexcept : _Ordered_profile() { _M_swap(__other); } _Ordered_profile& operator=(const _Ordered_profile&) noexcept { _M_profile_destruct(); _M_profile_construct(); } _Ordered_profile& operator=(_Ordered_profile&& __other) noexcept { _M_swap(__other); __other._M_profile_destruct(); __other._M_profile_construct(); } #endif ~_Ordered_profile() { _M_profile_destruct(); } void _M_profile_construct() _GLIBCXX_NOEXCEPT { _M_map2umap_info = __profcxx_map2umap_construct(); } void _M_profile_destruct() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_destruct(_M_map2umap_info); _M_map2umap_info = 0; } void _M_swap(_Ordered_profile& __other) { std::swap(_M_map2umap_info, __other._M_map2umap_info); } __gnu_profile::__map2umap_info* _M_map2umap_info; private: _Cont& _M_conjure() { return *static_cast<_Cont*>(this); } }; } // namespace __profile } // namespace std #endif PKgd1]L8/profile/base.hnu[// -*- C++ -*- // Copyright (C) 2009-2018 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 along // with this library; see the file COPYING3. If not see // . /** @file profile/base.h * @brief Sequential helper functions. * This file is a GNU profile extension to the Standard C++ Library. */ // Written by Lixia Liu #ifndef _GLIBCXX_PROFILE_BASE_H #define _GLIBCXX_PROFILE_BASE_H 1 #include // Profiling mode namespaces. /** * @namespace std::__profile * @brief GNU profile code, replaces standard behavior with profile behavior. */ namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { } } /** * @namespace __gnu_profile * @brief GNU profile code for public use. */ namespace __gnu_profile { // Import all the profile versions of components in namespace std. using namespace std::__profile; } #endif /* _GLIBCXX_PROFILE_BASE_H */ PKgd1]/ȒII8/profile/multiset.hnu[// Profiling multiset implementation -*- C++ -*- // Copyright (C) 2009-2018 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 profile/multiset.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MULTISET_H #define _GLIBCXX_PROFILE_MULTISET_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::multiset wrapper with performance instrumentation. template, typename _Allocator = std::allocator<_Key> > class multiset : public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef _Allocator allocator_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, multiset> iterator; typedef __iterator_tracker<_Base_const_iterator, multiset> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.3.1 construct/copy/destroy: #if __cplusplus < 201103L multiset() : _Base() { } multiset(const multiset& __x) : _Base(__x) { } ~multiset() { } #else multiset() = default; multiset(const multiset&) = default; multiset(multiset&&) = default; ~multiset() = default; #endif explicit multiset(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif multiset(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } #if __cplusplus >= 201103L multiset(initializer_list __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _Base(__l, __comp, __a) { } explicit multiset(const allocator_type& __a) : _Base(__a) { } multiset(const multiset& __x, const allocator_type& __a) : _Base(__x, __a) { } multiset(multiset&& __x, const allocator_type& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } multiset(initializer_list __l, const allocator_type& __a) : _Base(__l, __a) { } template multiset(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _Base(__first, __last, __a) { } #endif multiset(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L multiset& operator=(const multiset& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else multiset& operator=(const multiset&) = default; multiset& operator=(multiset&&) = default; multiset& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif void swap(multiset& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } // modifiers: #if __cplusplus >= 201103L template iterator emplace(_Args&&... __args) { // The cost is the same whether or not the element is inserted so we // always report insertion of 1 element. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::emplace(std::forward<_Args>(__args)...), this); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif iterator insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(__x), this); } #if __cplusplus >= 201103L iterator insert(value_type&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(std::move(__x)), this); } #endif iterator insert(const_iterator __pos, const value_type& __x) { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, value_type&& __x) { auto size_before = this->size(); auto __res = _Base::insert(__pos.base(), std::move(__x)); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif #if __cplusplus >= 201103L template> #else template #endif void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L void insert(initializer_list __l) { insert(__l.begin(), __l.end()); } #endif #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } else return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif // multiset operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::lower_bound(__x), this); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const multiset<_K1, _C1, _A1>&, const multiset<_K1, _C1, _A1>&); template friend bool operator< (const multiset<_K1, _C1, _A1>&, const multiset<_K1, _C1, _A1>&); }; template inline bool operator==(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template void swap(multiset<_Key, _Compare, _Allocator>& __x, multiset<_Key, _Compare, _Allocator>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { return __x.swap(__y); } } // namespace __profile } // namespace std #endif PKgd1] 3k77 8/ccomplexnu[// -*- C++ -*- // Copyright (C) 2007-2018 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/ccomplex * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CCOMPLEX #define _GLIBCXX_CCOMPLEX 1 #if __cplusplus < 201103L # include #endif extern "C++" { #include } #endif PKgd1]2)/H 8/cwctypenu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cwctype * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c wctype.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: // #pragma GCC system_header #include #if _GLIBCXX_HAVE_WCTYPE_H #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 10 // Work around glibc BZ 9694 #include #endif #include #endif // _GLIBCXX_HAVE_WCTYPE_H #ifndef _GLIBCXX_CWCTYPE #define _GLIBCXX_CWCTYPE 1 // Get rid of those macros defined in in lieu of real functions. #undef iswalnum #undef iswalpha #if _GLIBCXX_HAVE_ISWBLANK # undef iswblank #endif #undef iswcntrl #undef iswctype #undef iswdigit #undef iswgraph #undef iswlower #undef iswprint #undef iswpunct #undef iswspace #undef iswupper #undef iswxdigit #undef towctrans #undef towlower #undef towupper #undef wctrans #undef wctype #if _GLIBCXX_USE_WCHAR_T namespace std { using ::wctrans_t; using ::wctype_t; using ::wint_t; using ::iswalnum; using ::iswalpha; #if _GLIBCXX_HAVE_ISWBLANK using ::iswblank; #endif using ::iswcntrl; using ::iswctype; using ::iswdigit; using ::iswgraph; using ::iswlower; using ::iswprint; using ::iswpunct; using ::iswspace; using ::iswupper; using ::iswxdigit; using ::towctrans; using ::towlower; using ::towupper; using ::wctrans; using ::wctype; } // namespace #endif //_GLIBCXX_USE_WCHAR_T #endif // _GLIBCXX_CWCTYPE PKgd1]K 8/cstdalignnu[// -*- C++ -*- // Copyright (C) 2011-2018 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/cstdalign * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CSTDALIGN #define _GLIBCXX_CSTDALIGN 1 #if __cplusplus < 201103L # include #else # include # if _GLIBCXX_HAVE_STDALIGN_H # include # endif #endif #endif PKgd1]8/localenu[// Locale support -*- C++ -*- // Copyright (C) 1997-2018 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 // . // // ISO C++ 14882: 22.1 Locales // /** @file include/locale * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_LOCALE #define _GLIBCXX_LOCALE 1 #pragma GCC system_header #include #include #include #include #if __cplusplus >= 201103L # include #endif #endif /* _GLIBCXX_LOCALE */ PKgd1]ƒ<0G0G8/mutexnu[// -*- C++ -*- // Copyright (C) 2003-2018 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/mutex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_MUTEX #define _GLIBCXX_MUTEX 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #if ! _GTHREAD_USE_MUTEX_TIMEDLOCK # include # include #endif #ifndef _GLIBCXX_HAVE_TLS # include #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @ingroup mutexes * @{ */ #ifdef _GLIBCXX_HAS_GTHREADS // Common base class for std::recursive_mutex and std::recursive_timed_mutex class __recursive_mutex_base { protected: typedef __gthread_recursive_mutex_t __native_type; __recursive_mutex_base(const __recursive_mutex_base&) = delete; __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete; #ifdef __GTHREAD_RECURSIVE_MUTEX_INIT __native_type _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; __recursive_mutex_base() = default; #else __native_type _M_mutex; __recursive_mutex_base() { // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); } ~__recursive_mutex_base() { __gthread_recursive_mutex_destroy(&_M_mutex); } #endif }; /// The standard recursive mutex type. class recursive_mutex : private __recursive_mutex_base { public: typedef __native_type* native_handle_type; recursive_mutex() = default; ~recursive_mutex() = default; recursive_mutex(const recursive_mutex&) = delete; recursive_mutex& operator=(const recursive_mutex&) = delete; void lock() { int __e = __gthread_recursive_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_recursive_mutex_trylock(&_M_mutex); } void unlock() { // XXX EINVAL, EAGAIN, EBUSY __gthread_recursive_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } }; #if _GTHREAD_USE_MUTEX_TIMEDLOCK template class __timed_mutex_impl { protected: typedef chrono::high_resolution_clock __clock_t; template bool _M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { using chrono::steady_clock; auto __rt = chrono::duration_cast(__rtime); if (ratio_greater()) ++__rt; return _M_try_lock_until(steady_clock::now() + __rt); } template bool _M_try_lock_until(const chrono::time_point<__clock_t, _Duration>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; return static_cast<_Derived*>(this)->_M_timedlock(__ts); } template bool _M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { auto __rtime = __atime - _Clock::now(); return _M_try_lock_until(__clock_t::now() + __rtime); } }; /// The standard timed mutex type. class timed_mutex : private __mutex_base, public __timed_mutex_impl { public: typedef __native_type* native_handle_type; timed_mutex() = default; ~timed_mutex() = default; timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; void lock() { int __e = __gthread_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_mutex_trylock(&_M_mutex); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { return _M_try_lock_for(__rtime); } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { return _M_try_lock_until(__atime); } void unlock() { // XXX EINVAL, EAGAIN, EBUSY __gthread_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } private: friend class __timed_mutex_impl; bool _M_timedlock(const __gthread_time_t& __ts) { return !__gthread_mutex_timedlock(&_M_mutex, &__ts); } }; /// recursive_timed_mutex class recursive_timed_mutex : private __recursive_mutex_base, public __timed_mutex_impl { public: typedef __native_type* native_handle_type; recursive_timed_mutex() = default; ~recursive_timed_mutex() = default; recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; void lock() { int __e = __gthread_recursive_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_recursive_mutex_trylock(&_M_mutex); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { return _M_try_lock_for(__rtime); } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { return _M_try_lock_until(__atime); } void unlock() { // XXX EINVAL, EAGAIN, EBUSY __gthread_recursive_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } private: friend class __timed_mutex_impl; bool _M_timedlock(const __gthread_time_t& __ts) { return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); } }; #else // !_GTHREAD_USE_MUTEX_TIMEDLOCK /// timed_mutex class timed_mutex { mutex _M_mut; condition_variable _M_cv; bool _M_locked = false; public: timed_mutex() = default; ~timed_mutex() { __glibcxx_assert( !_M_locked ); } timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; void lock() { unique_lock __lk(_M_mut); _M_cv.wait(__lk, [&]{ return !_M_locked; }); _M_locked = true; } bool try_lock() { lock_guard __lk(_M_mut); if (_M_locked) return false; _M_locked = true; return true; } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { unique_lock __lk(_M_mut); if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; })) return false; _M_locked = true; return true; } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { unique_lock __lk(_M_mut); if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; })) return false; _M_locked = true; return true; } void unlock() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_locked ); _M_locked = false; _M_cv.notify_one(); } }; /// recursive_timed_mutex class recursive_timed_mutex { mutex _M_mut; condition_variable _M_cv; thread::id _M_owner; unsigned _M_count = 0; // Predicate type that tests whether the current thread can lock a mutex. struct _Can_lock { // Returns true if the mutex is unlocked or is locked by _M_caller. bool operator()() const noexcept { return _M_mx->_M_count == 0 || _M_mx->_M_owner == _M_caller; } const recursive_timed_mutex* _M_mx; thread::id _M_caller; }; public: recursive_timed_mutex() = default; ~recursive_timed_mutex() { __glibcxx_assert( _M_count == 0 ); } recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; void lock() { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; unique_lock __lk(_M_mut); _M_cv.wait(__lk, __can_lock); if (_M_count == -1u) __throw_system_error(EAGAIN); // [thread.timedmutex.recursive]/3 _M_owner = __id; ++_M_count; } bool try_lock() { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; lock_guard __lk(_M_mut); if (!__can_lock()) return false; if (_M_count == -1u) return false; _M_owner = __id; ++_M_count; return true; } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; unique_lock __lk(_M_mut); if (!_M_cv.wait_for(__lk, __rtime, __can_lock)) return false; if (_M_count == -1u) return false; _M_owner = __id; ++_M_count; return true; } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; unique_lock __lk(_M_mut); if (!_M_cv.wait_until(__lk, __atime, __can_lock)) return false; if (_M_count == -1u) return false; _M_owner = __id; ++_M_count; return true; } void unlock() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_owner == this_thread::get_id() ); __glibcxx_assert( _M_count > 0 ); if (--_M_count == 0) { _M_owner = {}; _M_cv.notify_one(); } } }; #endif #endif // _GLIBCXX_HAS_GTHREADS template inline unique_lock<_Lock> __try_to_lock(_Lock& __l) { return unique_lock<_Lock>{__l, try_to_lock}; } template struct __try_lock_impl { template static void __do_try_lock(tuple<_Lock&...>& __locks, int& __idx) { __idx = _Idx; auto __lock = std::__try_to_lock(std::get<_Idx>(__locks)); if (__lock.owns_lock()) { constexpr bool __cont = _Idx + 2 < sizeof...(_Lock); using __try_locker = __try_lock_impl<_Idx + 1, __cont>; __try_locker::__do_try_lock(__locks, __idx); if (__idx == -1) __lock.release(); } } }; template struct __try_lock_impl<_Idx, false> { template static void __do_try_lock(tuple<_Lock&...>& __locks, int& __idx) { __idx = _Idx; auto __lock = std::__try_to_lock(std::get<_Idx>(__locks)); if (__lock.owns_lock()) { __idx = -1; __lock.release(); } } }; /** @brief Generic try_lock. * @param __l1 Meets Lockable requirements (try_lock() may throw). * @param __l2 Meets Lockable requirements (try_lock() may throw). * @param __l3 Meets Lockable requirements (try_lock() may throw). * @return Returns -1 if all try_lock() calls return true. Otherwise returns * a 0-based index corresponding to the argument that returned false. * @post Either all arguments are locked, or none will be. * * Sequentially calls try_lock() on each argument. */ template int try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3) { int __idx; auto __locks = std::tie(__l1, __l2, __l3...); __try_lock_impl<0>::__do_try_lock(__locks, __idx); return __idx; } /** @brief Generic lock. * @param __l1 Meets Lockable requirements (try_lock() may throw). * @param __l2 Meets Lockable requirements (try_lock() may throw). * @param __l3 Meets Lockable requirements (try_lock() may throw). * @throw An exception thrown by an argument's lock() or try_lock() member. * @post All arguments are locked. * * All arguments are locked via a sequence of calls to lock(), try_lock() * and unlock(). If the call exits via an exception any locks that were * obtained will be released. */ template void lock(_L1& __l1, _L2& __l2, _L3&... __l3) { while (true) { using __try_locker = __try_lock_impl<0, sizeof...(_L3) != 0>; unique_lock<_L1> __first(__l1); int __idx; auto __locks = std::tie(__l2, __l3...); __try_locker::__do_try_lock(__locks, __idx); if (__idx == -1) { __first.release(); return; } } } #if __cplusplus >= 201703L #define __cpp_lib_scoped_lock 201703 /** @brief A scoped lock type for multiple lockable objects. * * A scoped_lock controls mutex ownership within a scope, releasing * ownership in the destructor. */ template class scoped_lock { public: explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...)) { std::lock(__m...); } explicit scoped_lock(adopt_lock_t, _MutexTypes&... __m) noexcept : _M_devices(std::tie(__m...)) { } // calling thread owns mutex ~scoped_lock() { std::apply([](_MutexTypes&... __m) { char __i[] __attribute__((__unused__)) = { (__m.unlock(), 0)... }; }, _M_devices); } scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; private: tuple<_MutexTypes&...> _M_devices; }; template<> class scoped_lock<> { public: explicit scoped_lock() = default; explicit scoped_lock(adopt_lock_t) noexcept { } ~scoped_lock() = default; scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; }; template class scoped_lock<_Mutex> { public: using mutex_type = _Mutex; explicit scoped_lock(mutex_type& __m) : _M_device(__m) { _M_device.lock(); } explicit scoped_lock(adopt_lock_t, mutex_type& __m) noexcept : _M_device(__m) { } // calling thread owns mutex ~scoped_lock() { _M_device.unlock(); } scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; private: mutex_type& _M_device; }; #endif // C++17 #ifdef _GLIBCXX_HAS_GTHREADS /// once_flag struct once_flag { private: typedef __gthread_once_t __native_type; __native_type _M_once = __GTHREAD_ONCE_INIT; public: /// Constructor constexpr once_flag() noexcept = default; /// Deleted copy constructor once_flag(const once_flag&) = delete; /// Deleted assignment operator once_flag& operator=(const once_flag&) = delete; template friend void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args); }; #ifdef _GLIBCXX_HAVE_TLS extern __thread void* __once_callable; extern __thread void (*__once_call)(); #else extern function __once_functor; extern void __set_once_functor_lock_ptr(unique_lock*); extern mutex& __get_once_mutex(); #endif extern "C" void __once_proxy(void); /// call_once template void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2442. call_once() shouldn't DECAY_COPY() auto __callable = [&] { std::__invoke(std::forward<_Callable>(__f), std::forward<_Args>(__args)...); }; #ifdef _GLIBCXX_HAVE_TLS __once_callable = std::__addressof(__callable); // NOLINT: PR 82481 __once_call = []{ (*(decltype(__callable)*)__once_callable)(); }; #else unique_lock __functor_lock(__get_once_mutex()); __once_functor = __callable; __set_once_functor_lock_ptr(&__functor_lock); #endif int __e = __gthread_once(&__once._M_once, &__once_proxy); #ifndef _GLIBCXX_HAVE_TLS if (__functor_lock) __set_once_functor_lock_ptr(0); #endif if (__e) __throw_system_error(__e); } #endif // _GLIBCXX_HAS_GTHREADS // @} group mutexes _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_MUTEX PKgd1]N'' 8/stdexceptnu[// Standard exception classes -*- C++ -*- // Copyright (C) 2001-2018 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/stdexcept * This is a Standard C++ Library header. */ // // ISO C++ 19.1 Exception classes // #ifndef _GLIBCXX_STDEXCEPT #define _GLIBCXX_STDEXCEPT 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_DUAL_ABI #if _GLIBCXX_USE_CXX11_ABI // Emulates an old COW string when the new std::string is in use. struct __cow_string { union { const char* _M_p; char _M_bytes[sizeof(const char*)]; }; __cow_string(); __cow_string(const std::string&); __cow_string(const char*, size_t); __cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; __cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; ~__cow_string(); #if __cplusplus >= 201103L __cow_string(__cow_string&&) noexcept; __cow_string& operator=(__cow_string&&) noexcept; #endif }; typedef basic_string __sso_string; #else // _GLIBCXX_USE_CXX11_ABI typedef basic_string __cow_string; // Emulates a new SSO string when the old std::string is in use. struct __sso_string { struct __str { const char* _M_p; size_t _M_string_length; char _M_local_buf[16]; }; union { __str _M_s; char _M_bytes[sizeof(__str)]; }; __sso_string() _GLIBCXX_USE_NOEXCEPT; __sso_string(const std::string&); __sso_string(const char*, size_t); __sso_string(const __sso_string&); __sso_string& operator=(const __sso_string&); ~__sso_string(); #if __cplusplus >= 201103L __sso_string(__sso_string&&) noexcept; __sso_string& operator=(__sso_string&&) noexcept; #endif }; #endif // _GLIBCXX_USE_CXX11_ABI #else // _GLIBCXX_USE_DUAL_ABI typedef basic_string __sso_string; typedef basic_string __cow_string; #endif /** * @addtogroup exceptions * @{ */ /** Logic errors represent problems in the internal logic of a program; * in theory, these are preventable, and even detectable before the * program runs (e.g., violations of class invariants). * @brief One of two subclasses of exception. */ class logic_error : public exception { __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit logic_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit logic_error(const char*) _GLIBCXX_TXN_SAFE; #endif #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT; logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT; #endif virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of * the current error (the same string passed to the ctor). */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void* ::_txnal_logic_error_get_msg(void* e); # endif }; /** Thrown by the library, or by you, to report domain errors (domain in * the mathematical sense). */ class domain_error : public logic_error { public: explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit domain_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to report invalid arguments to functions. */ class invalid_argument : public logic_error { public: explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown when an object is constructed that would exceed its maximum * permitted size (e.g., a basic_string instance). */ class length_error : public logic_error { public: explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit length_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~length_error() _GLIBCXX_USE_NOEXCEPT; }; /** This represents an argument whose value is not within the expected * range (e.g., boundary checks in basic_string). */ class out_of_range : public logic_error { public: explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT; }; /** Runtime errors represent problems outside the scope of a program; * they cannot be easily predicted and can generally only be caught as * the program executes. * @brief One of two subclasses of exception. */ class runtime_error : public exception { __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit runtime_error(const char*) _GLIBCXX_TXN_SAFE; #endif #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; #endif virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of * the current error (the same string passed to the ctor). */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void* ::_txnal_runtime_error_get_msg(void* e); # endif }; /** Thrown to indicate range errors in internal computations. */ class range_error : public runtime_error { public: explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit range_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~range_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to indicate arithmetic overflow. */ class overflow_error : public runtime_error { public: explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to indicate arithmetic underflow. */ class underflow_error : public runtime_error { public: explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT; }; // @} group exceptions _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GLIBCXX_STDEXCEPT */ PKgd1]8xvv 8/functionalnu[// -*- C++ -*- // Copyright (C) 2001-2018 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) 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 include/functional * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FUNCTIONAL #define _GLIBCXX_FUNCTIONAL 1 #pragma GCC system_header #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include // std::reference_wrapper and _Mem_fn_traits #include // std::function #if __cplusplus > 201402L # include # include # include # include # include #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201402L # define __cpp_lib_invoke 201411 /// Invoke a callable object. template inline invoke_result_t<_Callable, _Args...> invoke(_Callable&& __fn, _Args&&... __args) noexcept(is_nothrow_invocable_v<_Callable, _Args...>) { return std::__invoke(std::forward<_Callable>(__fn), std::forward<_Args>(__args)...); } #endif template::value> class _Mem_fn_base : public _Mem_fn_traits<_MemFunPtr>::__maybe_type { using _Traits = _Mem_fn_traits<_MemFunPtr>; using _Arity = typename _Traits::__arity; using _Varargs = typename _Traits::__vararg; template friend struct _Bind_check_arity; _MemFunPtr _M_pmf; public: using result_type = typename _Traits::__result_type; explicit constexpr _Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { } template auto operator()(_Args&&... __args) const noexcept(noexcept( std::__invoke(_M_pmf, std::forward<_Args>(__args)...))) -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) { return std::__invoke(_M_pmf, std::forward<_Args>(__args)...); } }; // Partial specialization for member object pointers. template class _Mem_fn_base<_MemObjPtr, false> { using _Arity = integral_constant; using _Varargs = false_type; template friend struct _Bind_check_arity; _MemObjPtr _M_pm; public: explicit constexpr _Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { } template auto operator()(_Tp&& __obj) const noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj)))) -> decltype(std::__invoke(_M_pm, std::forward<_Tp>(__obj))) { return std::__invoke(_M_pm, std::forward<_Tp>(__obj)); } }; template struct _Mem_fn; // undefined template struct _Mem_fn<_Res _Class::*> : _Mem_fn_base<_Res _Class::*> { using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2048. Unnecessary mem_fn overloads /** * @brief Returns a function object that forwards to the member * pointer @a pm. * @ingroup functors */ template inline _Mem_fn<_Tp _Class::*> mem_fn(_Tp _Class::* __pm) noexcept { return _Mem_fn<_Tp _Class::*>(__pm); } /** * @brief Determines if the given type _Tp is a function object that * should be treated as a subexpression when evaluating calls to * function objects returned by bind(). * * C++11 [func.bind.isbind]. * @ingroup binders */ template struct is_bind_expression : public false_type { }; /** * @brief Determines if the given type _Tp is a placeholder in a * bind() expression and, if so, which placeholder it is. * * C++11 [func.bind.isplace]. * @ingroup binders */ template struct is_placeholder : public integral_constant { }; #if __cplusplus > 201402L template inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value; template inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value; #endif // C++17 /** @brief The type of placeholder objects defined by libstdc++. * @ingroup binders */ template struct _Placeholder { }; /** @namespace std::placeholders * @brief ISO C++11 entities sub-namespace for functional. * @ingroup binders */ namespace placeholders { /* Define a large number of placeholders. There is no way to * simplify this with variadic templates, because we're introducing * unique names for each. */ extern const _Placeholder<1> _1; extern const _Placeholder<2> _2; extern const _Placeholder<3> _3; extern const _Placeholder<4> _4; extern const _Placeholder<5> _5; extern const _Placeholder<6> _6; extern const _Placeholder<7> _7; extern const _Placeholder<8> _8; extern const _Placeholder<9> _9; extern const _Placeholder<10> _10; extern const _Placeholder<11> _11; extern const _Placeholder<12> _12; extern const _Placeholder<13> _13; extern const _Placeholder<14> _14; extern const _Placeholder<15> _15; extern const _Placeholder<16> _16; extern const _Placeholder<17> _17; extern const _Placeholder<18> _18; extern const _Placeholder<19> _19; extern const _Placeholder<20> _20; extern const _Placeholder<21> _21; extern const _Placeholder<22> _22; extern const _Placeholder<23> _23; extern const _Placeholder<24> _24; extern const _Placeholder<25> _25; extern const _Placeholder<26> _26; extern const _Placeholder<27> _27; extern const _Placeholder<28> _28; extern const _Placeholder<29> _29; } /** * Partial specialization of is_placeholder that provides the placeholder * number for the placeholder objects defined by libstdc++. * @ingroup binders */ template struct is_placeholder<_Placeholder<_Num> > : public integral_constant { }; template struct is_placeholder > : public integral_constant { }; // Like tuple_element_t but SFINAE-friendly. template using _Safe_tuple_element_t = typename enable_if<(__i < tuple_size<_Tuple>::value), tuple_element<__i, _Tuple>>::type::type; /** * Maps an argument to bind() into an actual argument to the bound * function object [func.bind.bind]/10. Only the first parameter should * be specified: the rest are used to determine among the various * implementations. Note that, although this class is a function * object, it isn't entirely normal because it takes only two * parameters regardless of the number of parameters passed to the * bind expression. The first parameter is the bound argument and * the second parameter is a tuple containing references to the * rest of the arguments. */ template::value, bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> class _Mu; /** * If the argument is reference_wrapper<_Tp>, returns the * underlying reference. * C++11 [func.bind.bind] p10 bullet 1. */ template class _Mu, false, false> { public: /* Note: This won't actually work for const volatile * reference_wrappers, because reference_wrapper::get() is const * but not volatile-qualified. This might be a defect in the TR. */ template _Tp& operator()(_CVRef& __arg, _Tuple&) const volatile { return __arg.get(); } }; /** * If the argument is a bind expression, we invoke the underlying * function object with the same cv-qualifiers as we are given and * pass along all of our arguments (unwrapped). * C++11 [func.bind.bind] p10 bullet 2. */ template class _Mu<_Arg, true, false> { public: template auto operator()(_CVArg& __arg, tuple<_Args...>& __tuple) const volatile -> decltype(__arg(declval<_Args>()...)) { // Construct an index tuple and forward to __call typedef typename _Build_index_tuple::__type _Indexes; return this->__call(__arg, __tuple, _Indexes()); } private: // Invokes the underlying function object __arg by unpacking all // of the arguments in the tuple. template auto __call(_CVArg& __arg, tuple<_Args...>& __tuple, const _Index_tuple<_Indexes...>&) const volatile -> decltype(__arg(declval<_Args>()...)) { return __arg(std::get<_Indexes>(std::move(__tuple))...); } }; /** * If the argument is a placeholder for the Nth argument, returns * a reference to the Nth argument to the bind function object. * C++11 [func.bind.bind] p10 bullet 3. */ template class _Mu<_Arg, false, true> { public: template _Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&& operator()(const volatile _Arg&, _Tuple& __tuple) const volatile { return ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple)); } }; /** * If the argument is just a value, returns a reference to that * value. The cv-qualifiers on the reference are determined by the caller. * C++11 [func.bind.bind] p10 bullet 4. */ template class _Mu<_Arg, false, false> { public: template _CVArg&& operator()(_CVArg&& __arg, _Tuple&) const volatile { return std::forward<_CVArg>(__arg); } }; // std::get for volatile-qualified tuples template inline auto __volget(volatile tuple<_Tp...>& __tuple) -> __tuple_element_t<_Ind, tuple<_Tp...>> volatile& { return std::get<_Ind>(const_cast&>(__tuple)); } // std::get for const-volatile-qualified tuples template inline auto __volget(const volatile tuple<_Tp...>& __tuple) -> __tuple_element_t<_Ind, tuple<_Tp...>> const volatile& { return std::get<_Ind>(const_cast&>(__tuple)); } /// Type of the function object returned from bind(). template struct _Bind; template class _Bind<_Functor(_Bound_args...)> : public _Weak_result_type<_Functor> { typedef typename _Build_index_tuple::__type _Bound_indexes; _Functor _M_f; tuple<_Bound_args...> _M_bound_args; // Call unqualified template _Result __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { return std::__invoke(_M_f, _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... ); } // Call as const template _Result __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { return std::__invoke(_M_f, _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... ); } // Call as volatile template _Result __call_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { return std::__invoke(_M_f, _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... ); } // Call as const volatile template _Result __call_c_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { return std::__invoke(_M_f, _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... ); } template using _Mu_type = decltype( _Mu::type>()( std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) ); template using _Res_type_impl = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>&&...) >::type; template using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>; template using __dependent = typename enable_if::value+1), _Functor>::type; template class __cv_quals> using _Res_type_cv = _Res_type_impl< typename __cv_quals<__dependent<_CallArgs>>::type, _CallArgs, typename __cv_quals<_Bound_args>::type...>; public: template explicit _Bind(const _Functor& __f, _Args&&... __args) : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) { } template explicit _Bind(_Functor&& __f, _Args&&... __args) : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) { } _Bind(const _Bind&) = default; _Bind(_Bind&& __b) : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args)) { } // Call unqualified template>> _Result operator()(_Args&&... __args) { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const template, add_const>> _Result operator()(_Args&&... __args) const { return this->__call_c<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } #if __cplusplus > 201402L # define _GLIBCXX_DEPR_BIND \ [[deprecated("std::bind does not support volatile in C++17")]] #else # define _GLIBCXX_DEPR_BIND #endif // Call as volatile template, add_volatile>> _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) volatile { return this->__call_v<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const volatile template, add_cv>> _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) const volatile { return this->__call_c_v<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } }; /// Type of the function object returned from bind(). template struct _Bind_result; template class _Bind_result<_Result, _Functor(_Bound_args...)> { typedef typename _Build_index_tuple::__type _Bound_indexes; _Functor _M_f; tuple<_Bound_args...> _M_bound_args; // sfinae types template using __enable_if_void = typename enable_if{}>::type; template using __disable_if_void = typename enable_if{}, _Result>::type; // Call unqualified template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call unqualified, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as const template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as const, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as volatile template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as volatile, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as const volatile template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as const volatile, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } public: typedef _Result result_type; template explicit _Bind_result(const _Functor& __f, _Args&&... __args) : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) { } template explicit _Bind_result(_Functor&& __f, _Args&&... __args) : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) { } _Bind_result(const _Bind_result&) = default; _Bind_result(_Bind_result&& __b) : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args)) { } // Call unqualified template result_type operator()(_Args&&... __args) { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const template result_type operator()(_Args&&... __args) const { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as volatile template _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) volatile { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const volatile template _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) const volatile { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } }; #undef _GLIBCXX_DEPR_BIND /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression<_Bind<_Signature> > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression<_Bind_result<_Result, _Signature>> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; template struct _Bind_check_arity { }; template struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...> { static_assert(sizeof...(_BoundArgs) == sizeof...(_Args), "Wrong number of arguments for function"); }; template struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...> { static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args), "Wrong number of arguments for function"); }; template struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...> { using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity; using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs; static_assert(_Varargs::value ? sizeof...(_BoundArgs) >= _Arity::value + 1 : sizeof...(_BoundArgs) == _Arity::value + 1, "Wrong number of arguments for pointer-to-member"); }; // Trait type used to remove std::bind() from overload set via SFINAE // when first argument has integer type, so that std::bind() will // not be a better match than ::bind() from the BSD Sockets API. template::type> using __is_socketlike = __or_, is_enum<_Tp2>>; template struct _Bind_helper : _Bind_check_arity::type, _BoundArgs...> { typedef typename decay<_Func>::type __func_type; typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; }; // Partial specialization for is_socketlike == true, does not define // nested type so std::bind() will not participate in overload resolution // when the first argument might be a socket file descriptor. template struct _Bind_helper { }; /** * @brief Function template for std::bind. * @ingroup binders */ template inline typename _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bind_helper __helper_type; return typename __helper_type::type(std::forward<_Func>(__f), std::forward<_BoundArgs>(__args)...); } template struct _Bindres_helper : _Bind_check_arity::type, _BoundArgs...> { typedef typename decay<_Func>::type __functor_type; typedef _Bind_result<_Result, __functor_type(typename decay<_BoundArgs>::type...)> type; }; /** * @brief Function template for std::bind. * @ingroup binders */ template inline typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; return typename __helper_type::type(std::forward<_Func>(__f), std::forward<_BoundArgs>(__args)...); } #if __cplusplus >= 201402L /// Generalized negator. template class _Not_fn { template using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type; template static decltype(!std::declval<_Tp>()) _S_not() noexcept(noexcept(!std::declval<_Tp>())); public: template _Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { } _Not_fn(const _Not_fn& __fn) = default; _Not_fn(_Not_fn&& __fn) = default; ~_Not_fn() = default; // Macro to define operator() with given cv-qualifiers ref-qualifiers, // forwarding _M_fn and the function arguments with the same qualifiers, // and deducing the return type and exception-specification. #define _GLIBCXX_NOT_FN_CALL_OP( _QUALS ) \ template \ decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \ operator()(_Args&&... __args) _QUALS \ noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \ && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ { \ return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn), \ std::forward<_Args>(__args)...); \ } _GLIBCXX_NOT_FN_CALL_OP( & ) _GLIBCXX_NOT_FN_CALL_OP( const & ) _GLIBCXX_NOT_FN_CALL_OP( && ) _GLIBCXX_NOT_FN_CALL_OP( const && ) #undef _GLIBCXX_NOT_FN_CALL private: _Fn _M_fn; }; template struct __is_byte_like : false_type { }; template struct __is_byte_like<_Tp, equal_to<_Tp>> : __bool_constant::value> { }; template struct __is_byte_like<_Tp, equal_to> : __bool_constant::value> { }; #if __cplusplus >= 201703L // Declare std::byte (full definition is in ). enum class byte : unsigned char; template<> struct __is_byte_like> : true_type { }; template<> struct __is_byte_like> : true_type { }; #define __cpp_lib_not_fn 201603 /// [func.not_fn] Function template not_fn template inline auto not_fn(_Fn&& __fn) noexcept(std::is_nothrow_constructible, _Fn&&>::value) { return _Not_fn>{std::forward<_Fn>(__fn), 0}; } // Searchers #define __cpp_lib_boyer_moore_searcher 201603 template> class default_searcher { public: default_searcher(_ForwardIterator1 __pat_first, _ForwardIterator1 __pat_last, _BinaryPredicate __pred = _BinaryPredicate()) : _M_m(__pat_first, __pat_last, std::move(__pred)) { } template pair<_ForwardIterator2, _ForwardIterator2> operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const { _ForwardIterator2 __first_ret = std::search(__first, __last, std::get<0>(_M_m), std::get<1>(_M_m), std::get<2>(_M_m)); auto __ret = std::make_pair(__first_ret, __first_ret); if (__ret.first != __last) std::advance(__ret.second, std::distance(std::get<0>(_M_m), std::get<1>(_M_m))); return __ret; } private: tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; }; template struct __boyer_moore_map_base { template __boyer_moore_map_base(_RAIter __pat, size_t __patlen, _Hash&& __hf, _Pred&& __pred) : _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) } { if (__patlen > 0) for (__diff_type __i = 0; __i < __patlen - 1; ++__i) _M_bad_char[__pat[__i]] = __patlen - 1 - __i; } using __diff_type = _Tp; __diff_type _M_lookup(_Key __key, __diff_type __not_found) const { auto __iter = _M_bad_char.find(__key); if (__iter == _M_bad_char.end()) return __not_found; return __iter->second; } _Pred _M_pred() const { return _M_bad_char.key_eq(); } _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char; }; template struct __boyer_moore_array_base { template __boyer_moore_array_base(_RAIter __pat, size_t __patlen, _Unused&&, _Pred&& __pred) : _M_bad_char{ _GLIBCXX_STD_C::array<_Tp, _Len>{}, std::move(__pred) } { std::get<0>(_M_bad_char).fill(__patlen); if (__patlen > 0) for (__diff_type __i = 0; __i < __patlen - 1; ++__i) { auto __ch = __pat[__i]; using _UCh = make_unsigned_t; auto __uch = static_cast<_UCh>(__ch); std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i; } } using __diff_type = _Tp; template __diff_type _M_lookup(_Key __key, __diff_type __not_found) const { auto __ukey = static_cast>(__key); if (__ukey >= _Len) return __not_found; return std::get<0>(_M_bad_char)[__ukey]; } const _Pred& _M_pred() const { return std::get<1>(_M_bad_char); } tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char; }; // Use __boyer_moore_array_base when pattern consists of narrow characters // (or std::byte) and uses std::equal_to as the predicate. template::value_type, typename _Diff = typename iterator_traits<_RAIter>::difference_type> using __boyer_moore_base_t = conditional_t<__is_byte_like<_Val, _Pred>::value, __boyer_moore_array_base<_Diff, 256, _Pred>, __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>; template::value_type>, typename _BinaryPredicate = equal_to<>> class boyer_moore_searcher : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> { using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; using typename _Base::__diff_type; public: boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()); template pair<_RandomAccessIterator2, _RandomAccessIterator2> operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const; private: bool _M_is_prefix(_RAIter __word, __diff_type __len, __diff_type __pos) { const auto& __pred = this->_M_pred(); __diff_type __suffixlen = __len - __pos; for (__diff_type __i = 0; __i < __suffixlen; ++__i) if (!__pred(__word[__i], __word[__pos + __i])) return false; return true; } __diff_type _M_suffix_length(_RAIter __word, __diff_type __len, __diff_type __pos) { const auto& __pred = this->_M_pred(); __diff_type __i = 0; while (__pred(__word[__pos - __i], __word[__len - 1 - __i]) && __i < __pos) { ++__i; } return __i; } template __diff_type _M_bad_char_shift(_Tp __c) const { return this->_M_lookup(__c, _M_pat_end - _M_pat); } _RAIter _M_pat; _RAIter _M_pat_end; _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix; }; template::value_type>, typename _BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> { using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; using typename _Base::__diff_type; public: boyer_moore_horspool_searcher(_RAIter __pat, _RAIter __pat_end, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), _M_pat(__pat), _M_pat_end(__pat_end) { } template pair<_RandomAccessIterator2, _RandomAccessIterator2> operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { const auto& __pred = this->_M_pred(); auto __patlen = _M_pat_end - _M_pat; if (__patlen == 0) return std::make_pair(__first, __first); auto __len = __last - __first; while (__len >= __patlen) { for (auto __scan = __patlen - 1; __pred(__first[__scan], _M_pat[__scan]); --__scan) if (__scan == 0) return std::make_pair(__first, __first + __patlen); auto __shift = _M_bad_char_shift(__first[__patlen - 1]); __len -= __shift; __first += __shift; } return std::make_pair(__last, __last); } private: template __diff_type _M_bad_char_shift(_Tp __c) const { return this->_M_lookup(__c, _M_pat_end - _M_pat); } _RAIter _M_pat; _RAIter _M_pat_end; }; template boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end, _Hash __hf, _BinaryPredicate __pred) : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat) { auto __patlen = __pat_end - __pat; if (__patlen == 0) return; __diff_type __last_prefix = __patlen - 1; for (__diff_type __p = __patlen - 1; __p >= 0; --__p) { if (_M_is_prefix(__pat, __patlen, __p + 1)) __last_prefix = __p + 1; _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p); } for (__diff_type __p = 0; __p < __patlen - 1; ++__p) { auto __slen = _M_suffix_length(__pat, __patlen, __p); auto __pos = __patlen - 1 - __slen; if (!__pred(__pat[__p - __slen], __pat[__pos])) _M_good_suffix[__pos] = __patlen - 1 - __p + __slen; } } template template pair<_RandomAccessIterator2, _RandomAccessIterator2> boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { auto __patlen = _M_pat_end - _M_pat; if (__patlen == 0) return std::make_pair(__first, __first); const auto& __pred = this->_M_pred(); __diff_type __i = __patlen - 1; auto __stringlen = __last - __first; while (__i < __stringlen) { __diff_type __j = __patlen - 1; while (__j >= 0 && __pred(__first[__i], _M_pat[__j])) { --__i; --__j; } if (__j < 0) { const auto __match = __first + __i + 1; return std::make_pair(__match, __match + __patlen); } __i += std::max(_M_bad_char_shift(__first[__i]), _M_good_suffix[__j]); } return std::make_pair(__last, __last); } #endif // C++17 #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_FUNCTIONAL PKgd1]>LL 8/cstdargnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cstdarg * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stdarg.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #undef __need___va_list #include #include #ifndef _GLIBCXX_CSTDARG #define _GLIBCXX_CSTDARG 1 // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef va_end #define va_end(ap) va_end (ap) #endif namespace std { using ::va_list; } // namespace std #endif PKgd1]p""8/condition_variablenu[// -*- C++ -*- // Copyright (C) 2008-2018 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/condition_variable * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CONDITION_VARIABLE #define _GLIBCXX_CONDITION_VARIABLE 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #include #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup condition_variables Condition Variables * @ingroup concurrency * * Classes for condition_variable support. * @{ */ /// cv_status enum class cv_status { no_timeout, timeout }; /// condition_variable class condition_variable { typedef chrono::system_clock __clock_t; typedef __gthread_cond_t __native_type; #ifdef __GTHREAD_COND_INIT __native_type _M_cond = __GTHREAD_COND_INIT; #else __native_type _M_cond; #endif public: typedef __native_type* native_handle_type; condition_variable() noexcept; ~condition_variable() noexcept; condition_variable(const condition_variable&) = delete; condition_variable& operator=(const condition_variable&) = delete; void notify_one() noexcept; void notify_all() noexcept; void wait(unique_lock& __lock) noexcept; template void wait(unique_lock& __lock, _Predicate __p) { while (!__p()) wait(__lock); } template cv_status wait_until(unique_lock& __lock, const chrono::time_point<__clock_t, _Duration>& __atime) { return __wait_until_impl(__lock, __atime); } template cv_status wait_until(unique_lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; const auto __s_atime = __s_entry + __delta; return __wait_until_impl(__lock, __s_atime); } template bool wait_until(unique_lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime, _Predicate __p) { while (!__p()) if (wait_until(__lock, __atime) == cv_status::timeout) return __p(); return true; } template cv_status wait_for(unique_lock& __lock, const chrono::duration<_Rep, _Period>& __rtime) { using __dur = typename __clock_t::duration; auto __reltime = chrono::duration_cast<__dur>(__rtime); if (__reltime < __rtime) ++__reltime; return wait_until(__lock, __clock_t::now() + __reltime); } template bool wait_for(unique_lock& __lock, const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) { using __dur = typename __clock_t::duration; auto __reltime = chrono::duration_cast<__dur>(__rtime); if (__reltime < __rtime) ++__reltime; return wait_until(__lock, __clock_t::now() + __reltime, std::move(__p)); } native_handle_type native_handle() { return &_M_cond; } private: template cv_status __wait_until_impl(unique_lock& __lock, const chrono::time_point<__clock_t, _Dur>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(), &__ts); return (__clock_t::now() < __atime ? cv_status::no_timeout : cv_status::timeout); } }; void notify_all_at_thread_exit(condition_variable&, unique_lock); struct __at_thread_exit_elt { __at_thread_exit_elt* _M_next; void (*_M_cb)(void*); }; inline namespace _V2 { /// condition_variable_any // Like above, but mutex is not required to have try_lock. class condition_variable_any { typedef chrono::system_clock __clock_t; condition_variable _M_cond; shared_ptr _M_mutex; // scoped unlock - unlocks in ctor, re-locks in dtor template struct _Unlock { explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); } ~_Unlock() noexcept(false) { if (uncaught_exception()) { __try { _M_lock.lock(); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; } __catch(...) { } } else _M_lock.lock(); } _Unlock(const _Unlock&) = delete; _Unlock& operator=(const _Unlock&) = delete; _Lock& _M_lock; }; public: condition_variable_any() : _M_mutex(std::make_shared()) { } ~condition_variable_any() = default; condition_variable_any(const condition_variable_any&) = delete; condition_variable_any& operator=(const condition_variable_any&) = delete; void notify_one() noexcept { lock_guard __lock(*_M_mutex); _M_cond.notify_one(); } void notify_all() noexcept { lock_guard __lock(*_M_mutex); _M_cond.notify_all(); } template void wait(_Lock& __lock) { shared_ptr __mutex = _M_mutex; unique_lock __my_lock(*__mutex); _Unlock<_Lock> __unlock(__lock); // *__mutex must be unlocked before re-locking __lock so move // ownership of *__mutex lock to an object with shorter lifetime. unique_lock __my_lock2(std::move(__my_lock)); _M_cond.wait(__my_lock2); } template void wait(_Lock& __lock, _Predicate __p) { while (!__p()) wait(__lock); } template cv_status wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime) { shared_ptr __mutex = _M_mutex; unique_lock __my_lock(*__mutex); _Unlock<_Lock> __unlock(__lock); // *__mutex must be unlocked before re-locking __lock so move // ownership of *__mutex lock to an object with shorter lifetime. unique_lock __my_lock2(std::move(__my_lock)); return _M_cond.wait_until(__my_lock2, __atime); } template bool wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime, _Predicate __p) { while (!__p()) if (wait_until(__lock, __atime) == cv_status::timeout) return __p(); return true; } template cv_status wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime) { return wait_until(__lock, __clock_t::now() + __rtime); } template bool wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); } }; } // end inline namespace // @} group condition_variables _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_CONDITION_VARIABLE PKgd1] M&rr 8/variantnu[// -*- C++ -*- // Copyright (C) 2016-2018 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 variant * This is the C++ Library header. */ #ifndef _GLIBCXX_VARIANT #define _GLIBCXX_VARIANT 1 #pragma GCC system_header #if __cplusplus >= 201703L #include #include #include #include #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { namespace __variant { template struct _Nth_type; template struct _Nth_type<_Np, _First, _Rest...> : _Nth_type<_Np-1, _Rest...> { }; template struct _Nth_type<0, _First, _Rest...> { using type = _First; }; } // namespace __variant } // namespace __detail #define __cpp_lib_variant 201606L template class tuple; template class variant; template struct hash; template struct variant_size; template struct variant_size : variant_size<_Variant> {}; template struct variant_size : variant_size<_Variant> {}; template struct variant_size : variant_size<_Variant> {}; template struct variant_size> : std::integral_constant {}; template inline constexpr size_t variant_size_v = variant_size<_Variant>::value; template struct variant_alternative; template struct variant_alternative<_Np, variant<_First, _Rest...>> : variant_alternative<_Np-1, variant<_Rest...>> {}; template struct variant_alternative<0, variant<_First, _Rest...>> { using type = _First; }; template using variant_alternative_t = typename variant_alternative<_Np, _Variant>::type; template struct variant_alternative<_Np, const _Variant> { using type = add_const_t>; }; template struct variant_alternative<_Np, volatile _Variant> { using type = add_volatile_t>; }; template struct variant_alternative<_Np, const volatile _Variant> { using type = add_cv_t>; }; inline constexpr size_t variant_npos = -1; template constexpr variant_alternative_t<_Np, variant<_Types...>>& get(variant<_Types...>&); template constexpr variant_alternative_t<_Np, variant<_Types...>>&& get(variant<_Types...>&&); template constexpr variant_alternative_t<_Np, variant<_Types...>> const& get(const variant<_Types...>&); template constexpr variant_alternative_t<_Np, variant<_Types...>> const&& get(const variant<_Types...>&&); namespace __detail { namespace __variant { // Returns the first apparence of _Tp in _Types. // Returns sizeof...(_Types) if _Tp is not in _Types. template struct __index_of : std::integral_constant {}; template inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value; template struct __index_of<_Tp, _First, _Rest...> : std::integral_constant ? 0 : __index_of_v<_Tp, _Rest...> + 1> {}; // _Uninitialized is guaranteed to be a literal type, even if T is not. // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented // yet. When it's implemented, _Uninitialized can be changed to the alias // to T, therefore equivalent to being removed entirely. // // Another reason we may not want to remove _Uninitialzied may be that, we // want _Uninitialized to be trivially destructible, no matter whether T // is; but we will see. template> struct _Uninitialized; template struct _Uninitialized<_Type, true> { template constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args) : _M_storage(std::forward<_Args>(__args)...) { } constexpr const _Type& _M_get() const & { return _M_storage; } constexpr _Type& _M_get() & { return _M_storage; } constexpr const _Type&& _M_get() const && { return std::move(_M_storage); } constexpr _Type&& _M_get() && { return std::move(_M_storage); } _Type _M_storage; }; template struct _Uninitialized<_Type, false> { template constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args) { ::new (&_M_storage) _Type(std::forward<_Args>(__args)...); } const _Type& _M_get() const & { return *_M_storage._M_ptr(); } _Type& _M_get() & { return *_M_storage._M_ptr(); } const _Type&& _M_get() const && { return std::move(*_M_storage._M_ptr()); } _Type&& _M_get() && { return std::move(*_M_storage._M_ptr()); } __gnu_cxx::__aligned_membuf<_Type> _M_storage; }; template _Ref __ref_cast(void* __ptr) { return static_cast<_Ref>(*static_cast*>(__ptr)); } template constexpr decltype(auto) __get(in_place_index_t<0>, _Union&& __u) { return std::forward<_Union>(__u)._M_first._M_get(); } template constexpr decltype(auto) __get(in_place_index_t<_Np>, _Union&& __u) { return __variant::__get(in_place_index<_Np-1>, std::forward<_Union>(__u)._M_rest); } // Returns the typed storage for __v. template constexpr decltype(auto) __get(_Variant&& __v) { return __variant::__get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u); } // Various functions as "vtable" entries, where those vtables are used by // polymorphic operations. template void __erased_ctor(void* __lhs, void* __rhs) { using _Type = remove_reference_t<_Lhs>; ::new (__lhs) _Type(__variant::__ref_cast<_Rhs>(__rhs)); } template void __erased_dtor(_Variant&& __v) { std::_Destroy(std::__addressof(__variant::__get<_Np>(__v))); } template void __erased_assign(void* __lhs, void* __rhs) { __variant::__ref_cast<_Lhs>(__lhs) = __variant::__ref_cast<_Rhs>(__rhs); } template void __erased_swap(void* __lhs, void* __rhs) { using std::swap; swap(__variant::__ref_cast<_Lhs>(__lhs), __variant::__ref_cast<_Rhs>(__rhs)); } #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ template \ constexpr bool \ __erased_##__NAME(const _Variant& __lhs, const _Variant& __rhs) \ { \ return __variant::__get<_Np>(std::forward<_Variant>(__lhs)) \ __OP __variant::__get<_Np>(std::forward<_Variant>(__rhs)); \ } _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE template size_t __erased_hash(void* __t) { return std::hash>>{}( __variant::__ref_cast<_Tp>(__t)); } template struct _Traits { static constexpr bool _S_default_ctor = is_default_constructible_v::type>; static constexpr bool _S_copy_ctor = (is_copy_constructible_v<_Types> && ...); static constexpr bool _S_move_ctor = (is_move_constructible_v<_Types> && ...); static constexpr bool _S_copy_assign = _S_copy_ctor && _S_move_ctor && (is_copy_assignable_v<_Types> && ...); static constexpr bool _S_move_assign = _S_move_ctor && (is_move_assignable_v<_Types> && ...); static constexpr bool _S_trivial_dtor = (is_trivially_destructible_v<_Types> && ...); static constexpr bool _S_trivial_copy_ctor = (is_trivially_copy_constructible_v<_Types> && ...); static constexpr bool _S_trivial_move_ctor = (is_trivially_move_constructible_v<_Types> && ...); static constexpr bool _S_trivial_copy_assign = _S_trivial_dtor && (is_trivially_copy_assignable_v<_Types> && ...); static constexpr bool _S_trivial_move_assign = _S_trivial_dtor && (is_trivially_move_assignable_v<_Types> && ...); // The following nothrow traits are for non-trivial SMFs. Trivial SMFs // are always nothrow. static constexpr bool _S_nothrow_default_ctor = is_nothrow_default_constructible_v< typename _Nth_type<0, _Types...>::type>; static constexpr bool _S_nothrow_copy_ctor = false; static constexpr bool _S_nothrow_move_ctor = (is_nothrow_move_constructible_v<_Types> && ...); static constexpr bool _S_nothrow_copy_assign = false; static constexpr bool _S_nothrow_move_assign = _S_nothrow_move_ctor && (is_nothrow_move_assignable_v<_Types> && ...); }; // Defines members and ctors. template union _Variadic_union { }; template union _Variadic_union<_First, _Rest...> { constexpr _Variadic_union() : _M_rest() { } template constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args) : _M_first(in_place_index<0>, std::forward<_Args>(__args)...) { } template constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args) : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...) { } _Uninitialized<_First> _M_first; _Variadic_union<_Rest...> _M_rest; }; // Defines index and the dtor, possibly trivial. template struct _Variant_storage; template using __select_index = typename __select_int::_Select_int_base::type::value_type; template struct _Variant_storage { template static constexpr void (*_S_vtable[])(const _Variant_storage&) = { &__erased_dtor... }; constexpr _Variant_storage() : _M_index(variant_npos) { } template constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), _M_index(_Np) { } template constexpr void _M_reset_impl(std::index_sequence<__indices...>) { if (_M_index != __index_type(variant_npos)) _S_vtable<__indices...>[_M_index](*this); } void _M_reset() { _M_reset_impl(std::index_sequence_for<_Types...>{}); _M_index = variant_npos; } ~_Variant_storage() { _M_reset(); } void* _M_storage() const { return const_cast(static_cast( std::addressof(_M_u))); } constexpr bool _M_valid() const noexcept { return this->_M_index != __index_type(variant_npos); } _Variadic_union<_Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; template struct _Variant_storage { constexpr _Variant_storage() : _M_index(variant_npos) { } template constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), _M_index(_Np) { } void _M_reset() { _M_index = variant_npos; } void* _M_storage() const { return const_cast(static_cast( std::addressof(_M_u))); } constexpr bool _M_valid() const noexcept { return this->_M_index != __index_type(variant_npos); } _Variadic_union<_Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; template using _Variant_storage_alias = _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>; // The following are (Copy|Move) (ctor|assign) layers for forwarding // triviality and handling non-trivial SMF behaviors. template struct _Copy_ctor_base : _Variant_storage_alias<_Types...> { using _Base = _Variant_storage_alias<_Types...>; using _Base::_Base; _Copy_ctor_base(const _Copy_ctor_base& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_ctor<_Types&, const _Types&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); this->_M_index = __rhs._M_index; } } _Copy_ctor_base(_Copy_ctor_base&&) = default; _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default; _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default; }; template struct _Copy_ctor_base : _Variant_storage_alias<_Types...> { using _Base = _Variant_storage_alias<_Types...>; using _Base::_Base; }; template using _Copy_ctor_alias = _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>; template struct _Move_ctor_base : _Copy_ctor_alias<_Types...> { using _Base = _Copy_ctor_alias<_Types...>; using _Base::_Base; _Move_ctor_base(_Move_ctor_base&& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_move_ctor) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_ctor<_Types&, _Types&&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); this->_M_index = __rhs._M_index; } } void _M_destructive_move(_Move_ctor_base&& __rhs) { this->~_Move_ctor_base(); __try { ::new (this) _Move_ctor_base(std::move(__rhs)); } __catch (...) { this->_M_index = variant_npos; __throw_exception_again; } } _Move_ctor_base(const _Move_ctor_base&) = default; _Move_ctor_base& operator=(const _Move_ctor_base&) = default; _Move_ctor_base& operator=(_Move_ctor_base&&) = default; }; template struct _Move_ctor_base : _Copy_ctor_alias<_Types...> { using _Base = _Copy_ctor_alias<_Types...>; using _Base::_Base; void _M_destructive_move(_Move_ctor_base&& __rhs) { this->~_Move_ctor_base(); ::new (this) _Move_ctor_base(std::move(__rhs)); } }; template using _Move_ctor_alias = _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>; template struct _Copy_assign_base : _Move_ctor_alias<_Types...> { using _Base = _Move_ctor_alias<_Types...>; using _Base::_Base; _Copy_assign_base& operator=(const _Copy_assign_base& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_copy_assign) { if (this->_M_index == __rhs._M_index) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_assign<_Types&, const _Types&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); } } else { _Copy_assign_base __tmp(__rhs); this->_M_destructive_move(std::move(__tmp)); } __glibcxx_assert(this->_M_index == __rhs._M_index); return *this; } _Copy_assign_base(const _Copy_assign_base&) = default; _Copy_assign_base(_Copy_assign_base&&) = default; _Copy_assign_base& operator=(_Copy_assign_base&&) = default; }; template struct _Copy_assign_base : _Move_ctor_alias<_Types...> { using _Base = _Move_ctor_alias<_Types...>; using _Base::_Base; }; template using _Copy_assign_alias = _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>; template struct _Move_assign_base : _Copy_assign_alias<_Types...> { using _Base = _Copy_assign_alias<_Types...>; using _Base::_Base; _Move_assign_base& operator=(_Move_assign_base&& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_move_assign) { if (this->_M_index == __rhs._M_index) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_assign<_Types&, _Types&&>... }; _S_vtable[__rhs._M_index] (this->_M_storage(), __rhs._M_storage()); } } else { _Move_assign_base __tmp(std::move(__rhs)); this->_M_destructive_move(std::move(__tmp)); } __glibcxx_assert(this->_M_index == __rhs._M_index); return *this; } _Move_assign_base(const _Move_assign_base&) = default; _Move_assign_base(_Move_assign_base&&) = default; _Move_assign_base& operator=(const _Move_assign_base&) = default; }; template struct _Move_assign_base : _Copy_assign_alias<_Types...> { using _Base = _Copy_assign_alias<_Types...>; using _Base::_Base; }; template using _Move_assign_alias = _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>; template struct _Variant_base : _Move_assign_alias<_Types...> { using _Base = _Move_assign_alias<_Types...>; constexpr _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor) : _Variant_base(in_place_index<0>) { } template constexpr explicit _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args) : _Base(__i, std::forward<_Args>(__args)...) { } _Variant_base(const _Variant_base&) = default; _Variant_base(_Variant_base&&) = default; _Variant_base& operator=(const _Variant_base&) = default; _Variant_base& operator=(_Variant_base&&) = default; }; // For how many times does _Tp appear in _Tuple? template struct __tuple_count; template inline constexpr size_t __tuple_count_v = __tuple_count<_Tp, _Tuple>::value; template struct __tuple_count<_Tp, tuple<_Types...>> : integral_constant { }; template struct __tuple_count<_Tp, tuple<_First, _Rest...>> : integral_constant< size_t, __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { }; // TODO: Reuse this in ? template inline constexpr bool __exactly_once = __tuple_count_v<_Tp, tuple<_Types...>> == 1; // Takes _Types and create an overloaded _S_fun for each type. // If a type appears more than once in _Types, create only one overload. template struct __overload_set { static void _S_fun(); }; template struct __overload_set<_First, _Rest...> : __overload_set<_Rest...> { using __overload_set<_Rest...>::_S_fun; static integral_constant _S_fun(_First); }; template struct __overload_set : __overload_set<_Rest...> { using __overload_set<_Rest...>::_S_fun; }; // Helper for variant(_Tp&&) and variant::operator=(_Tp&&). // __accepted_index maps the arbitrary _Tp to an alternative type in _Variant. template struct __accepted_index { static constexpr size_t value = variant_npos; }; template struct __accepted_index< _Tp, variant<_Types...>, decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()), std::declval())> { static constexpr size_t value = sizeof...(_Types) - 1 - decltype(__overload_set<_Types...>:: _S_fun(std::declval<_Tp>()))::value; }; // Returns the raw storage for __v. template void* __get_storage(_Variant&& __v) { return __v._M_storage(); } // Used for storing multi-dimensional vtable. template struct _Multi_array { constexpr const _Tp& _M_access() const { return _M_data; } _Tp _M_data; }; template struct _Multi_array<_Tp, __first, __rest...> { template constexpr const _Tp& _M_access(size_t __first_index, _Args... __rest_indices) const { return _M_arr[__first_index]._M_access(__rest_indices...); } _Multi_array<_Tp, __rest...> _M_arr[__first]; }; // Creates a multi-dimensional vtable recursively. // // For example, // visit([](auto, auto){}, // variant(), // typedef'ed as V1 // variant()) // typedef'ed as V2 // will trigger instantiations of: // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0, 0>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0, 1>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0, 2>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1, 0>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1, 1>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1, 2>> // The returned multi-dimensional vtable can be fast accessed by the visitor // using index calculation. template struct __gen_vtable_impl; template struct __gen_vtable_impl< _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>, tuple<_Variants...>, std::index_sequence<__indices...>> { using _Next = remove_reference_t::type>; using _Array_type = _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>; static constexpr _Array_type _S_apply() { _Array_type __vtable{}; _S_apply_all_alts( __vtable, make_index_sequence>()); return __vtable; } template static constexpr void _S_apply_all_alts(_Array_type& __vtable, std::index_sequence<__var_indices...>) { (_S_apply_single_alt<__var_indices>( __vtable._M_arr[__var_indices]), ...); } template static constexpr void _S_apply_single_alt(_Tp& __element) { using _Alternative = variant_alternative_t<__index, _Next>; __element = __gen_vtable_impl< remove_reference_t, tuple<_Variants...>, std::index_sequence<__indices..., __index>>::_S_apply(); } }; template struct __gen_vtable_impl< _Multi_array<_Result_type (*)(_Visitor, _Variants...)>, tuple<_Variants...>, std::index_sequence<__indices...>> { using _Array_type = _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>; static constexpr decltype(auto) __visit_invoke(_Visitor&& __visitor, _Variants... __vars) { return std::__invoke(std::forward<_Visitor>(__visitor), __variant::__get<__indices>(std::forward<_Variants>(__vars))...); } static constexpr auto _S_apply() { return _Array_type{&__visit_invoke}; } }; template struct __gen_vtable { using _Func_ptr = _Result_type (*)(_Visitor&&, _Variants...); using _Array_type = _Multi_array<_Func_ptr, variant_size_v>...>; static constexpr _Array_type _S_apply() { return __gen_vtable_impl<_Array_type, tuple<_Variants...>, std::index_sequence<>>::_S_apply(); } static constexpr auto _S_vtable = _S_apply(); }; template struct _Base_dedup : public _Tp { }; template struct _Variant_hash_base; template struct _Variant_hash_base, std::index_sequence<__indices...>> : _Base_dedup<__indices, __poison_hash>>... { }; } // namespace __variant } // namespace __detail template constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>; } template constexpr _Tp& get(variant<_Types...>& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); } template constexpr _Tp&& get(variant<_Types...>&& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( std::move(__v)); } template constexpr const _Tp& get(const variant<_Types...>& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); } template constexpr const _Tp&& get(const variant<_Types...>&& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( std::move(__v)); } template constexpr add_pointer_t>> get_if(variant<_Types...>* __ptr) noexcept { using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void"); if (__ptr && __ptr->index() == _Np) return &__detail::__variant::__get<_Np>(*__ptr); return nullptr; } template constexpr add_pointer_t>> get_if(const variant<_Types...>* __ptr) noexcept { using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void"); if (__ptr && __ptr->index() == _Np) return &__detail::__variant::__get<_Np>(*__ptr); return nullptr; } template constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __ptr) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( __ptr); } template constexpr add_pointer_t get_if(const variant<_Types...>* __ptr) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( __ptr); } struct monostate { }; #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ template \ constexpr bool operator __OP(const variant<_Types...>& __lhs, \ const variant<_Types...>& __rhs) \ { \ return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \ } \ \ constexpr bool operator __OP(monostate, monostate) noexcept \ { return 0 __OP 0; } _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE template constexpr decltype(auto) visit(_Visitor&&, _Variants&&...); template inline enable_if_t<(is_move_constructible_v<_Types> && ...) && (is_swappable_v<_Types> && ...)> swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } template enable_if_t && ...) && (is_swappable_v<_Types> && ...))> swap(variant<_Types...>&, variant<_Types...>&) = delete; class bad_variant_access : public exception { public: bad_variant_access() noexcept : _M_reason("Unknown reason") { } const char* what() const noexcept override { return _M_reason; } private: bad_variant_access(const char* __reason) : _M_reason(__reason) { } const char* _M_reason; friend void __throw_bad_variant_access(const char* __what); }; inline void __throw_bad_variant_access(const char* __what) { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); } template class variant : private __detail::__variant::_Variant_base<_Types...>, private _Enable_default_constructor< __detail::__variant::_Traits<_Types...>::_S_default_ctor, variant<_Types...>>, private _Enable_copy_move< __detail::__variant::_Traits<_Types...>::_S_copy_ctor, __detail::__variant::_Traits<_Types...>::_S_copy_assign, __detail::__variant::_Traits<_Types...>::_S_move_ctor, __detail::__variant::_Traits<_Types...>::_S_move_assign, variant<_Types...>> { private: static_assert(sizeof...(_Types) > 0, "variant must have at least one alternative"); static_assert(!(std::is_reference_v<_Types> || ...), "variant must have no reference alternative"); static_assert(!(std::is_void_v<_Types> || ...), "variant must have no void alternative"); using _Base = __detail::__variant::_Variant_base<_Types...>; using _Default_ctor_enabler = _Enable_default_constructor< __detail::__variant::_Traits<_Types...>::_S_default_ctor, variant<_Types...>>; template static constexpr bool __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>; template static constexpr size_t __accepted_index = __detail::__variant::__accepted_index<_Tp&&, variant>::value; template struct __to_type_impl; template struct __to_type_impl<_Np, true> { using type = variant_alternative_t<_Np, variant>; }; template using __to_type = typename __to_type_impl<_Np>::type; template using __accepted_type = __to_type<__accepted_index<_Tp>>; template static constexpr size_t __index_of = __detail::__variant::__index_of_v<_Tp, _Types...>; using _Traits = __detail::__variant::_Traits<_Types...>; template struct __is_in_place_tag : false_type { }; template struct __is_in_place_tag> : true_type { }; template struct __is_in_place_tag> : true_type { }; template static constexpr bool __not_in_place_tag = !__is_in_place_tag>::value; public: variant() = default; variant(const variant& __rhs) = default; variant(variant&&) = default; variant& operator=(const variant&) = default; variant& operator=(variant&&) = default; ~variant() = default; template, variant>>, typename = enable_if_t<(sizeof...(_Types)>0)>, typename = enable_if_t<__not_in_place_tag<_Tp>>, typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>> && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>> constexpr variant(_Tp&& __t) noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>) : variant(in_place_index<__accepted_index<_Tp&&>>, std::forward<_Tp>(__t)) { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); } template && is_constructible_v<_Tp, _Args&&...>>> constexpr explicit variant(in_place_type_t<_Tp>, _Args&&... __args) : variant(in_place_index<__index_of<_Tp>>, std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template && is_constructible_v< _Tp, initializer_list<_Up>&, _Args&&...>>> constexpr explicit variant(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args) : variant(in_place_index<__index_of<_Tp>>, __il, std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template, _Args&&...>>> constexpr explicit variant(in_place_index_t<_Np>, _Args&&... __args) : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } template, initializer_list<_Up>&, _Args&&...>>> constexpr explicit variant(in_place_index_t<_Np>, initializer_list<_Up> __il, _Args&&... __args) : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } template enable_if_t<__exactly_once<__accepted_type<_Tp&&>> && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&> && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&> && !is_same_v, variant>, variant&> operator=(_Tp&& __rhs) noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&> && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>) { constexpr auto __index = __accepted_index<_Tp&&>; if (index() == __index) std::get<__index>(*this) = std::forward<_Tp>(__rhs); else this->emplace<__index>(std::forward<_Tp>(__rhs)); __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); return *this; } template enable_if_t && __exactly_once<_Tp>, _Tp&> emplace(_Args&&... __args) { auto& ret = this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...); __glibcxx_assert(holds_alternative<_Tp>(*this)); return ret; } template enable_if_t&, _Args...> && __exactly_once<_Tp>, _Tp&> emplace(initializer_list<_Up> __il, _Args&&... __args) { auto& ret = this->emplace<__index_of<_Tp>>(__il, std::forward<_Args>(__args)...); __glibcxx_assert(holds_alternative<_Tp>(*this)); return ret; } template enable_if_t, _Args...>, variant_alternative_t<_Np, variant>&> emplace(_Args&&... __args) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); this->~variant(); __try { ::new (this) variant(in_place_index<_Np>, std::forward<_Args>(__args)...); } __catch (...) { this->_M_index = variant_npos; __throw_exception_again; } __glibcxx_assert(index() == _Np); return std::get<_Np>(*this); } template enable_if_t, initializer_list<_Up>&, _Args...>, variant_alternative_t<_Np, variant>&> emplace(initializer_list<_Up> __il, _Args&&... __args) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); this->~variant(); __try { ::new (this) variant(in_place_index<_Np>, __il, std::forward<_Args>(__args)...); } __catch (...) { this->_M_index = variant_npos; __throw_exception_again; } __glibcxx_assert(index() == _Np); return std::get<_Np>(*this); } constexpr bool valueless_by_exception() const noexcept { return !this->_M_valid(); } constexpr size_t index() const noexcept { if (this->_M_index == typename _Base::__index_type(variant_npos)) return variant_npos; return this->_M_index; } void swap(variant& __rhs) noexcept((__is_nothrow_swappable<_Types>::value && ...) && is_nothrow_move_constructible_v) { if (this->index() == __rhs.index()) { if (this->_M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__detail::__variant::__erased_swap<_Types&, _Types&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); } } else if (!this->_M_valid()) { this->_M_destructive_move(std::move(__rhs)); __rhs._M_reset(); } else if (!__rhs._M_valid()) { __rhs._M_destructive_move(std::move(*this)); this->_M_reset(); } else { auto __tmp = std::move(__rhs); __rhs._M_destructive_move(std::move(*this)); this->_M_destructive_move(std::move(__tmp)); } } private: #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ template \ static constexpr bool \ (*_S_erased_##__NAME[])(const variant&, const variant&) = \ { &__detail::__variant::__erased_##__NAME< \ const variant&, __indices>... }; \ template \ constexpr bool \ _M_##__NAME(const variant& __rhs, \ std::index_sequence<__indices...>) const \ { \ auto __lhs_index = this->index(); \ auto __rhs_index = __rhs.index(); \ if (__lhs_index != __rhs_index || valueless_by_exception()) \ /* Modulo addition. */ \ return __lhs_index + 1 __OP __rhs_index + 1; \ return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \ } _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE #ifdef __clang__ public: using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852 private: #endif template friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v); template friend void* __detail::__variant::__get_storage(_Vp&& __v); #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \ template \ friend constexpr bool \ operator __OP(const variant<_Tp...>& __lhs, \ const variant<_Tp...>& __rhs); _VARIANT_RELATION_FUNCTION_TEMPLATE(<) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=) _VARIANT_RELATION_FUNCTION_TEMPLATE(==) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=) _VARIANT_RELATION_FUNCTION_TEMPLATE(>) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE }; template constexpr variant_alternative_t<_Np, variant<_Types...>>& get(variant<_Types...>& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(__v); } template constexpr variant_alternative_t<_Np, variant<_Types...>>&& get(variant<_Types...>&& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(std::move(__v)); } template constexpr const variant_alternative_t<_Np, variant<_Types...>>& get(const variant<_Types...>& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(__v); } template constexpr const variant_alternative_t<_Np, variant<_Types...>>&& get(const variant<_Types...>&& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(std::move(__v)); } template constexpr decltype(auto) visit(_Visitor&& __visitor, _Variants&&... __variants) { if ((__variants.valueless_by_exception() || ...)) __throw_bad_variant_access("Unexpected index"); using _Result_type = decltype(std::forward<_Visitor>(__visitor)( std::get<0>(std::forward<_Variants>(__variants))...)); constexpr auto& __vtable = __detail::__variant::__gen_vtable< _Result_type, _Visitor&&, _Variants&&...>::_S_vtable; auto __func_ptr = __vtable._M_access(__variants.index()...); return (*__func_ptr)(std::forward<_Visitor>(__visitor), std::forward<_Variants>(__variants)...); } template struct __variant_hash_call_base_impl { size_t operator()(const variant<_Types...>& __t) const noexcept((is_nothrow_invocable_v>, _Types> && ...)) { if (!__t.valueless_by_exception()) { namespace __edv = __detail::__variant; static constexpr size_t (*_S_vtable[])(void*) = { &__edv::__erased_hash... }; return hash{}(__t.index()) + _S_vtable[__t.index()](__edv::__get_storage(__t)); } return hash{}(__t.index()); } }; template struct __variant_hash_call_base_impl {}; template using __variant_hash_call_base = __variant_hash_call_base_impl<(__poison_hash>:: __enable_hash_call &&...), _Types...>; template struct hash> : private __detail::__variant::_Variant_hash_base< variant<_Types...>, std::index_sequence_for<_Types...>>, public __variant_hash_call_base<_Types...> { using result_type [[__deprecated__]] = size_t; using argument_type [[__deprecated__]] = variant<_Types...>; }; template<> struct hash { using result_type [[__deprecated__]] = size_t; using argument_type [[__deprecated__]] = monostate; size_t operator()(const monostate& __t) const noexcept { constexpr size_t __magic_monostate_hash = -7777; return __magic_monostate_hash; } }; template struct __is_fast_hash>> : bool_constant<(__is_fast_hash<_Types>::value && ...)> { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_VARIANT PKgd1]N3MM8/rationu[// ratio -*- C++ -*- // Copyright (C) 2008-2018 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/ratio * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_RATIO #define _GLIBCXX_RATIO 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup ratio Rational Arithmetic * @ingroup utilities * * Compile time representation of finite rational numbers. * @{ */ template struct __static_sign : integral_constant { }; template struct __static_abs : integral_constant::value> { }; template struct __static_gcd : __static_gcd<_Qn, (_Pn % _Qn)> { }; template struct __static_gcd<_Pn, 0> : integral_constant::value> { }; template struct __static_gcd<0, _Qn> : integral_constant::value> { }; // Let c = 2^(half # of bits in an intmax_t) // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0 // The multiplication of N and M becomes, // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0 // Multiplication is safe if each term and the sum of the terms // is representable by intmax_t. template struct __safe_multiply { private: static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static const uintmax_t __a0 = __static_abs<_Pn>::value % __c; static const uintmax_t __a1 = __static_abs<_Pn>::value / __c; static const uintmax_t __b0 = __static_abs<_Qn>::value % __c; static const uintmax_t __b1 = __static_abs<_Qn>::value / __c; static_assert(__a1 == 0 || __b1 == 0, "overflow in multiplication"); static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1), "overflow in multiplication"); static_assert(__b0 * __a0 <= __INTMAX_MAX__, "overflow in multiplication"); static_assert((__a0 * __b1 + __b0 * __a1) * __c <= __INTMAX_MAX__ - __b0 * __a0, "overflow in multiplication"); public: static const intmax_t value = _Pn * _Qn; }; // Some double-precision utilities, where numbers are represented as // __hi*2^(8*sizeof(uintmax_t)) + __lo. template struct __big_less : integral_constant { }; template struct __big_add { static constexpr uintmax_t __lo = __lo1 + __lo2; static constexpr uintmax_t __hi = (__hi1 + __hi2 + (__lo1 + __lo2 < __lo1)); // carry }; // Subtract a number from a bigger one. template struct __big_sub { static_assert(!__big_less<__hi1, __lo1, __hi2, __lo2>::value, "Internal library error"); static constexpr uintmax_t __lo = __lo1 - __lo2; static constexpr uintmax_t __hi = (__hi1 - __hi2 - (__lo1 < __lo2)); // carry }; // Same principle as __safe_multiply. template struct __big_mul { private: static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static constexpr uintmax_t __x0 = __x % __c; static constexpr uintmax_t __x1 = __x / __c; static constexpr uintmax_t __y0 = __y % __c; static constexpr uintmax_t __y1 = __y / __c; static constexpr uintmax_t __x0y0 = __x0 * __y0; static constexpr uintmax_t __x0y1 = __x0 * __y1; static constexpr uintmax_t __x1y0 = __x1 * __y0; static constexpr uintmax_t __x1y1 = __x1 * __y1; static constexpr uintmax_t __mix = __x0y1 + __x1y0; // possible carry... static constexpr uintmax_t __mix_lo = __mix * __c; static constexpr uintmax_t __mix_hi = __mix / __c + ((__mix < __x0y1) ? __c : 0); // ... added here typedef __big_add<__mix_hi, __mix_lo, __x1y1, __x0y0> _Res; public: static constexpr uintmax_t __hi = _Res::__hi; static constexpr uintmax_t __lo = _Res::__lo; }; // Adapted from __udiv_qrnnd_c in longlong.h // This version assumes that the high bit of __d is 1. template struct __big_div_impl { private: static_assert(__d >= (uintmax_t(1) << (sizeof(intmax_t) * 8 - 1)), "Internal library error"); static_assert(__n1 < __d, "Internal library error"); static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static constexpr uintmax_t __d1 = __d / __c; static constexpr uintmax_t __d0 = __d % __c; static constexpr uintmax_t __q1x = __n1 / __d1; static constexpr uintmax_t __r1x = __n1 % __d1; static constexpr uintmax_t __m = __q1x * __d0; static constexpr uintmax_t __r1y = __r1x * __c + __n0 / __c; static constexpr uintmax_t __r1z = __r1y + __d; static constexpr uintmax_t __r1 = ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) ? (__r1z + __d) : __r1z : __r1y) - __m; static constexpr uintmax_t __q1 = __q1x - ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) ? 2 : 1 : 0); static constexpr uintmax_t __q0x = __r1 / __d1; static constexpr uintmax_t __r0x = __r1 % __d1; static constexpr uintmax_t __n = __q0x * __d0; static constexpr uintmax_t __r0y = __r0x * __c + __n0 % __c; static constexpr uintmax_t __r0z = __r0y + __d; static constexpr uintmax_t __r0 = ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) ? (__r0z + __d) : __r0z : __r0y) - __n; static constexpr uintmax_t __q0 = __q0x - ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) ? 2 : 1 : 0); public: static constexpr uintmax_t __quot = __q1 * __c + __q0; static constexpr uintmax_t __rem = __r0; private: typedef __big_mul<__quot, __d> _Prod; typedef __big_add<_Prod::__hi, _Prod::__lo, 0, __rem> _Sum; static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, "Internal library error"); }; template struct __big_div { private: static_assert(__d != 0, "Internal library error"); static_assert(sizeof (uintmax_t) == sizeof (unsigned long long), "This library calls __builtin_clzll on uintmax_t, which " "is unsafe on your platform. Please complain to " "http://gcc.gnu.org/bugzilla/"); static constexpr int __shift = __builtin_clzll(__d); static constexpr int __coshift_ = sizeof(uintmax_t) * 8 - __shift; static constexpr int __coshift = (__shift != 0) ? __coshift_ : 0; static constexpr uintmax_t __c1 = uintmax_t(1) << __shift; static constexpr uintmax_t __c2 = uintmax_t(1) << __coshift; static constexpr uintmax_t __new_d = __d * __c1; static constexpr uintmax_t __new_n0 = __n0 * __c1; static constexpr uintmax_t __n1_shifted = (__n1 % __d) * __c1; static constexpr uintmax_t __n0_top = (__shift != 0) ? (__n0 / __c2) : 0; static constexpr uintmax_t __new_n1 = __n1_shifted + __n0_top; typedef __big_div_impl<__new_n1, __new_n0, __new_d> _Res; public: static constexpr uintmax_t __quot_hi = __n1 / __d; static constexpr uintmax_t __quot_lo = _Res::__quot; static constexpr uintmax_t __rem = _Res::__rem / __c1; private: typedef __big_mul<__quot_lo, __d> _P0; typedef __big_mul<__quot_hi, __d> _P1; typedef __big_add<_P0::__hi, _P0::__lo, _P1::__lo, __rem> _Sum; // No overflow. static_assert(_P1::__hi == 0, "Internal library error"); static_assert(_Sum::__hi >= _P0::__hi, "Internal library error"); // Matches the input data. static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, "Internal library error"); static_assert(__rem < __d, "Internal library error"); }; /** * @brief Provides compile-time rational arithmetic. * * This class template represents any finite rational number with a * numerator and denominator representable by compile-time constants of * type intmax_t. The ratio is simplified when instantiated. * * For example: * @code * std::ratio<7,-21>::num == -1; * std::ratio<7,-21>::den == 3; * @endcode * */ template struct ratio { static_assert(_Den != 0, "denominator cannot be zero"); static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__, "out of range"); // Note: sign(N) * abs(N) == N static constexpr intmax_t num = _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value; static constexpr intmax_t den = __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value; typedef ratio type; }; template constexpr intmax_t ratio<_Num, _Den>::num; template constexpr intmax_t ratio<_Num, _Den>::den; template struct __ratio_multiply { private: static const intmax_t __gcd1 = __static_gcd<_R1::num, _R2::den>::value; static const intmax_t __gcd2 = __static_gcd<_R2::num, _R1::den>::value; public: typedef ratio< __safe_multiply<(_R1::num / __gcd1), (_R2::num / __gcd2)>::value, __safe_multiply<(_R1::den / __gcd2), (_R2::den / __gcd1)>::value> type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_multiply<_R1, _R2>::num; template constexpr intmax_t __ratio_multiply<_R1, _R2>::den; /// ratio_multiply template using ratio_multiply = typename __ratio_multiply<_R1, _R2>::type; template struct __ratio_divide { static_assert(_R2::num != 0, "division by 0"); typedef typename __ratio_multiply< _R1, ratio<_R2::den, _R2::num>>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_divide<_R1, _R2>::num; template constexpr intmax_t __ratio_divide<_R1, _R2>::den; /// ratio_divide template using ratio_divide = typename __ratio_divide<_R1, _R2>::type; /// ratio_equal template struct ratio_equal : integral_constant { }; /// ratio_not_equal template struct ratio_not_equal : integral_constant::value> { }; // Both numbers are positive. template, typename _Right = __big_mul<_R2::num,_R1::den> > struct __ratio_less_impl_1 : integral_constant::value> { }; template::value != __static_sign<_R2::num>::value)), bool = (__static_sign<_R1::num>::value == -1 && __static_sign<_R2::num>::value == -1)> struct __ratio_less_impl : __ratio_less_impl_1<_R1, _R2>::type { }; template struct __ratio_less_impl<_R1, _R2, true, false> : integral_constant { }; template struct __ratio_less_impl<_R1, _R2, false, true> : __ratio_less_impl_1, ratio<-_R1::num, _R1::den> >::type { }; /// ratio_less template struct ratio_less : __ratio_less_impl<_R1, _R2>::type { }; /// ratio_less_equal template struct ratio_less_equal : integral_constant::value> { }; /// ratio_greater template struct ratio_greater : integral_constant::value> { }; /// ratio_greater_equal template struct ratio_greater_equal : integral_constant::value> { }; #if __cplusplus > 201402L template inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value; template inline constexpr bool ratio_not_equal_v = ratio_not_equal<_R1, _R2>::value; template inline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value; template inline constexpr bool ratio_less_equal_v = ratio_less_equal<_R1, _R2>::value; template inline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value; template inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<_R1, _R2>::value; #endif // C++17 template= 0), bool = (_R2::num >= 0), bool = ratio_less::value, _R1::den>, ratio<__static_abs<_R2::num>::value, _R2::den> >::value> struct __ratio_add_impl { private: typedef typename __ratio_add_impl< ratio<-_R1::num, _R1::den>, ratio<-_R2::num, _R2::den> >::type __t; public: typedef ratio<-__t::num, __t::den> type; }; // True addition of nonnegative numbers. template struct __ratio_add_impl<_R1, _R2, true, true, __b> { private: static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; static constexpr uintmax_t __d2 = _R2::den / __g; typedef __big_mul<_R1::den, __d2> __d; typedef __big_mul<_R1::num, _R2::den / __g> __x; typedef __big_mul<_R2::num, _R1::den / __g> __y; typedef __big_add<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; static_assert(__n::__hi >= __x::__hi, "Internal library error"); typedef __big_div<__n::__hi, __n::__lo, __g> __ng; static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; static_assert(__n_final::__rem == 0, "Internal library error"); static_assert(__n_final::__quot_hi == 0 && __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); typedef __big_mul<_R1::den / __g2, __d2> __d_final; static_assert(__d_final::__hi == 0 && __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); public: typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; }; template struct __ratio_add_impl<_R1, _R2, false, true, true> : __ratio_add_impl<_R2, _R1> { }; // True subtraction of nonnegative numbers yielding a nonnegative result. template struct __ratio_add_impl<_R1, _R2, true, false, false> { private: static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; static constexpr uintmax_t __d2 = _R2::den / __g; typedef __big_mul<_R1::den, __d2> __d; typedef __big_mul<_R1::num, _R2::den / __g> __x; typedef __big_mul<-_R2::num, _R1::den / __g> __y; typedef __big_sub<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; typedef __big_div<__n::__hi, __n::__lo, __g> __ng; static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; static_assert(__n_final::__rem == 0, "Internal library error"); static_assert(__n_final::__quot_hi == 0 && __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); typedef __big_mul<_R1::den / __g2, __d2> __d_final; static_assert(__d_final::__hi == 0 && __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); public: typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; }; template struct __ratio_add { typedef typename __ratio_add_impl<_R1, _R2>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_add<_R1, _R2>::num; template constexpr intmax_t __ratio_add<_R1, _R2>::den; /// ratio_add template using ratio_add = typename __ratio_add<_R1, _R2>::type; template struct __ratio_subtract { typedef typename __ratio_add< _R1, ratio<-_R2::num, _R2::den>>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_subtract<_R1, _R2>::num; template constexpr intmax_t __ratio_subtract<_R1, _R2>::den; /// ratio_subtract template using ratio_subtract = typename __ratio_subtract<_R1, _R2>::type; typedef ratio<1, 1000000000000000000> atto; typedef ratio<1, 1000000000000000> femto; typedef ratio<1, 1000000000000> pico; typedef ratio<1, 1000000000> nano; typedef ratio<1, 1000000> micro; typedef ratio<1, 1000> milli; typedef ratio<1, 100> centi; typedef ratio<1, 10> deci; typedef ratio< 10, 1> deca; typedef ratio< 100, 1> hecto; typedef ratio< 1000, 1> kilo; typedef ratio< 1000000, 1> mega; typedef ratio< 1000000000, 1> giga; typedef ratio< 1000000000000, 1> tera; typedef ratio< 1000000000000000, 1> peta; typedef ratio< 1000000000000000000, 1> exa; // @} group ratio _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif //_GLIBCXX_RATIO PKgd1]*8/cmathnu[// -*- C++ -*- C forwarding header. // Copyright (C) 1997-2018 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/cmath * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c math.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 26.5 C library // #pragma GCC system_header #include #include #include #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include #ifndef _GLIBCXX_CMATH #define _GLIBCXX_CMATH 1 // Get rid of those macros defined in in lieu of real functions. #undef div #undef acos #undef asin #undef atan #undef atan2 #undef ceil #undef cos #undef cosh #undef exp #undef fabs #undef floor #undef fmod #undef frexp #undef ldexp #undef log #undef log10 #undef modf #undef pow #undef sin #undef sinh #undef sqrt #undef tan #undef tanh extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::acos; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float acos(float __x) { return __builtin_acosf(__x); } inline _GLIBCXX_CONSTEXPR long double acos(long double __x) { return __builtin_acosl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acos(_Tp __x) { return __builtin_acos(__x); } using ::asin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float asin(float __x) { return __builtin_asinf(__x); } inline _GLIBCXX_CONSTEXPR long double asin(long double __x) { return __builtin_asinl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asin(_Tp __x) { return __builtin_asin(__x); } using ::atan; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float atan(float __x) { return __builtin_atanf(__x); } inline _GLIBCXX_CONSTEXPR long double atan(long double __x) { return __builtin_atanl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atan(_Tp __x) { return __builtin_atan(__x); } using ::atan2; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float atan2(float __y, float __x) { return __builtin_atan2f(__y, __x); } inline _GLIBCXX_CONSTEXPR long double atan2(long double __y, long double __x) { return __builtin_atan2l(__y, __x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type atan2(_Tp __y, _Up __x) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return atan2(__type(__y), __type(__x)); } using ::ceil; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float ceil(float __x) { return __builtin_ceilf(__x); } inline _GLIBCXX_CONSTEXPR long double ceil(long double __x) { return __builtin_ceill(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ceil(_Tp __x) { return __builtin_ceil(__x); } using ::cos; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float cos(float __x) { return __builtin_cosf(__x); } inline _GLIBCXX_CONSTEXPR long double cos(long double __x) { return __builtin_cosl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cos(_Tp __x) { return __builtin_cos(__x); } using ::cosh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float cosh(float __x) { return __builtin_coshf(__x); } inline _GLIBCXX_CONSTEXPR long double cosh(long double __x) { return __builtin_coshl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cosh(_Tp __x) { return __builtin_cosh(__x); } using ::exp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float exp(float __x) { return __builtin_expf(__x); } inline _GLIBCXX_CONSTEXPR long double exp(long double __x) { return __builtin_expl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp(_Tp __x) { return __builtin_exp(__x); } using ::fabs; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float fabs(float __x) { return __builtin_fabsf(__x); } inline _GLIBCXX_CONSTEXPR long double fabs(long double __x) { return __builtin_fabsl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type fabs(_Tp __x) { return __builtin_fabs(__x); } using ::floor; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float floor(float __x) { return __builtin_floorf(__x); } inline _GLIBCXX_CONSTEXPR long double floor(long double __x) { return __builtin_floorl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type floor(_Tp __x) { return __builtin_floor(__x); } using ::fmod; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float fmod(float __x, float __y) { return __builtin_fmodf(__x, __y); } inline _GLIBCXX_CONSTEXPR long double fmod(long double __x, long double __y) { return __builtin_fmodl(__x, __y); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmod(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmod(__type(__x), __type(__y)); } using ::frexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline float frexp(float __x, int* __exp) { return __builtin_frexpf(__x, __exp); } inline long double frexp(long double __x, int* __exp) { return __builtin_frexpl(__x, __exp); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type frexp(_Tp __x, int* __exp) { return __builtin_frexp(__x, __exp); } using ::ldexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float ldexp(float __x, int __exp) { return __builtin_ldexpf(__x, __exp); } inline _GLIBCXX_CONSTEXPR long double ldexp(long double __x, int __exp) { return __builtin_ldexpl(__x, __exp); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ldexp(_Tp __x, int __exp) { return __builtin_ldexp(__x, __exp); } using ::log; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float log(float __x) { return __builtin_logf(__x); } inline _GLIBCXX_CONSTEXPR long double log(long double __x) { return __builtin_logl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log(_Tp __x) { return __builtin_log(__x); } using ::log10; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float log10(float __x) { return __builtin_log10f(__x); } inline _GLIBCXX_CONSTEXPR long double log10(long double __x) { return __builtin_log10l(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log10(_Tp __x) { return __builtin_log10(__x); } using ::modf; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline float modf(float __x, float* __iptr) { return __builtin_modff(__x, __iptr); } inline long double modf(long double __x, long double* __iptr) { return __builtin_modfl(__x, __iptr); } #endif using ::pow; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float pow(float __x, float __y) { return __builtin_powf(__x, __y); } inline _GLIBCXX_CONSTEXPR long double pow(long double __x, long double __y) { return __builtin_powl(__x, __y); } #if __cplusplus < 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 550. What should the return type of pow(float,int) be? inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); } inline float pow(float __x, int __n) { return __builtin_powif(__x, __n); } inline long double pow(long double __x, int __n) { return __builtin_powil(__x, __n); } #endif #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type pow(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return pow(__type(__x), __type(__y)); } using ::sin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sin(float __x) { return __builtin_sinf(__x); } inline _GLIBCXX_CONSTEXPR long double sin(long double __x) { return __builtin_sinl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sin(_Tp __x) { return __builtin_sin(__x); } using ::sinh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sinh(float __x) { return __builtin_sinhf(__x); } inline _GLIBCXX_CONSTEXPR long double sinh(long double __x) { return __builtin_sinhl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sinh(_Tp __x) { return __builtin_sinh(__x); } using ::sqrt; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sqrt(float __x) { return __builtin_sqrtf(__x); } inline _GLIBCXX_CONSTEXPR long double sqrt(long double __x) { return __builtin_sqrtl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sqrt(_Tp __x) { return __builtin_sqrt(__x); } using ::tan; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float tan(float __x) { return __builtin_tanf(__x); } inline _GLIBCXX_CONSTEXPR long double tan(long double __x) { return __builtin_tanl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tan(_Tp __x) { return __builtin_tan(__x); } using ::tanh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float tanh(float __x) { return __builtin_tanhf(__x); } inline _GLIBCXX_CONSTEXPR long double tanh(long double __x) { return __builtin_tanhl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tanh(_Tp __x) { return __builtin_tanh(__x); } #if _GLIBCXX_USE_C99_MATH #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC // These are possible macros imported from C99-land. #undef fpclassify #undef isfinite #undef isinf #undef isnan #undef isnormal #undef signbit #undef isgreater #undef isgreaterequal #undef isless #undef islessequal #undef islessgreater #undef isunordered #if __cplusplus >= 201103L #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int fpclassify(float __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } constexpr int fpclassify(double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } constexpr int fpclassify(long double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type fpclassify(_Tp __x) { return __x != 0 ? FP_NORMAL : FP_ZERO; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isfinite(float __x) { return __builtin_isfinite(__x); } constexpr bool isfinite(double __x) { return __builtin_isfinite(__x); } constexpr bool isfinite(long double __x) { return __builtin_isfinite(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isfinite(_Tp __x) { return true; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isinf(float __x) { return __builtin_isinf(__x); } #if _GLIBCXX_HAVE_OBSOLETE_ISINF \ && !_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC using ::isinf; #else constexpr bool isinf(double __x) { return __builtin_isinf(__x); } #endif constexpr bool isinf(long double __x) { return __builtin_isinf(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isinf(_Tp __x) { return false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isnan(float __x) { return __builtin_isnan(__x); } #if _GLIBCXX_HAVE_OBSOLETE_ISNAN \ && !_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC using ::isnan; #else constexpr bool isnan(double __x) { return __builtin_isnan(__x); } #endif constexpr bool isnan(long double __x) { return __builtin_isnan(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isnan(_Tp __x) { return false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isnormal(float __x) { return __builtin_isnormal(__x); } constexpr bool isnormal(double __x) { return __builtin_isnormal(__x); } constexpr bool isnormal(long double __x) { return __builtin_isnormal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isnormal(_Tp __x) { return __x != 0 ? true : false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP // Note: middle-end/36757 is fixed, __builtin_signbit is type-generic. constexpr bool signbit(float __x) { return __builtin_signbit(__x); } constexpr bool signbit(double __x) { return __builtin_signbit(__x); } constexpr bool signbit(long double __x) { return __builtin_signbit(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type signbit(_Tp __x) { return __x < 0 ? true : false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isgreater(float __x, float __y) { return __builtin_isgreater(__x, __y); } constexpr bool isgreater(double __x, double __y) { return __builtin_isgreater(__x, __y); } constexpr bool isgreater(long double __x, long double __y) { return __builtin_isgreater(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isgreater(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isgreater(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isgreaterequal(float __x, float __y) { return __builtin_isgreaterequal(__x, __y); } constexpr bool isgreaterequal(double __x, double __y) { return __builtin_isgreaterequal(__x, __y); } constexpr bool isgreaterequal(long double __x, long double __y) { return __builtin_isgreaterequal(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isgreaterequal(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isgreaterequal(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isless(float __x, float __y) { return __builtin_isless(__x, __y); } constexpr bool isless(double __x, double __y) { return __builtin_isless(__x, __y); } constexpr bool isless(long double __x, long double __y) { return __builtin_isless(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isless(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isless(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool islessequal(float __x, float __y) { return __builtin_islessequal(__x, __y); } constexpr bool islessequal(double __x, double __y) { return __builtin_islessequal(__x, __y); } constexpr bool islessequal(long double __x, long double __y) { return __builtin_islessequal(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type islessequal(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_islessequal(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool islessgreater(float __x, float __y) { return __builtin_islessgreater(__x, __y); } constexpr bool islessgreater(double __x, double __y) { return __builtin_islessgreater(__x, __y); } constexpr bool islessgreater(long double __x, long double __y) { return __builtin_islessgreater(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type islessgreater(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_islessgreater(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isunordered(float __x, float __y) { return __builtin_isunordered(__x, __y); } constexpr bool isunordered(double __x, double __y) { return __builtin_isunordered(__x, __y); } constexpr bool isunordered(long double __x, long double __y) { return __builtin_isunordered(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isunordered(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isunordered(__type(__x), __type(__y)); } #endif #else template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type fpclassify(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isfinite(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isfinite(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isinf(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isinf(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnan(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnan(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnormal(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnormal(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type signbit(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_signbit(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreater(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreaterequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreaterequal(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isless(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isless(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessequal(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessgreater(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isunordered(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isunordered(__type(__f1), __type(__f2)); } #endif // C++11 #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ #endif /* _GLIBCXX_USE_C99_MATH */ #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_MATH_TR1 #undef acosh #undef acoshf #undef acoshl #undef asinh #undef asinhf #undef asinhl #undef atanh #undef atanhf #undef atanhl #undef cbrt #undef cbrtf #undef cbrtl #undef copysign #undef copysignf #undef copysignl #undef erf #undef erff #undef erfl #undef erfc #undef erfcf #undef erfcl #undef exp2 #undef exp2f #undef exp2l #undef expm1 #undef expm1f #undef expm1l #undef fdim #undef fdimf #undef fdiml #undef fma #undef fmaf #undef fmal #undef fmax #undef fmaxf #undef fmaxl #undef fmin #undef fminf #undef fminl #undef hypot #undef hypotf #undef hypotl #undef ilogb #undef ilogbf #undef ilogbl #undef lgamma #undef lgammaf #undef lgammal #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS #undef llrint #undef llrintf #undef llrintl #undef llround #undef llroundf #undef llroundl #endif #undef log1p #undef log1pf #undef log1pl #undef log2 #undef log2f #undef log2l #undef logb #undef logbf #undef logbl #undef lrint #undef lrintf #undef lrintl #undef lround #undef lroundf #undef lroundl #undef nan #undef nanf #undef nanl #undef nearbyint #undef nearbyintf #undef nearbyintl #undef nextafter #undef nextafterf #undef nextafterl #undef nexttoward #undef nexttowardf #undef nexttowardl #undef remainder #undef remainderf #undef remainderl #undef remquo #undef remquof #undef remquol #undef rint #undef rintf #undef rintl #undef round #undef roundf #undef roundl #undef scalbln #undef scalblnf #undef scalblnl #undef scalbn #undef scalbnf #undef scalbnl #undef tgamma #undef tgammaf #undef tgammal #undef trunc #undef truncf #undef truncl // types using ::double_t; using ::float_t; // functions using ::acosh; using ::acoshf; using ::acoshl; using ::asinh; using ::asinhf; using ::asinhl; using ::atanh; using ::atanhf; using ::atanhl; using ::cbrt; using ::cbrtf; using ::cbrtl; using ::copysign; using ::copysignf; using ::copysignl; using ::erf; using ::erff; using ::erfl; using ::erfc; using ::erfcf; using ::erfcl; using ::exp2; using ::exp2f; using ::exp2l; using ::expm1; using ::expm1f; using ::expm1l; using ::fdim; using ::fdimf; using ::fdiml; using ::fma; using ::fmaf; using ::fmal; using ::fmax; using ::fmaxf; using ::fmaxl; using ::fmin; using ::fminf; using ::fminl; using ::hypot; using ::hypotf; using ::hypotl; using ::ilogb; using ::ilogbf; using ::ilogbl; using ::lgamma; using ::lgammaf; using ::lgammal; #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS using ::llrint; using ::llrintf; using ::llrintl; using ::llround; using ::llroundf; using ::llroundl; #endif using ::log1p; using ::log1pf; using ::log1pl; using ::log2; using ::log2f; using ::log2l; using ::logb; using ::logbf; using ::logbl; using ::lrint; using ::lrintf; using ::lrintl; using ::lround; using ::lroundf; using ::lroundl; using ::nan; using ::nanf; using ::nanl; using ::nearbyint; using ::nearbyintf; using ::nearbyintl; using ::nextafter; using ::nextafterf; using ::nextafterl; using ::nexttoward; using ::nexttowardf; using ::nexttowardl; using ::remainder; using ::remainderf; using ::remainderl; using ::remquo; using ::remquof; using ::remquol; using ::rint; using ::rintf; using ::rintl; using ::round; using ::roundf; using ::roundl; using ::scalbln; using ::scalblnf; using ::scalblnl; using ::scalbn; using ::scalbnf; using ::scalbnl; using ::tgamma; using ::tgammaf; using ::tgammal; using ::trunc; using ::truncf; using ::truncl; /// Additional overloads. #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float acosh(float __x) { return __builtin_acoshf(__x); } constexpr long double acosh(long double __x) { return __builtin_acoshl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acosh(_Tp __x) { return __builtin_acosh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float asinh(float __x) { return __builtin_asinhf(__x); } constexpr long double asinh(long double __x) { return __builtin_asinhl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asinh(_Tp __x) { return __builtin_asinh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float atanh(float __x) { return __builtin_atanhf(__x); } constexpr long double atanh(long double __x) { return __builtin_atanhl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atanh(_Tp __x) { return __builtin_atanh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float cbrt(float __x) { return __builtin_cbrtf(__x); } constexpr long double cbrt(long double __x) { return __builtin_cbrtl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cbrt(_Tp __x) { return __builtin_cbrt(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float copysign(float __x, float __y) { return __builtin_copysignf(__x, __y); } constexpr long double copysign(long double __x, long double __y) { return __builtin_copysignl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type copysign(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return copysign(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erf(float __x) { return __builtin_erff(__x); } constexpr long double erf(long double __x) { return __builtin_erfl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type erf(_Tp __x) { return __builtin_erf(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erfc(float __x) { return __builtin_erfcf(__x); } constexpr long double erfc(long double __x) { return __builtin_erfcl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type erfc(_Tp __x) { return __builtin_erfc(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float exp2(float __x) { return __builtin_exp2f(__x); } constexpr long double exp2(long double __x) { return __builtin_exp2l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp2(_Tp __x) { return __builtin_exp2(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float expm1(float __x) { return __builtin_expm1f(__x); } constexpr long double expm1(long double __x) { return __builtin_expm1l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type expm1(_Tp __x) { return __builtin_expm1(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fdim(float __x, float __y) { return __builtin_fdimf(__x, __y); } constexpr long double fdim(long double __x, long double __y) { return __builtin_fdiml(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fdim(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fdim(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fma(float __x, float __y, float __z) { return __builtin_fmaf(__x, __y, __z); } constexpr long double fma(long double __x, long double __y, long double __z) { return __builtin_fmal(__x, __y, __z); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type fma(_Tp __x, _Up __y, _Vp __z) { typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type; return fma(__type(__x), __type(__y), __type(__z)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmax(float __x, float __y) { return __builtin_fmaxf(__x, __y); } constexpr long double fmax(long double __x, long double __y) { return __builtin_fmaxl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmax(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmax(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmin(float __x, float __y) { return __builtin_fminf(__x, __y); } constexpr long double fmin(long double __x, long double __y) { return __builtin_fminl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmin(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmin(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float hypot(float __x, float __y) { return __builtin_hypotf(__x, __y); } constexpr long double hypot(long double __x, long double __y) { return __builtin_hypotl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type hypot(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return hypot(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int ilogb(float __x) { return __builtin_ilogbf(__x); } constexpr int ilogb(long double __x) { return __builtin_ilogbl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type ilogb(_Tp __x) { return __builtin_ilogb(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float lgamma(float __x) { return __builtin_lgammaf(__x); } constexpr long double lgamma(long double __x) { return __builtin_lgammal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type lgamma(_Tp __x) { return __builtin_lgamma(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long long llrint(float __x) { return __builtin_llrintf(__x); } constexpr long long llrint(long double __x) { return __builtin_llrintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long long>::__type llrint(_Tp __x) { return __builtin_llrint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long long llround(float __x) { return __builtin_llroundf(__x); } constexpr long long llround(long double __x) { return __builtin_llroundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long long>::__type llround(_Tp __x) { return __builtin_llround(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float log1p(float __x) { return __builtin_log1pf(__x); } constexpr long double log1p(long double __x) { return __builtin_log1pl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log1p(_Tp __x) { return __builtin_log1p(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP // DR 568. constexpr float log2(float __x) { return __builtin_log2f(__x); } constexpr long double log2(long double __x) { return __builtin_log2l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log2(_Tp __x) { return __builtin_log2(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float logb(float __x) { return __builtin_logbf(__x); } constexpr long double logb(long double __x) { return __builtin_logbl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type logb(_Tp __x) { return __builtin_logb(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long lrint(float __x) { return __builtin_lrintf(__x); } constexpr long lrint(long double __x) { return __builtin_lrintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long>::__type lrint(_Tp __x) { return __builtin_lrint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long lround(float __x) { return __builtin_lroundf(__x); } constexpr long lround(long double __x) { return __builtin_lroundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long>::__type lround(_Tp __x) { return __builtin_lround(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nearbyint(float __x) { return __builtin_nearbyintf(__x); } constexpr long double nearbyint(long double __x) { return __builtin_nearbyintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type nearbyint(_Tp __x) { return __builtin_nearbyint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nextafter(float __x, float __y) { return __builtin_nextafterf(__x, __y); } constexpr long double nextafter(long double __x, long double __y) { return __builtin_nextafterl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type nextafter(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return nextafter(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nexttoward(float __x, long double __y) { return __builtin_nexttowardf(__x, __y); } constexpr long double nexttoward(long double __x, long double __y) { return __builtin_nexttowardl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type nexttoward(_Tp __x, long double __y) { return __builtin_nexttoward(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float remainder(float __x, float __y) { return __builtin_remainderf(__x, __y); } constexpr long double remainder(long double __x, long double __y) { return __builtin_remainderl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type remainder(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return remainder(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP inline float remquo(float __x, float __y, int* __pquo) { return __builtin_remquof(__x, __y, __pquo); } inline long double remquo(long double __x, long double __y, int* __pquo) { return __builtin_remquol(__x, __y, __pquo); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type remquo(_Tp __x, _Up __y, int* __pquo) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return remquo(__type(__x), __type(__y), __pquo); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float rint(float __x) { return __builtin_rintf(__x); } constexpr long double rint(long double __x) { return __builtin_rintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type rint(_Tp __x) { return __builtin_rint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float round(float __x) { return __builtin_roundf(__x); } constexpr long double round(long double __x) { return __builtin_roundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type round(_Tp __x) { return __builtin_round(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float scalbln(float __x, long __ex) { return __builtin_scalblnf(__x, __ex); } constexpr long double scalbln(long double __x, long __ex) { return __builtin_scalblnl(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type scalbln(_Tp __x, long __ex) { return __builtin_scalbln(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float scalbn(float __x, int __ex) { return __builtin_scalbnf(__x, __ex); } constexpr long double scalbn(long double __x, int __ex) { return __builtin_scalbnl(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type scalbn(_Tp __x, int __ex) { return __builtin_scalbn(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float tgamma(float __x) { return __builtin_tgammaf(__x); } constexpr long double tgamma(long double __x) { return __builtin_tgammal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tgamma(_Tp __x) { return __builtin_tgamma(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float trunc(float __x) { return __builtin_truncf(__x); } constexpr long double trunc(long double __x) { return __builtin_truncl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type trunc(_Tp __x) { return __builtin_trunc(__x); } #endif #endif // _GLIBCXX_USE_C99_MATH_TR1 #endif // C++11 #if __cplusplus > 201402L // [c.math.hypot3], three-dimensional hypotenuse #define __cpp_lib_hypot 201603 template inline _Tp __hypot3(_Tp __x, _Tp __y, _Tp __z) { __x = std::abs(__x); __y = std::abs(__y); __z = std::abs(__z); if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x) return __a * std::sqrt((__x / __a) * (__x / __a) + (__y / __a) * (__y / __a) + (__z / __a) * (__z / __a)); else return {}; } inline float hypot(float __x, float __y, float __z) { return std::__hypot3(__x, __y, __z); } inline double hypot(double __x, double __y, double __z) { return std::__hypot3(__x, __y, __z); } inline long double hypot(long double __x, long double __y, long double __z) { return std::__hypot3(__x, __y, __z); } template typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type hypot(_Tp __x, _Up __y, _Vp __z) { using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type; return std::__hypot3<__type>(__x, __y, __z); } #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_STD_SPEC_FUNCS # include #endif } // extern "C++" #endif PKgd1]rj))8/threadnu[// -*- C++ -*- // Copyright (C) 2008-2018 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/thread * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_THREAD #define _GLIBCXX_THREAD 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #include #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup threads Threads * @ingroup concurrency * * Classes for thread support. * @{ */ /// thread class thread { public: // Abstract base class for types that wrap arbitrary functors to be // invoked in the new thread of execution. struct _State { virtual ~_State(); virtual void _M_run() = 0; }; using _State_ptr = unique_ptr<_State>; typedef __gthread_t native_handle_type; /// thread::id class id { native_handle_type _M_thread; public: id() noexcept : _M_thread() { } explicit id(native_handle_type __id) : _M_thread(__id) { } private: friend class thread; friend class hash; friend bool operator==(thread::id __x, thread::id __y) noexcept; friend bool operator<(thread::id __x, thread::id __y) noexcept; template friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id); }; private: id _M_id; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained template using __not_same = __not_::type>::type, thread>>; public: thread() noexcept = default; template>> explicit thread(_Callable&& __f, _Args&&... __args) { static_assert( __is_invocable::type, typename decay<_Args>::type...>::value, "std::thread arguments must be invocable after conversion to rvalues" ); #ifdef GTHR_ACTIVE_PROXY // Create a reference to pthread_create, not just the gthr weak symbol. auto __depend = reinterpret_cast(&pthread_create); #else auto __depend = nullptr; #endif _M_start_thread(_S_make_state( __make_invoker(std::forward<_Callable>(__f), std::forward<_Args>(__args)...)), __depend); } ~thread() { if (joinable()) std::terminate(); } thread(const thread&) = delete; thread(thread&& __t) noexcept { swap(__t); } thread& operator=(const thread&) = delete; thread& operator=(thread&& __t) noexcept { if (joinable()) std::terminate(); swap(__t); return *this; } void swap(thread& __t) noexcept { std::swap(_M_id, __t._M_id); } bool joinable() const noexcept { return !(_M_id == id()); } void join(); void detach(); thread::id get_id() const noexcept { return _M_id; } /** @pre thread is joinable */ native_handle_type native_handle() { return _M_id._M_thread; } // Returns a value that hints at the number of hardware thread contexts. static unsigned int hardware_concurrency() noexcept; private: template struct _State_impl : public _State { _Callable _M_func; _State_impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f)) { } void _M_run() { _M_func(); } }; void _M_start_thread(_State_ptr, void (*)()); template static _State_ptr _S_make_state(_Callable&& __f) { using _Impl = _State_impl<_Callable>; return _State_ptr{new _Impl{std::forward<_Callable>(__f)}}; } #if _GLIBCXX_THREAD_ABI_COMPAT public: struct _Impl_base; typedef shared_ptr<_Impl_base> __shared_base_type; struct _Impl_base { __shared_base_type _M_this_ptr; virtual ~_Impl_base() = default; virtual void _M_run() = 0; }; private: void _M_start_thread(__shared_base_type, void (*)()); void _M_start_thread(__shared_base_type); #endif private: // A call wrapper that does INVOKE(forwarded tuple elements...) template struct _Invoker { _Tuple _M_t; template static __tuple_element_t<_Index, _Tuple>&& _S_declval(); template auto _M_invoke(_Index_tuple<_Ind...>) noexcept(noexcept(std::__invoke(_S_declval<_Ind>()...))) -> decltype(std::__invoke(_S_declval<_Ind>()...)) { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); } using _Indices = typename _Build_index_tuple::value>::__type; auto operator()() noexcept(noexcept(std::declval<_Invoker&>()._M_invoke(_Indices()))) -> decltype(std::declval<_Invoker&>()._M_invoke(_Indices())) { return _M_invoke(_Indices()); } }; template using __decayed_tuple = tuple::type...>; public: // Returns a call wrapper that stores // tuple{DECAY_COPY(__callable), DECAY_COPY(__args)...}. template static _Invoker<__decayed_tuple<_Callable, _Args...>> __make_invoker(_Callable&& __callable, _Args&&... __args) { return { __decayed_tuple<_Callable, _Args...>{ std::forward<_Callable>(__callable), std::forward<_Args>(__args)... } }; } }; inline void swap(thread& __x, thread& __y) noexcept { __x.swap(__y); } inline bool operator==(thread::id __x, thread::id __y) noexcept { // pthread_equal is undefined if either thread ID is not valid, so we // can't safely use __gthread_equal on default-constructed values (nor // the non-zero value returned by this_thread::get_id() for // single-threaded programs using GNU libc). Assume EqualityComparable. return __x._M_thread == __y._M_thread; } inline bool operator!=(thread::id __x, thread::id __y) noexcept { return !(__x == __y); } inline bool operator<(thread::id __x, thread::id __y) noexcept { // Pthreads doesn't define any way to do this, so we just have to // assume native_handle_type is LessThanComparable. return __x._M_thread < __y._M_thread; } inline bool operator<=(thread::id __x, thread::id __y) noexcept { return !(__y < __x); } inline bool operator>(thread::id __x, thread::id __y) noexcept { return __y < __x; } inline bool operator>=(thread::id __x, thread::id __y) noexcept { return !(__x < __y); } // DR 889. /// std::hash specialization for thread::id. template<> struct hash : public __hash_base { size_t operator()(const thread::id& __id) const noexcept { return std::_Hash_impl::hash(__id._M_thread); } }; template inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id) { if (__id == thread::id()) return __out << "thread::id of a non-executing thread"; else return __out << __id._M_thread; } /** @namespace std::this_thread * @brief ISO C++ 2011 entities sub-namespace for thread. * 30.3.2 Namespace this_thread. */ namespace this_thread { /// get_id inline thread::id get_id() noexcept { #ifdef __GLIBC__ // For the GNU C library pthread_self() is usable without linking to // libpthread.so but returns 0, so we cannot use it in single-threaded // programs, because this_thread::get_id() != thread::id{} must be true. // We know that pthread_t is an integral type in the GNU C library. if (!__gthread_active_p()) return thread::id(1); #endif return thread::id(__gthread_self()); } /// yield inline void yield() noexcept { #ifdef _GLIBCXX_USE_SCHED_YIELD __gthread_yield(); #endif } void __sleep_for(chrono::seconds, chrono::nanoseconds); /// sleep_for template inline void sleep_for(const chrono::duration<_Rep, _Period>& __rtime) { if (__rtime <= __rtime.zero()) return; auto __s = chrono::duration_cast(__rtime); auto __ns = chrono::duration_cast(__rtime - __s); #ifdef _GLIBCXX_USE_NANOSLEEP __gthread_time_t __ts = { static_cast(__s.count()), static_cast(__ns.count()) }; while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR) { } #else __sleep_for(__s, __ns); #endif } /// sleep_until template inline void sleep_until(const chrono::time_point<_Clock, _Duration>& __atime) { auto __now = _Clock::now(); if (_Clock::is_steady) { if (__now < __atime) sleep_for(__atime - __now); return; } while (__now < __atime) { sleep_for(__atime - __now); __now = _Clock::now(); } } } // @} group threads _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_THREAD PKgd1]v  8/typeindexnu[// C++11 -*- C++ -*- // Copyright (C) 2010-2018 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/typeindex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TYPEINDEX #define _GLIBCXX_TYPEINDEX 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Class type_index * @ingroup utilities * * The class type_index provides a simple wrapper for type_info * which can be used as an index type in associative containers * (23.6) and in unordered associative containers (23.7). */ struct type_index { type_index(const type_info& __rhs) noexcept : _M_target(&__rhs) { } bool operator==(const type_index& __rhs) const noexcept { return *_M_target == *__rhs._M_target; } bool operator!=(const type_index& __rhs) const noexcept { return *_M_target != *__rhs._M_target; } bool operator<(const type_index& __rhs) const noexcept { return _M_target->before(*__rhs._M_target); } bool operator<=(const type_index& __rhs) const noexcept { return !__rhs._M_target->before(*_M_target); } bool operator>(const type_index& __rhs) const noexcept { return __rhs._M_target->before(*_M_target); } bool operator>=(const type_index& __rhs) const noexcept { return !_M_target->before(*__rhs._M_target); } size_t hash_code() const noexcept { return _M_target->hash_code(); } const char* name() const noexcept { return _M_target->name(); } private: const type_info* _M_target; }; template struct hash; /// std::hash specialization for type_index. template<> struct hash { typedef size_t result_type; typedef type_index argument_type; size_t operator()(const type_index& __ti) const noexcept { return __ti.hash_code(); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TYPEINDEX PKgd1]ʼnww 8/cstdintnu[// -*- C++ -*- // Copyright (C) 2007-2018 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/cstdint * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CSTDINT #define _GLIBCXX_CSTDINT 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #if _GLIBCXX_HAVE_STDINT_H # include #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std { using ::int8_t; using ::int16_t; using ::int32_t; using ::int64_t; using ::int_fast8_t; using ::int_fast16_t; using ::int_fast32_t; using ::int_fast64_t; using ::int_least8_t; using ::int_least16_t; using ::int_least32_t; using ::int_least64_t; using ::intmax_t; using ::intptr_t; using ::uint8_t; using ::uint16_t; using ::uint32_t; using ::uint64_t; using ::uint_fast8_t; using ::uint_fast16_t; using ::uint_fast32_t; using ::uint_fast64_t; using ::uint_least8_t; using ::uint_least16_t; using ::uint_least32_t; using ::uint_least64_t; using ::uintmax_t; using ::uintptr_t; } // namespace std #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_CSTDINT PKgd1]9yy 8/cstdboolnu[// -*- C++ -*- // Copyright (C) 2007-2018 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/cstdbool * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CSTDBOOL #define _GLIBCXX_CSTDBOOL 1 #if __cplusplus < 201103L # include #else # include # if _GLIBCXX_HAVE_STDBOOL_H # include # endif #endif #endif PKgd1]aD 8/ciso646nu[// -*- C++ -*- forwarding header. // Copyright (C) 2001-2018 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 ciso646 * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c iso646.h, * which is empty in C++. */ #ifndef _GLIBCXX_CISO646 #define _GLIBCXX_CISO646 #pragma GCC system_header #include #endif PKgd1]aa8/atomicnu[// -*- C++ -*- header. // Copyright (C) 2008-2018 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/atomic * This is a Standard C++ Library header. */ // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html #ifndef _GLIBCXX_ATOMIC #define _GLIBCXX_ATOMIC 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup atomics * @{ */ #if __cplusplus > 201402L # define __cpp_lib_atomic_is_always_lock_free 201603 #endif template struct atomic; /// atomic // NB: No operators or fetch-operations for this type. template<> struct atomic { private: __atomic_base _M_base; public: atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(bool __i) noexcept : _M_base(__i) { } bool operator=(bool __i) noexcept { return _M_base.operator=(__i); } bool operator=(bool __i) volatile noexcept { return _M_base.operator=(__i); } operator bool() const noexcept { return _M_base.load(); } operator bool() const volatile noexcept { return _M_base.load(); } bool is_lock_free() const noexcept { return _M_base.is_lock_free(); } bool is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2; #endif void store(bool __i, memory_order __m = memory_order_seq_cst) noexcept { _M_base.store(__i, __m); } void store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept { _M_base.store(__i, __m); } bool load(memory_order __m = memory_order_seq_cst) const noexcept { return _M_base.load(__m); } bool load(memory_order __m = memory_order_seq_cst) const volatile noexcept { return _M_base.load(__m); } bool exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.exchange(__i, __m); } bool exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.exchange(__i, __m); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m); } }; /** * @brief Generic atomic type, primary class template. * * @tparam _Tp Type to be made atomic, must be trivally copyable. */ template struct atomic { private: // Align 1/2/4/8/16-byte types to at least their size. static constexpr int _S_min_alignment = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16 ? 0 : sizeof(_Tp); static constexpr int _S_alignment = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp); alignas(_S_alignment) _Tp _M_i; static_assert(__is_trivially_copyable(_Tp), "std::atomic requires a trivially copyable type"); static_assert(sizeof(_Tp) > 0, "Incomplete or zero-sized types are not supported"); public: atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } operator _Tp() const noexcept { return load(); } operator _Tp() const volatile noexcept { return load(); } _Tp operator=(_Tp __i) noexcept { store(__i); return __i; } _Tp operator=(_Tp __i) volatile noexcept { store(__i); return __i; } bool is_lock_free() const noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast(-__alignof(_M_i))); } bool is_lock_free() const volatile noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast(-__alignof(_M_i))); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = __atomic_always_lock_free(sizeof(_M_i), 0); #endif void store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } void store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } _Tp load(memory_order __m = memory_order_seq_cst) const noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_load(std::__addressof(_M_i), __ptr, __m); return *__ptr; } _Tp load(memory_order __m = memory_order_seq_cst) const volatile noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_load(std::__addressof(_M_i), __ptr, __m); return *__ptr; } _Tp exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), __ptr, __m); return *__ptr; } _Tp exchange(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), __ptr, __m); return *__ptr; } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } }; /// Partial specialization for pointer types. template struct atomic<_Tp*> { typedef _Tp* __pointer_type; typedef __atomic_base<_Tp*> __base_type; __base_type _M_b; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } operator __pointer_type() const noexcept { return __pointer_type(_M_b); } operator __pointer_type() const volatile noexcept { return __pointer_type(_M_b); } __pointer_type operator=(__pointer_type __p) noexcept { return _M_b.operator=(__p); } __pointer_type operator=(__pointer_type __p) volatile noexcept { return _M_b.operator=(__p); } __pointer_type operator++(int) noexcept { return _M_b++; } __pointer_type operator++(int) volatile noexcept { return _M_b++; } __pointer_type operator--(int) noexcept { return _M_b--; } __pointer_type operator--(int) volatile noexcept { return _M_b--; } __pointer_type operator++() noexcept { return ++_M_b; } __pointer_type operator++() volatile noexcept { return ++_M_b; } __pointer_type operator--() noexcept { return --_M_b; } __pointer_type operator--() volatile noexcept { return --_M_b; } __pointer_type operator+=(ptrdiff_t __d) noexcept { return _M_b.operator+=(__d); } __pointer_type operator+=(ptrdiff_t __d) volatile noexcept { return _M_b.operator+=(__d); } __pointer_type operator-=(ptrdiff_t __d) noexcept { return _M_b.operator-=(__d); } __pointer_type operator-=(ptrdiff_t __d) volatile noexcept { return _M_b.operator-=(__d); } bool is_lock_free() const noexcept { return _M_b.is_lock_free(); } bool is_lock_free() const volatile noexcept { return _M_b.is_lock_free(); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_POINTER_LOCK_FREE == 2; #endif void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.store(__p, __m); } void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.store(__p, __m); } __pointer_type load(memory_order __m = memory_order_seq_cst) const noexcept { return _M_b.load(__m); } __pointer_type load(memory_order __m = memory_order_seq_cst) const volatile noexcept { return _M_b.load(__m); } __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.exchange(__p, __m); } __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.exchange(__p, __m); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m, __cmpexch_failure_order(__m)); } __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.fetch_add(__d, __m); } __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.fetch_add(__d, __m); } __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.fetch_sub(__d, __m); } __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.fetch_sub(__d, __m); } }; /// Explicit specialization for char. template<> struct atomic : __atomic_base { typedef char __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for signed char. template<> struct atomic : __atomic_base { typedef signed char __integral_type; typedef __atomic_base __base_type; atomic() noexcept= default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned char. template<> struct atomic : __atomic_base { typedef unsigned char __integral_type; typedef __atomic_base __base_type; atomic() noexcept= default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for short. template<> struct atomic : __atomic_base { typedef short __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned short. template<> struct atomic : __atomic_base { typedef unsigned short __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; #endif }; /// Explicit specialization for int. template<> struct atomic : __atomic_base { typedef int __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned int. template<> struct atomic : __atomic_base { typedef unsigned int __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; #endif }; /// Explicit specialization for long. template<> struct atomic : __atomic_base { typedef long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned long. template<> struct atomic : __atomic_base { typedef unsigned long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for long long. template<> struct atomic : __atomic_base { typedef long long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned long long. template<> struct atomic : __atomic_base { typedef unsigned long long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for wchar_t. template<> struct atomic : __atomic_base { typedef wchar_t __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2; #endif }; /// Explicit specialization for char16_t. template<> struct atomic : __atomic_base { typedef char16_t __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR16_T_LOCK_FREE == 2; #endif }; /// Explicit specialization for char32_t. template<> struct atomic : __atomic_base { typedef char32_t __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR32_T_LOCK_FREE == 2; #endif }; /// atomic_bool typedef atomic atomic_bool; /// atomic_char typedef atomic atomic_char; /// atomic_schar typedef atomic atomic_schar; /// atomic_uchar typedef atomic atomic_uchar; /// atomic_short typedef atomic atomic_short; /// atomic_ushort typedef atomic atomic_ushort; /// atomic_int typedef atomic atomic_int; /// atomic_uint typedef atomic atomic_uint; /// atomic_long typedef atomic atomic_long; /// atomic_ulong typedef atomic atomic_ulong; /// atomic_llong typedef atomic atomic_llong; /// atomic_ullong typedef atomic atomic_ullong; /// atomic_wchar_t typedef atomic atomic_wchar_t; /// atomic_char16_t typedef atomic atomic_char16_t; /// atomic_char32_t typedef atomic atomic_char32_t; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2441. Exact-width atomic typedefs should be provided /// atomic_int8_t typedef atomic atomic_int8_t; /// atomic_uint8_t typedef atomic atomic_uint8_t; /// atomic_int16_t typedef atomic atomic_int16_t; /// atomic_uint16_t typedef atomic atomic_uint16_t; /// atomic_int32_t typedef atomic atomic_int32_t; /// atomic_uint32_t typedef atomic atomic_uint32_t; /// atomic_int64_t typedef atomic atomic_int64_t; /// atomic_uint64_t typedef atomic atomic_uint64_t; /// atomic_int_least8_t typedef atomic atomic_int_least8_t; /// atomic_uint_least8_t typedef atomic atomic_uint_least8_t; /// atomic_int_least16_t typedef atomic atomic_int_least16_t; /// atomic_uint_least16_t typedef atomic atomic_uint_least16_t; /// atomic_int_least32_t typedef atomic atomic_int_least32_t; /// atomic_uint_least32_t typedef atomic atomic_uint_least32_t; /// atomic_int_least64_t typedef atomic atomic_int_least64_t; /// atomic_uint_least64_t typedef atomic atomic_uint_least64_t; /// atomic_int_fast8_t typedef atomic atomic_int_fast8_t; /// atomic_uint_fast8_t typedef atomic atomic_uint_fast8_t; /// atomic_int_fast16_t typedef atomic atomic_int_fast16_t; /// atomic_uint_fast16_t typedef atomic atomic_uint_fast16_t; /// atomic_int_fast32_t typedef atomic atomic_int_fast32_t; /// atomic_uint_fast32_t typedef atomic atomic_uint_fast32_t; /// atomic_int_fast64_t typedef atomic atomic_int_fast64_t; /// atomic_uint_fast64_t typedef atomic atomic_uint_fast64_t; #endif /// atomic_intptr_t typedef atomic atomic_intptr_t; /// atomic_uintptr_t typedef atomic atomic_uintptr_t; /// atomic_size_t typedef atomic atomic_size_t; /// atomic_ptrdiff_t typedef atomic atomic_ptrdiff_t; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// atomic_intmax_t typedef atomic atomic_intmax_t; /// atomic_uintmax_t typedef atomic atomic_uintmax_t; #endif // Function definitions, atomic_flag operations. inline bool atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m) noexcept { return __a->test_and_set(__m); } inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, memory_order __m) noexcept { return __a->test_and_set(__m); } inline void atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept { __a->clear(__m); } inline void atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m) noexcept { __a->clear(__m); } inline bool atomic_flag_test_and_set(atomic_flag* __a) noexcept { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } inline bool atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } inline void atomic_flag_clear(atomic_flag* __a) noexcept { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } inline void atomic_flag_clear(volatile atomic_flag* __a) noexcept { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } // Function templates generally applicable to atomic types. template inline bool atomic_is_lock_free(const atomic<_ITp>* __a) noexcept { return __a->is_lock_free(); } template inline bool atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept { return __a->is_lock_free(); } template inline void atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept { __a->store(__i, memory_order_relaxed); } template inline void atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept { __a->store(__i, memory_order_relaxed); } template inline void atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { __a->store(__i, __m); } template inline void atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { __a->store(__i, __m); } template inline _ITp atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept { return __a->load(__m); } template inline _ITp atomic_load_explicit(const volatile atomic<_ITp>* __a, memory_order __m) noexcept { return __a->load(__m); } template inline _ITp atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->exchange(__i, __m); } template inline _ITp atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->exchange(__i, __m); } template inline bool atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } template inline bool atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } template inline bool atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } template inline bool atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } template inline void atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept { atomic_store_explicit(__a, __i, memory_order_seq_cst); } template inline void atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept { atomic_store_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_load(const atomic<_ITp>* __a) noexcept { return atomic_load_explicit(__a, memory_order_seq_cst); } template inline _ITp atomic_load(const volatile atomic<_ITp>* __a) noexcept { return atomic_load_explicit(__a, memory_order_seq_cst); } template inline _ITp atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } template inline bool atomic_compare_exchange_weak(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template inline bool atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template inline bool atomic_compare_exchange_strong(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template inline bool atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } // Function templates for atomic_integral operations only, using // __atomic_base. Template argument should be constricted to // intergral types as specified in the standard, excluding address // types. template inline _ITp atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_add(__i, __m); } template inline _ITp atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_add(__i, __m); } template inline _ITp atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_sub(__i, __m); } template inline _ITp atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_sub(__i, __m); } template inline _ITp atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_and(__i, __m); } template inline _ITp atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_and(__i, __m); } template inline _ITp atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_or(__i, __m); } template inline _ITp atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_or(__i, __m); } template inline _ITp atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_xor(__i, __m); } template inline _ITp atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_xor(__i, __m); } template inline _ITp atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } // Partial specializations for pointers. template inline _ITp* atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_add(__d, __m); } template inline _ITp* atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_add(__d, __m); } template inline _ITp* atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_add(__d); } template inline _ITp* atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_add(__d); } template inline _ITp* atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_sub(__d, __m); } template inline _ITp* atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_sub(__d, __m); } template inline _ITp* atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_sub(__d); } template inline _ITp* atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_sub(__d); } // @} group atomics _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_ATOMIC PKgd1]D@V 8/cstdlibnu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cstdlib * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stdlib.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #include #ifndef _GLIBCXX_CSTDLIB #define _GLIBCXX_CSTDLIB 1 #if !_GLIBCXX_HOSTED // The C standard does not require a freestanding implementation to // provide . However, the C++ standard does still require // -- but only the functionality mentioned in // [lib.support.start.term]. #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 namespace std { extern "C" void abort(void) throw () _GLIBCXX_NORETURN; extern "C" int atexit(void (*)(void)) throw (); extern "C" void exit(int) throw () _GLIBCXX_NORETURN; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT extern "C" int at_quick_exit(void (*)(void)) throw (); # endif # ifdef _GLIBCXX_HAVE_QUICK_EXIT extern "C" void quick_exit(int) throw() _GLIBCXX_NORETURN; # endif #endif } // namespace std #else // Need to ensure this finds the C library's not a libstdc++ // wrapper that might already be installed later in the include search path. #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include // Get rid of those macros defined in in lieu of real functions. #undef abort #if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) # undef aligned_alloc #endif #undef atexit #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT # undef at_quick_exit # endif #endif #undef atof #undef atoi #undef atol #undef bsearch #undef calloc #undef div #undef exit #undef free #undef getenv #undef labs #undef ldiv #undef malloc #undef mblen #undef mbstowcs #undef mbtowc #undef qsort #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_QUICK_EXIT # undef quick_exit # endif #endif #undef rand #undef realloc #undef srand #undef strtod #undef strtol #undef strtoul #undef system #undef wcstombs #undef wctomb extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::div_t; using ::ldiv_t; using ::abort; #if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) using ::aligned_alloc; #endif using ::atexit; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT using ::at_quick_exit; # endif #endif using ::atof; using ::atoi; using ::atol; using ::bsearch; using ::calloc; using ::div; using ::exit; using ::free; using ::getenv; using ::labs; using ::ldiv; using ::malloc; #ifdef _GLIBCXX_HAVE_MBSTATE_T using ::mblen; using ::mbstowcs; using ::mbtowc; #endif // _GLIBCXX_HAVE_MBSTATE_T using ::qsort; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_QUICK_EXIT using ::quick_exit; # endif #endif using ::rand; using ::realloc; using ::srand; using ::strtod; using ::strtol; using ::strtoul; using ::system; #ifdef _GLIBCXX_USE_WCHAR_T using ::wcstombs; using ::wctomb; #endif // _GLIBCXX_USE_WCHAR_T #ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO inline ldiv_t div(long __i, long __j) { return ldiv(__i, __j); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99_STDLIB #undef _Exit #undef llabs #undef lldiv #undef atoll #undef strtoll #undef strtoull #undef strtof #undef strtold namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::lldiv_t; #endif #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" void (_Exit)(int) throw () _GLIBCXX_NORETURN; #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::_Exit; #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::llabs; inline lldiv_t div(long long __n, long long __d) { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } using ::lldiv; #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (atoll)(const char *) throw (); extern "C" long long int (strtoll)(const char * __restrict, char ** __restrict, int) throw (); extern "C" unsigned long long int (strtoull)(const char * __restrict, char ** __restrict, int) throw (); #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::atoll; using ::strtoll; using ::strtoull; #endif using ::strtof; using ::strtold; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx namespace std { #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::__gnu_cxx::lldiv_t; #endif using ::__gnu_cxx::_Exit; #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::__gnu_cxx::llabs; using ::__gnu_cxx::div; using ::__gnu_cxx::lldiv; #endif using ::__gnu_cxx::atoll; using ::__gnu_cxx::strtof; using ::__gnu_cxx::strtoll; using ::__gnu_cxx::strtoull; using ::__gnu_cxx::strtold; } // namespace std #endif // _GLIBCXX_USE_C99_STDLIB } // extern "C++" #endif // !_GLIBCXX_HOSTED #endif PKgd1]WNVV8/bitsetnu[// -*- C++ -*- // Copyright (C) 2001-2018 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) 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 include/bitset * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_BITSET #define _GLIBCXX_BITSET 1 #pragma GCC system_header #include #include // For invalid_argument, out_of_range, // overflow_error #include #include #if __cplusplus >= 201103L # include #endif #define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_LONG__) #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \ ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1)) #define _GLIBCXX_BITSET_BITS_PER_ULL (__CHAR_BIT__ * __SIZEOF_LONG_LONG__) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * Base class, general case. It is a class invariant that _Nw will be * nonnegative. * * See documentation for bitset. */ template struct _Base_bitset { typedef unsigned long _WordT; /// 0 is the least significant word. _WordT _M_w[_Nw]; _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT : _M_w() { } #if __cplusplus >= 201103L constexpr _Base_bitset(unsigned long long __val) noexcept : _M_w{ _WordT(__val) #if __SIZEOF_LONG_LONG__ > __SIZEOF_LONG__ , _WordT(__val >> _GLIBCXX_BITSET_BITS_PER_WORD) #endif } { } #else _Base_bitset(unsigned long __val) : _M_w() { _M_w[0] = __val; } #endif static _GLIBCXX_CONSTEXPR size_t _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR size_t _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static _GLIBCXX_CONSTEXPR size_t _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR _WordT _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } _WordT& _M_getword(size_t __pos) _GLIBCXX_NOEXCEPT { return _M_w[_S_whichword(__pos)]; } _GLIBCXX_CONSTEXPR _WordT _M_getword(size_t __pos) const _GLIBCXX_NOEXCEPT { return _M_w[_S_whichword(__pos)]; } #if __cplusplus >= 201103L const _WordT* _M_getdata() const noexcept { return _M_w; } #endif _WordT& _M_hiword() _GLIBCXX_NOEXCEPT { return _M_w[_Nw - 1]; } _GLIBCXX_CONSTEXPR _WordT _M_hiword() const _GLIBCXX_NOEXCEPT { return _M_w[_Nw - 1]; } void _M_do_and(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] &= __x._M_w[__i]; } void _M_do_or(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] |= __x._M_w[__i]; } void _M_do_xor(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] ^= __x._M_w[__i]; } void _M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT; void _M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT; void _M_do_flip() _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] = ~_M_w[__i]; } void _M_do_set() _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] = ~static_cast<_WordT>(0); } void _M_do_reset() _GLIBCXX_NOEXCEPT { __builtin_memset(_M_w, 0, _Nw * sizeof(_WordT)); } bool _M_is_equal(const _Base_bitset<_Nw>& __x) const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; ++__i) if (_M_w[__i] != __x._M_w[__i]) return false; return true; } template bool _M_are_all() const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw - 1; __i++) if (_M_w[__i] != ~static_cast<_WordT>(0)) return false; return _M_hiword() == (~static_cast<_WordT>(0) >> (_Nw * _GLIBCXX_BITSET_BITS_PER_WORD - _Nb)); } bool _M_is_any() const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) if (_M_w[__i] != static_cast<_WordT>(0)) return true; return false; } size_t _M_do_count() const _GLIBCXX_NOEXCEPT { size_t __result = 0; for (size_t __i = 0; __i < _Nw; __i++) __result += __builtin_popcountl(_M_w[__i]); return __result; } unsigned long _M_do_to_ulong() const; #if __cplusplus >= 201103L unsigned long long _M_do_to_ullong() const; #endif // find first "on" bit size_t _M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT; // find the next "on" bit that follows "prev" size_t _M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT; }; // Definitions of non-inline functions from _Base_bitset. template void _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; if (__offset == 0) for (size_t __n = _Nw - 1; __n >= __wshift; --__n) _M_w[__n] = _M_w[__n - __wshift]; else { const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD - __offset); for (size_t __n = _Nw - 1; __n > __wshift; --__n) _M_w[__n] = ((_M_w[__n - __wshift] << __offset) | (_M_w[__n - __wshift - 1] >> __sub_offset)); _M_w[__wshift] = _M_w[0] << __offset; } std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); } } template void _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __limit = _Nw - __wshift - 1; if (__offset == 0) for (size_t __n = 0; __n <= __limit; ++__n) _M_w[__n] = _M_w[__n + __wshift]; else { const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD - __offset); for (size_t __n = 0; __n < __limit; ++__n) _M_w[__n] = ((_M_w[__n + __wshift] >> __offset) | (_M_w[__n + __wshift + 1] << __sub_offset)); _M_w[__limit] = _M_w[_Nw-1] >> __offset; } std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); } } template unsigned long _Base_bitset<_Nw>::_M_do_to_ulong() const { for (size_t __i = 1; __i < _Nw; ++__i) if (_M_w[__i]) __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); return _M_w[0]; } #if __cplusplus >= 201103L template unsigned long long _Base_bitset<_Nw>::_M_do_to_ullong() const { const bool __dw = sizeof(unsigned long long) > sizeof(unsigned long); for (size_t __i = 1 + __dw; __i < _Nw; ++__i) if (_M_w[__i]) __throw_overflow_error(__N("_Base_bitset::_M_do_to_ullong")); if (__dw) return _M_w[0] + (static_cast(_M_w[1]) << _GLIBCXX_BITSET_BITS_PER_WORD); return _M_w[0]; } #endif template size_t _Base_bitset<_Nw>:: _M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) { _WordT __thisword = _M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + __builtin_ctzl(__thisword)); } // not found, so return an indication of failure. return __not_found; } template size_t _Base_bitset<_Nw>:: _M_do_find_next(size_t __prev, size_t __not_found) const _GLIBCXX_NOEXCEPT { // make bound inclusive ++__prev; // check out of bounds if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) return __not_found; // search first word size_t __i = _S_whichword(__prev); _WordT __thisword = _M_w[__i]; // mask off bits below bound __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); if (__thisword != static_cast<_WordT>(0)) return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + __builtin_ctzl(__thisword)); // check subsequent words __i++; for (; __i < _Nw; __i++) { __thisword = _M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + __builtin_ctzl(__thisword)); } // not found, so return an indication of failure. return __not_found; } // end _M_do_find_next /** * Base class, specialization for a single word. * * See documentation for bitset. */ template<> struct _Base_bitset<1> { typedef unsigned long _WordT; _WordT _M_w; _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT : _M_w(0) { } #if __cplusplus >= 201103L constexpr _Base_bitset(unsigned long long __val) noexcept #else _Base_bitset(unsigned long __val) #endif : _M_w(__val) { } static _GLIBCXX_CONSTEXPR size_t _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR size_t _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static _GLIBCXX_CONSTEXPR size_t _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR _WordT _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } _WordT& _M_getword(size_t) _GLIBCXX_NOEXCEPT { return _M_w; } _GLIBCXX_CONSTEXPR _WordT _M_getword(size_t) const _GLIBCXX_NOEXCEPT { return _M_w; } #if __cplusplus >= 201103L const _WordT* _M_getdata() const noexcept { return &_M_w; } #endif _WordT& _M_hiword() _GLIBCXX_NOEXCEPT { return _M_w; } _GLIBCXX_CONSTEXPR _WordT _M_hiword() const _GLIBCXX_NOEXCEPT { return _M_w; } void _M_do_and(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT { _M_w &= __x._M_w; } void _M_do_or(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT { _M_w |= __x._M_w; } void _M_do_xor(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT { _M_w ^= __x._M_w; } void _M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT { _M_w <<= __shift; } void _M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT { _M_w >>= __shift; } void _M_do_flip() _GLIBCXX_NOEXCEPT { _M_w = ~_M_w; } void _M_do_set() _GLIBCXX_NOEXCEPT { _M_w = ~static_cast<_WordT>(0); } void _M_do_reset() _GLIBCXX_NOEXCEPT { _M_w = 0; } bool _M_is_equal(const _Base_bitset<1>& __x) const _GLIBCXX_NOEXCEPT { return _M_w == __x._M_w; } template bool _M_are_all() const _GLIBCXX_NOEXCEPT { return _M_w == (~static_cast<_WordT>(0) >> (_GLIBCXX_BITSET_BITS_PER_WORD - _Nb)); } bool _M_is_any() const _GLIBCXX_NOEXCEPT { return _M_w != 0; } size_t _M_do_count() const _GLIBCXX_NOEXCEPT { return __builtin_popcountl(_M_w); } unsigned long _M_do_to_ulong() const _GLIBCXX_NOEXCEPT { return _M_w; } #if __cplusplus >= 201103L unsigned long long _M_do_to_ullong() const noexcept { return _M_w; } #endif size_t _M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT { if (_M_w != 0) return __builtin_ctzl(_M_w); else return __not_found; } // find the next "on" bit that follows "prev" size_t _M_do_find_next(size_t __prev, size_t __not_found) const _GLIBCXX_NOEXCEPT { ++__prev; if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) return __not_found; _WordT __x = _M_w >> __prev; if (__x != 0) return __builtin_ctzl(__x) + __prev; else return __not_found; } }; /** * Base class, specialization for no storage (zero-length %bitset). * * See documentation for bitset. */ template<> struct _Base_bitset<0> { typedef unsigned long _WordT; _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT { } #if __cplusplus >= 201103L constexpr _Base_bitset(unsigned long long) noexcept #else _Base_bitset(unsigned long) #endif { } static _GLIBCXX_CONSTEXPR size_t _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR size_t _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static _GLIBCXX_CONSTEXPR size_t _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR _WordT _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } // This would normally give access to the data. The bounds-checking // in the bitset class will prevent the user from getting this far, // but (1) it must still return an lvalue to compile, and (2) the // user might call _Unchecked_set directly, in which case this /needs/ // to fail. Let's not penalize zero-length users unless they actually // make an unchecked call; all the memory ugliness is therefore // localized to this single should-never-get-this-far function. _WordT& _M_getword(size_t) _GLIBCXX_NOEXCEPT { __throw_out_of_range(__N("_Base_bitset::_M_getword")); return *new _WordT; } _GLIBCXX_CONSTEXPR _WordT _M_getword(size_t) const _GLIBCXX_NOEXCEPT { return 0; } _GLIBCXX_CONSTEXPR _WordT _M_hiword() const _GLIBCXX_NOEXCEPT { return 0; } void _M_do_and(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT { } void _M_do_or(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT { } void _M_do_xor(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT { } void _M_do_left_shift(size_t) _GLIBCXX_NOEXCEPT { } void _M_do_right_shift(size_t) _GLIBCXX_NOEXCEPT { } void _M_do_flip() _GLIBCXX_NOEXCEPT { } void _M_do_set() _GLIBCXX_NOEXCEPT { } void _M_do_reset() _GLIBCXX_NOEXCEPT { } // Are all empty bitsets equal to each other? Are they equal to // themselves? How to compare a thing which has no state? What is // the sound of one zero-length bitset clapping? bool _M_is_equal(const _Base_bitset<0>&) const _GLIBCXX_NOEXCEPT { return true; } template bool _M_are_all() const _GLIBCXX_NOEXCEPT { return true; } bool _M_is_any() const _GLIBCXX_NOEXCEPT { return false; } size_t _M_do_count() const _GLIBCXX_NOEXCEPT { return 0; } unsigned long _M_do_to_ulong() const _GLIBCXX_NOEXCEPT { return 0; } #if __cplusplus >= 201103L unsigned long long _M_do_to_ullong() const noexcept { return 0; } #endif // Normally "not found" is the size, but that could also be // misinterpreted as an index in this corner case. Oh well. size_t _M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT { return 0; } size_t _M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT { return 0; } }; // Helper class to zero out the unused high-order bits in the highest word. template struct _Sanitize { typedef unsigned long _WordT; static void _S_do_sanitize(_WordT& __val) _GLIBCXX_NOEXCEPT { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); } }; template<> struct _Sanitize<0> { typedef unsigned long _WordT; static void _S_do_sanitize(_WordT) _GLIBCXX_NOEXCEPT { } }; #if __cplusplus >= 201103L template struct _Sanitize_val { static constexpr unsigned long long _S_do_sanitize_val(unsigned long long __val) { return __val; } }; template struct _Sanitize_val<_Nb, true> { static constexpr unsigned long long _S_do_sanitize_val(unsigned long long __val) { return __val & ~((~static_cast(0)) << _Nb); } }; #endif /** * @brief The %bitset class represents a @e fixed-size sequence of bits. * @ingroup utilities * * (Note that %bitset does @e not meet the formal requirements of a * container. Mainly, it lacks iterators.) * * The template argument, @a Nb, may be any non-negative number, * specifying the number of bits (e.g., "0", "12", "1024*1024"). * * In the general unoptimized case, storage is allocated in word-sized * blocks. Let B be the number of bits in a word, then (Nb+(B-1))/B * words will be used for storage. B - Nb%B bits are unused. (They are * the high-order bits in the highest word.) It is a class invariant * that those unused bits are always zero. * * If you think of %bitset as a simple array of bits, be * aware that your mental picture is reversed: a %bitset behaves * the same way as bits in integers do, with the bit at index 0 in * the least significant / right-hand position, and the bit at * index Nb-1 in the most significant / left-hand position. * Thus, unlike other containers, a %bitset's index counts from * right to left, to put it very loosely. * * This behavior is preserved when translating to and from strings. For * example, the first line of the following program probably prints * b('a') is 0001100001 on a modern ASCII system. * * @code * #include * #include * #include * * using namespace std; * * int main() * { * long a = 'a'; * bitset<10> b(a); * * cout << "b('a') is " << b << endl; * * ostringstream s; * s << b; * string str = s.str(); * cout << "index 3 in the string is " << str[3] << " but\n" * << "index 3 in the bitset is " << b[3] << endl; * } * @endcode * * Also see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_containers.html * for a description of extensions. * * Most of the actual code isn't contained in %bitset<> itself, but in the * base class _Base_bitset. The base class works with whole words, not with * individual bits. This allows us to specialize _Base_bitset for the * important special case where the %bitset is only a single word. * * Extra confusion can result due to the fact that the storage for * _Base_bitset @e is a regular array, and is indexed as such. This is * carefully encapsulated. */ template class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { private: typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; typedef unsigned long _WordT; template void _M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position) const { if (__position > __s.size()) __throw_out_of_range_fmt(__N("bitset::bitset: __position " "(which is %zu) > __s.size() " "(which is %zu)"), __position, __s.size()); } void _M_check(size_t __position, const char *__s) const { if (__position >= _Nb) __throw_out_of_range_fmt(__N("%s: __position (which is %zu) " ">= _Nb (which is %zu)"), __s, __position, _Nb); } void _M_do_sanitize() _GLIBCXX_NOEXCEPT { typedef _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD> __sanitize_type; __sanitize_type::_S_do_sanitize(this->_M_hiword()); } #if __cplusplus >= 201103L friend struct std::hash; #endif public: /** * This encapsulates the concept of a single bit. An instance of this * class is a proxy for an actual bit; this way the individual bit * operations are done as faster word-size bitwise instructions. * * Most users will never need to use this class directly; conversions * to and from bool are automatic and should be transparent. Overloaded * operators help to preserve the illusion. * * (On a typical system, this bit %reference is 64 * times the size of an actual bit. Ha.) */ class reference { friend class bitset; _WordT* _M_wp; size_t _M_bpos; // left undefined reference(); public: reference(bitset& __b, size_t __pos) _GLIBCXX_NOEXCEPT { _M_wp = &__b._M_getword(__pos); _M_bpos = _Base::_S_whichbit(__pos); } ~reference() _GLIBCXX_NOEXCEPT { } // For b[i] = __x; reference& operator=(bool __x) _GLIBCXX_NOEXCEPT { if (__x) *_M_wp |= _Base::_S_maskbit(_M_bpos); else *_M_wp &= ~_Base::_S_maskbit(_M_bpos); return *this; } // For b[i] = b[__j]; reference& operator=(const reference& __j) _GLIBCXX_NOEXCEPT { if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) *_M_wp |= _Base::_S_maskbit(_M_bpos); else *_M_wp &= ~_Base::_S_maskbit(_M_bpos); return *this; } // Flips the bit bool operator~() const _GLIBCXX_NOEXCEPT { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } // For __x = b[i]; operator bool() const _GLIBCXX_NOEXCEPT { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } // For b[i].flip(); reference& flip() _GLIBCXX_NOEXCEPT { *_M_wp ^= _Base::_S_maskbit(_M_bpos); return *this; } }; friend class reference; // 23.3.5.1 constructors: /// All bits set to zero. _GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT { } /// Initial bits bitwise-copied from a single word (others set to zero). #if __cplusplus >= 201103L constexpr bitset(unsigned long long __val) noexcept : _Base(_Sanitize_val<_Nb>::_S_do_sanitize_val(__val)) { } #else bitset(unsigned long __val) : _Base(__val) { _M_do_sanitize(); } #endif /** * Use a subset of a string. * @param __s A string of @a 0 and @a 1 characters. * @param __position Index of the first character in @a __s to use; * defaults to zero. * @throw std::out_of_range If @a pos is bigger the size of @a __s. * @throw std::invalid_argument If a character appears in the string * which is neither @a 0 nor @a 1. */ template explicit bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position = 0) : _Base() { _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, std::basic_string<_CharT, _Traits, _Alloc>::npos, _CharT('0'), _CharT('1')); } /** * Use a subset of a string. * @param __s A string of @a 0 and @a 1 characters. * @param __position Index of the first character in @a __s to use. * @param __n The number of characters to copy. * @throw std::out_of_range If @a __position is bigger the size * of @a __s. * @throw std::invalid_argument If a character appears in the string * which is neither @a 0 nor @a 1. */ template bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position, size_t __n) : _Base() { _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1')); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. template bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position, size_t __n, _CharT __zero, _CharT __one = _CharT('1')) : _Base() { _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, __n, __zero, __one); } #if __cplusplus >= 201103L /** * Construct from a character %array. * @param __str An %array of characters @a zero and @a one. * @param __n The number of characters to use. * @param __zero The character corresponding to the value 0. * @param __one The character corresponding to the value 1. * @throw std::invalid_argument If a character appears in the string * which is neither @a __zero nor @a __one. */ template explicit bitset(const _CharT* __str, typename std::basic_string<_CharT>::size_type __n = std::basic_string<_CharT>::npos, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) : _Base() { if (!__str) __throw_logic_error(__N("bitset::bitset(const _CharT*, ...)")); if (__n == std::basic_string<_CharT>::npos) __n = std::char_traits<_CharT>::length(__str); _M_copy_from_ptr<_CharT, std::char_traits<_CharT>>(__str, __n, 0, __n, __zero, __one); } #endif // 23.3.5.2 bitset operations: //@{ /** * Operations on bitsets. * @param __rhs A same-sized bitset. * * These should be self-explanatory. */ bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { this->_M_do_and(__rhs); return *this; } bitset<_Nb>& operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { this->_M_do_or(__rhs); return *this; } bitset<_Nb>& operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { this->_M_do_xor(__rhs); return *this; } //@} //@{ /** * Operations on bitsets. * @param __position The number of places to shift. * * These should be self-explanatory. */ bitset<_Nb>& operator<<=(size_t __position) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__position < _Nb, 1)) { this->_M_do_left_shift(__position); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } bitset<_Nb>& operator>>=(size_t __position) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__position < _Nb, 1)) { this->_M_do_right_shift(__position); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } //@} //@{ /** * These versions of single-bit set, reset, flip, and test are * extensions from the SGI version. They do no range checking. * @ingroup SGIextensions */ bitset<_Nb>& _Unchecked_set(size_t __pos) _GLIBCXX_NOEXCEPT { this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); return *this; } bitset<_Nb>& _Unchecked_set(size_t __pos, int __val) _GLIBCXX_NOEXCEPT { if (__val) this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); else this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } bitset<_Nb>& _Unchecked_reset(size_t __pos) _GLIBCXX_NOEXCEPT { this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } bitset<_Nb>& _Unchecked_flip(size_t __pos) _GLIBCXX_NOEXCEPT { this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); return *this; } _GLIBCXX_CONSTEXPR bool _Unchecked_test(size_t __pos) const _GLIBCXX_NOEXCEPT { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) != static_cast<_WordT>(0)); } //@} // Set, reset, and flip. /** * @brief Sets every bit to true. */ bitset<_Nb>& set() _GLIBCXX_NOEXCEPT { this->_M_do_set(); this->_M_do_sanitize(); return *this; } /** * @brief Sets a given bit to a particular value. * @param __position The index of the bit. * @param __val Either true or false, defaults to true. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bitset<_Nb>& set(size_t __position, bool __val = true) { this->_M_check(__position, __N("bitset::set")); return _Unchecked_set(__position, __val); } /** * @brief Sets every bit to false. */ bitset<_Nb>& reset() _GLIBCXX_NOEXCEPT { this->_M_do_reset(); return *this; } /** * @brief Sets a given bit to false. * @param __position The index of the bit. * @throw std::out_of_range If @a pos is bigger the size of the %set. * * Same as writing @c set(pos,false). */ bitset<_Nb>& reset(size_t __position) { this->_M_check(__position, __N("bitset::reset")); return _Unchecked_reset(__position); } /** * @brief Toggles every bit to its opposite value. */ bitset<_Nb>& flip() _GLIBCXX_NOEXCEPT { this->_M_do_flip(); this->_M_do_sanitize(); return *this; } /** * @brief Toggles a given bit to its opposite value. * @param __position The index of the bit. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bitset<_Nb>& flip(size_t __position) { this->_M_check(__position, __N("bitset::flip")); return _Unchecked_flip(__position); } /// See the no-argument flip(). bitset<_Nb> operator~() const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(*this).flip(); } //@{ /** * @brief Array-indexing support. * @param __position Index into the %bitset. * @return A bool for a const %bitset. For non-const * bitsets, an instance of the reference proxy class. * @note These operators do no range checking and throw no exceptions, * as required by DR 11 to the standard. * * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already * resolves DR 11 (items 1 and 2), but does not do the range-checking * required by that DR's resolution. -pme * The DR has since been changed: range-checking is a precondition * (users' responsibility), and these functions must not throw. -pme */ reference operator[](size_t __position) { return reference(*this, __position); } _GLIBCXX_CONSTEXPR bool operator[](size_t __position) const { return _Unchecked_test(__position); } //@} /** * @brief Returns a numerical interpretation of the %bitset. * @return The integral equivalent of the bits. * @throw std::overflow_error If there are too many bits to be * represented in an @c unsigned @c long. */ unsigned long to_ulong() const { return this->_M_do_to_ulong(); } #if __cplusplus >= 201103L unsigned long long to_ullong() const { return this->_M_do_to_ullong(); } #endif /** * @brief Returns a character interpretation of the %bitset. * @return The string equivalent of the bits. * * Note the ordering of the bits: decreasing character positions * correspond to increasing bit positions (see the main class notes for * an example). */ template std::basic_string<_CharT, _Traits, _Alloc> to_string() const { std::basic_string<_CharT, _Traits, _Alloc> __result; _M_copy_to_string(__result, _CharT('0'), _CharT('1')); return __result; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. template std::basic_string<_CharT, _Traits, _Alloc> to_string(_CharT __zero, _CharT __one = _CharT('1')) const { std::basic_string<_CharT, _Traits, _Alloc> __result; _M_copy_to_string(__result, __zero, __one); return __result; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 434. bitset::to_string() hard to use. template std::basic_string<_CharT, _Traits, std::allocator<_CharT> > to_string() const { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 853. to_string needs updating with zero and one. template std::basic_string<_CharT, _Traits, std::allocator<_CharT> > to_string(_CharT __zero, _CharT __one = _CharT('1')) const { return to_string<_CharT, _Traits, std::allocator<_CharT> >(__zero, __one); } template std::basic_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> > to_string() const { return to_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> >(); } template std::basic_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> > to_string(_CharT __zero, _CharT __one = _CharT('1')) const { return to_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> >(__zero, __one); } std::basic_string, std::allocator > to_string() const { return to_string, std::allocator >(); } std::basic_string, std::allocator > to_string(char __zero, char __one = '1') const { return to_string, std::allocator >(__zero, __one); } // Helper functions for string operations. template void _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, _CharT, _CharT); template void _M_copy_from_string(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos, size_t __n, _CharT __zero, _CharT __one) { _M_copy_from_ptr<_CharT, _Traits>(__s.data(), __s.size(), __pos, __n, __zero, __one); } template void _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&, _CharT, _CharT) const; // NB: Backward compat. template void _M_copy_from_string(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos, size_t __n) { _M_copy_from_string(__s, __pos, __n, _CharT('0'), _CharT('1')); } template void _M_copy_to_string(std::basic_string<_CharT, _Traits,_Alloc>& __s) const { _M_copy_to_string(__s, _CharT('0'), _CharT('1')); } /// Returns the number of bits which are set. size_t count() const _GLIBCXX_NOEXCEPT { return this->_M_do_count(); } /// Returns the total number of bits. _GLIBCXX_CONSTEXPR size_t size() const _GLIBCXX_NOEXCEPT { return _Nb; } //@{ /// These comparisons for equality/inequality are, well, @e bitwise. bool operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return this->_M_is_equal(__rhs); } bool operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return !this->_M_is_equal(__rhs); } //@} /** * @brief Tests the value of a bit. * @param __position The index of a bit. * @return The value at @a pos. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bool test(size_t __position) const { this->_M_check(__position, __N("bitset::test")); return _Unchecked_test(__position); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 693. std::bitset::all() missing. /** * @brief Tests whether all the bits are on. * @return True if all the bits are set. */ bool all() const _GLIBCXX_NOEXCEPT { return this->template _M_are_all<_Nb>(); } /** * @brief Tests whether any of the bits are on. * @return True if at least one bit is set. */ bool any() const _GLIBCXX_NOEXCEPT { return this->_M_is_any(); } /** * @brief Tests whether any of the bits are on. * @return True if none of the bits are set. */ bool none() const _GLIBCXX_NOEXCEPT { return !this->_M_is_any(); } //@{ /// Self-explanatory. bitset<_Nb> operator<<(size_t __position) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(*this) <<= __position; } bitset<_Nb> operator>>(size_t __position) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(*this) >>= __position; } //@} /** * @brief Finds the index of the first "on" bit. * @return The index of the first bit set, or size() if not found. * @ingroup SGIextensions * @sa _Find_next */ size_t _Find_first() const _GLIBCXX_NOEXCEPT { return this->_M_do_find_first(_Nb); } /** * @brief Finds the index of the next "on" bit after prev. * @return The index of the next bit set, or size() if not found. * @param __prev Where to start searching. * @ingroup SGIextensions * @sa _Find_first */ size_t _Find_next(size_t __prev) const _GLIBCXX_NOEXCEPT { return this->_M_do_find_next(__prev, _Nb); } }; // Definitions of non-inline member functions. template template void bitset<_Nb>:: _M_copy_from_ptr(const _CharT* __s, size_t __len, size_t __pos, size_t __n, _CharT __zero, _CharT __one) { reset(); const size_t __nbits = std::min(_Nb, std::min(__n, size_t(__len - __pos))); for (size_t __i = __nbits; __i > 0; --__i) { const _CharT __c = __s[__pos + __nbits - __i]; if (_Traits::eq(__c, __zero)) ; else if (_Traits::eq(__c, __one)) _Unchecked_set(__i - 1); else __throw_invalid_argument(__N("bitset::_M_copy_from_ptr")); } } template template void bitset<_Nb>:: _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s, _CharT __zero, _CharT __one) const { __s.assign(_Nb, __zero); for (size_t __i = _Nb; __i > 0; --__i) if (_Unchecked_test(__i - 1)) _Traits::assign(__s[_Nb - __i], __one); } // 23.3.5.3 bitset operations: //@{ /** * @brief Global bitwise operations on bitsets. * @param __x A bitset. * @param __y A bitset of the same size as @a __x. * @return A new bitset. * * These should be self-explanatory. */ template inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { bitset<_Nb> __result(__x); __result &= __y; return __result; } template inline bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { bitset<_Nb> __result(__x); __result |= __y; return __result; } template inline bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { bitset<_Nb> __result(__x); __result ^= __y; return __result; } //@} //@{ /** * @brief Global I/O operators for bitsets. * * Direct I/O between streams and bitsets is supported. Output is * straightforward. Input will skip whitespace, only accept @a 0 and @a 1 * characters, and will only extract as many digits as the %bitset will * hold. */ template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) { typedef typename _Traits::char_type char_type; typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; std::basic_string<_CharT, _Traits> __tmp; __tmp.reserve(_Nb); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 303. Bitset input operator underspecified const char_type __zero = __is.widen('0'); const char_type __one = __is.widen('1'); typename __ios_base::iostate __state = __ios_base::goodbit; typename __istream_type::sentry __sentry(__is); if (__sentry) { __try { for (size_t __i = _Nb; __i > 0; --__i) { static typename _Traits::int_type __eof = _Traits::eof(); typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); if (_Traits::eq_int_type(__c1, __eof)) { __state |= __ios_base::eofbit; break; } else { const char_type __c2 = _Traits::to_char_type(__c1); if (_Traits::eq(__c2, __zero)) __tmp.push_back(__zero); else if (_Traits::eq(__c2, __one)) __tmp.push_back(__one); else if (_Traits:: eq_int_type(__is.rdbuf()->sputbackc(__c2), __eof)) { __state |= __ios_base::failbit; break; } } } } __catch(__cxxabiv1::__forced_unwind&) { __is._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { __is._M_setstate(__ios_base::badbit); } } if (__tmp.empty() && _Nb) __state |= __ios_base::failbit; else __x._M_copy_from_string(__tmp, static_cast(0), _Nb, __zero, __one); if (__state) __is.setstate(__state); return __is; } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) { std::basic_string<_CharT, _Traits> __tmp; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. const ctype<_CharT>& __ct = use_facet >(__os.getloc()); __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); return __os << __tmp; } //@} _GLIBCXX_END_NAMESPACE_CONTAINER } // namespace std #undef _GLIBCXX_BITSET_WORDS #undef _GLIBCXX_BITSET_BITS_PER_WORD #undef _GLIBCXX_BITSET_BITS_PER_ULL #if __cplusplus >= 201103L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 1182. /// std::hash specialization for bitset. template struct hash<_GLIBCXX_STD_C::bitset<_Nb>> : public __hash_base> { size_t operator()(const _GLIBCXX_STD_C::bitset<_Nb>& __b) const noexcept { const size_t __clength = (_Nb + __CHAR_BIT__ - 1) / __CHAR_BIT__; return std::_Hash_impl::hash(__b._M_getdata(), __clength); } }; template<> struct hash<_GLIBCXX_STD_C::bitset<0>> : public __hash_base> { size_t operator()(const _GLIBCXX_STD_C::bitset<0>&) const noexcept { return 0; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif /* _GLIBCXX_BITSET */ PKgd1]44=gg8/memorynu[// -*- C++ -*- // Copyright (C) 2001-2018 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) 1997-1999 * 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 include/memory * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_MEMORY #define _GLIBCXX_MEMORY 1 #pragma GCC system_header /** * @defgroup memory Memory * @ingroup utilities * * Components for memory allocation, deallocation, and management. */ /** * @defgroup pointer_abstractions Pointer Abstractions * @ingroup memory * * Smart pointers, etc. */ #include #include #include #include #include #include #if __cplusplus >= 201103L # include // std::exception # include // std::type_info in get_deleter # include // std::basic_ostream # include # include # include # include // std::less # include # include # include # include # include # include # if _GLIBCXX_USE_DEPRECATED # include # endif #else # include #endif #if __cplusplus >= 201103L # include # ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Fit aligned storage in buffer. * * [ptr.align] * * This function tries to fit @a __size bytes of storage with alignment * @a __align into the buffer @a __ptr of size @a __space bytes. If such * a buffer fits then @a __ptr is changed to point to the first byte of the * aligned storage and @a __space is reduced by the bytes used for alignment. * * @param __align A fundamental or extended alignment value. * @param __size Size of the aligned storage required. * @param __ptr Pointer to a buffer of @a __space bytes. * @param __space Size of the buffer pointed to by @a __ptr. * @return the updated pointer if the aligned storage fits, otherwise nullptr. */ inline void* align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept { const auto __intptr = reinterpret_cast(__ptr); const auto __aligned = (__intptr - 1u + __align) & -__align; const auto __diff = __aligned - __intptr; if ((__size + __diff) > __space) return nullptr; else { __space -= __diff; return __ptr = reinterpret_cast(__aligned); } } // 20.7.4 [util.dynamic.safety], pointer safety enum class pointer_safety { relaxed, preferred, strict }; inline void declare_reachable(void*) { } template inline _Tp* undeclare_reachable(_Tp* __p) { return __p; } inline void declare_no_pointers(char*, size_t) { } inline void undeclare_no_pointers(char*, size_t) { } inline pointer_safety get_pointer_safety() noexcept { return pointer_safety::relaxed; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif /* _GLIBCXX_MEMORY */ PKgd1](BOMM8/ctimenu[// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/ctime * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c time.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.5 Date and time // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CTIME #define _GLIBCXX_CTIME 1 // Get rid of those macros defined in in lieu of real functions. #undef clock #undef difftime #undef mktime #undef time #undef asctime #undef ctime #undef gmtime #undef localtime #undef strftime namespace std { using ::clock_t; using ::time_t; using ::tm; using ::clock; using ::difftime; using ::mktime; using ::time; using ::asctime; using ::ctime; using ::gmtime; using ::localtime; using ::strftime; } // namespace #endif PKgd1]iC 8/stdlib.hnu[// -*- C++ -*- compatibility header. // Copyright (C) 2002-2018 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 stdlib.h * This is a Standard C++ Library header. */ #if !defined __cplusplus || defined _GLIBCXX_INCLUDE_NEXT_C_HEADERS # include_next #else #ifndef _GLIBCXX_STDLIB_H #define _GLIBCXX_STDLIB_H 1 # include using std::abort; using std::atexit; using std::exit; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT using std::at_quick_exit; # endif # ifdef _GLIBCXX_HAVE_QUICK_EXIT using std::quick_exit; # endif #endif #if _GLIBCXX_HOSTED using std::div_t; using std::ldiv_t; using std::abs; using std::atof; using std::atoi; using std::atol; using std::bsearch; using std::calloc; using std::div; using std::free; using std::getenv; using std::labs; using std::ldiv; using std::malloc; #ifdef _GLIBCXX_HAVE_MBSTATE_T using std::mblen; using std::mbstowcs; using std::mbtowc; #endif // _GLIBCXX_HAVE_MBSTATE_T using std::qsort; using std::rand; using std::realloc; using std::srand; using std::strtod; using std::strtol; using std::strtoul; using std::system; #ifdef _GLIBCXX_USE_WCHAR_T using std::wcstombs; using std::wctomb; #endif // _GLIBCXX_USE_WCHAR_T #endif #endif // _GLIBCXX_STDLIB_H #endif // __cplusplus PKgd1]ui i 8/dequenu[// -*- C++ -*- // Copyright (C) 2001-2018 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) 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 include/deque * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_DEQUE #define _GLIBCXX_DEQUE 1 #pragma GCC system_header #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif /* _GLIBCXX_DEQUE */ PKgd1]bȝ 8/ext/atomicity.hnu[// Support for atomic operations -*- C++ -*- // Copyright (C) 2004-2018 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/atomicity.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _GLIBCXX_ATOMICITY_H #define _GLIBCXX_ATOMICITY_H 1 #pragma GCC system_header #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Functions for portable atomic access. // To abstract locking primitives across all thread policies, use: // __exchange_and_add_dispatch // __atomic_add_dispatch #ifdef _GLIBCXX_ATOMIC_BUILTINS static inline _Atomic_word __exchange_and_add(volatile _Atomic_word* __mem, int __val) { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } static inline void __atomic_add(volatile _Atomic_word* __mem, int __val) { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } #else _Atomic_word __attribute__ ((__unused__)) __exchange_and_add(volatile _Atomic_word*, int) throw (); void __attribute__ ((__unused__)) __atomic_add(volatile _Atomic_word*, int) throw (); #endif static inline _Atomic_word __exchange_and_add_single(_Atomic_word* __mem, int __val) { _Atomic_word __result = *__mem; *__mem += __val; return __result; } static inline void __atomic_add_single(_Atomic_word* __mem, int __val) { *__mem += __val; } static inline _Atomic_word __attribute__ ((__unused__)) __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) { #ifdef __GTHREADS if (__gthread_active_p()) return __exchange_and_add(__mem, __val); else return __exchange_and_add_single(__mem, __val); #else return __exchange_and_add_single(__mem, __val); #endif } static inline void __attribute__ ((__unused__)) __atomic_add_dispatch(_Atomic_word* __mem, int __val) { #ifdef __GTHREADS if (__gthread_active_p()) __atomic_add(__mem, __val); else __atomic_add_single(__mem, __val); #else __atomic_add_single(__mem, __val); #endif } _GLIBCXX_END_NAMESPACE_VERSION } // namespace // Even if the CPU doesn't need a memory barrier, we need to ensure // that the compiler doesn't reorder memory accesses across the // barriers. #ifndef _GLIBCXX_READ_MEM_BARRIER #define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE) #endif #ifndef _GLIBCXX_WRITE_MEM_BARRIER #define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE) #endif #endif PKgd1]t 8/ext/iteratornu[// HP/SGI iterator extensions -*- C++ -*- // Copyright (C) 2001-2018 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 ext/iterator * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ITERATOR #define _EXT_ITERATOR 1 #pragma GCC system_header #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // There are two signatures for distance. In addition to the one // taking two iterators and returning a result, there is another // taking two iterators and a reference-to-result variable, and // returning nothing. The latter seems to be an SGI extension. // -- pedwards template inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, std::input_iterator_tag) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) while (__first != __last) { ++__first; ++__n; } } template inline void __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, std::random_access_iterator_tag) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __n += __last - __first; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline void distance(_InputIterator __first, _InputIterator __last, _Distance& __n) { // concept requirements -- taken care of in __distance __distance(__first, __last, __n, std::__iterator_category(__first)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]_8/ext/new_allocator.hnu[// Allocator that wraps operator new -*- C++ -*- // Copyright (C) 2001-2018 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 #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* = static_cast(0)) { if (__n > this->max_size()) std::__throw_bad_alloc(); #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al)); } #endif return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type) { #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif ::operator delete(__p); } 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 PKgd1]820## 8/ext/randomnu[// Random number extensions -*- C++ -*- // Copyright (C) 2012-2018 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/random * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_RANDOM #define _EXT_RANDOM 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #ifdef __SSE2__ # include #endif #if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C) namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Mersenne twister implementation optimized for vector operations. * * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ */ template class simd_fast_mersenne_twister_engine { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__sr1 < 32, "first right shift too large"); static_assert(__sr2 < 16, "second right shift too large"); static_assert(__sl1 < 32, "first left shift too large"); static_assert(__sl2 < 16, "second left shift too large"); public: typedef _UIntType result_type; private: static constexpr size_t m_w = sizeof(result_type) * 8; static constexpr size_t _M_nstate = __m / 128 + 1; static constexpr size_t _M_nstate32 = _M_nstate * 4; static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); static_assert(16 % sizeof(_UIntType) == 0, "UIntType size must divide 16"); public: static constexpr size_t state_size = _M_nstate * (16 / sizeof(result_type)); static constexpr result_type default_seed = 5489u; // constructors and member function explicit simd_fast_mersenne_twister_engine(result_type __sd = default_seed) { seed(__sd); } template::value> ::type> explicit simd_fast_mersenne_twister_engine(_Sseq& __q) { seed(__q); } void seed(result_type __sd = default_seed); template typename std::enable_if::value>::type seed(_Sseq& __q); static constexpr result_type min() { return 0; } static constexpr result_type max() { return std::numeric_limits::max(); } void discard(unsigned long long __z); result_type operator()() { if (__builtin_expect(_M_pos >= state_size, 0)) _M_gen_rand(); return _M_stateT[_M_pos++]; } template friend bool operator==(const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs, const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs); template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine <_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); private: union { #ifdef __SSE2__ __m128i _M_state[_M_nstate]; #endif #ifdef __ARM_NEON #ifdef __aarch64__ __Uint32x4_t _M_state[_M_nstate]; #endif #endif uint32_t _M_state32[_M_nstate32]; result_type _M_stateT[state_size]; } __attribute__ ((__aligned__ (16))); size_t _M_pos; void _M_gen_rand(void); void _M_period_certification(); }; template inline bool operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { return !(__lhs == __rhs); } /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined * in the C implementation by Daito and Matsumoto, as both a 32-bit * and 64-bit version. */ typedef simd_fast_mersenne_twister_engine sfmt607; typedef simd_fast_mersenne_twister_engine sfmt607_64; typedef simd_fast_mersenne_twister_engine sfmt1279; typedef simd_fast_mersenne_twister_engine sfmt1279_64; typedef simd_fast_mersenne_twister_engine sfmt2281; typedef simd_fast_mersenne_twister_engine sfmt2281_64; typedef simd_fast_mersenne_twister_engine sfmt4253; typedef simd_fast_mersenne_twister_engine sfmt4253_64; typedef simd_fast_mersenne_twister_engine sfmt11213; typedef simd_fast_mersenne_twister_engine sfmt11213_64; typedef simd_fast_mersenne_twister_engine sfmt19937; typedef simd_fast_mersenne_twister_engine sfmt19937_64; typedef simd_fast_mersenne_twister_engine sfmt44497; typedef simd_fast_mersenne_twister_engine sfmt44497_64; typedef simd_fast_mersenne_twister_engine sfmt86243; typedef simd_fast_mersenne_twister_engine sfmt86243_64; typedef simd_fast_mersenne_twister_engine sfmt132049; typedef simd_fast_mersenne_twister_engine sfmt132049_64; typedef simd_fast_mersenne_twister_engine sfmt216091; typedef simd_fast_mersenne_twister_engine sfmt216091_64; #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /** * @brief A beta continuous distribution for random numbers. * * The formula for the beta probability density function is: * @f[ * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)} * x^{\alpha - 1} (1 - x)^{\beta - 1} * @f] */ template class beta_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef beta_distribution<_RealType> distribution_type; friend class beta_distribution<_RealType>; explicit param_type(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_alpha(__alpha_val), _M_beta(__beta_val) { __glibcxx_assert(_M_alpha > _RealType(0)); __glibcxx_assert(_M_beta > _RealType(0)); } _RealType alpha() const { return _M_alpha; } _RealType beta() const { return _M_beta; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_alpha == __p2._M_alpha && __p1._M_beta == __p2._M_beta); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); _RealType _M_alpha; _RealType _M_beta; }; public: /** * @brief Constructs a beta distribution with parameters * @f$\alpha@f$ and @f$\beta@f$. */ explicit beta_distribution(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_param(__alpha_val, __beta_val) { } explicit beta_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$\alpha@f$ of the distribution. */ _RealType alpha() const { return _M_param.alpha(); } /** * @brief Returns the @f$\beta@f$ of the distribution. */ _RealType beta() const { return _M_param.beta(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return result_type(1); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two beta distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const beta_distribution& __d1, const beta_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %beta_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %beta_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType1>& __x); /** * @brief Extracts a %beta_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %beta_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two beta distributions are different. */ template inline bool operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1, const __gnu_cxx::beta_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A multi-variate normal continuous distribution for random numbers. * * The formula for the normal probability density function is * @f[ * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) = * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}} * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T} * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})} * @f] * * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance * matrix (which must be positive-definite). */ template class normal_mv_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ class param_type { static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2; public: typedef normal_mv_distribution<_Dimen, _RealType> distribution_type; friend class normal_mv_distribution<_Dimen, _RealType>; param_type() { std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0)); auto __it = _M_t.begin(); for (size_t __i = 0; __i < _Dimen; ++__i) { std::fill_n(__it, __i, _RealType(0)); __it += __i; *__it++ = _RealType(1); } } template param_type(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) { __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator2>) _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend) <= _Dimen); const auto __dist = std::distance(__varcovbegin, __varcovend); _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen || __dist == _Dimen * (_Dimen + 1) / 2 || __dist == _Dimen); if (__dist == _Dimen * _Dimen) _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend); else if (__dist == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend); else { __glibcxx_assert(__dist == _Dimen); _M_init_diagonal(__meanbegin, __meanend, __varcovbegin, __varcovend); } } param_type(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) { _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen); _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen || __varcov.size() == _Dimen * (_Dimen + 1) / 2 || __varcov.size() == _Dimen); if (__varcov.size() == _Dimen * _Dimen) _M_init_full(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else { __glibcxx_assert(__varcov.size() == _Dimen); _M_init_diagonal(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); } } std::array<_RealType, _Dimen> mean() const { return _M_mean; } std::array<_RealType, _M_t_size> varcov() const { return _M_t; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: template void _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template void _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template void _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend); std::array<_RealType, _Dimen> _M_mean; std::array<_RealType, _M_t_size> _M_t; }; public: normal_mv_distribution() : _M_param(), _M_nd() { } template normal_mv_distribution(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend), _M_nd() { } normal_mv_distribution(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) : _M_param(__mean, __varcov), _M_nd() { } explicit normal_mv_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the mean of the distribution. */ result_type mean() const { return _M_param.mean(); } /** * @brief Returns the compact form of the variance/covariance * matrix of the distribution. */ std::array<_RealType, _Dimen * (_Dimen + 1) / 2> varcov() const { return _M_param.varcov(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::lowest()); return __res; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::max()); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { return this->__generate_impl(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { return this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two multi-variant normal distributions have * the same parameters and the sequences that would * be generated are equal. */ template friend bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d2); /** * @brief Inserts a %normal_mv_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %normal_mv_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %normal_mv_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %normal_mv_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two multi-variate normal distributions are * different. */ template inline bool operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Rice continuous distribution for random numbers. * * The formula for the Rice probability density function is * @f[ * p(x|\nu,\sigma) = \frac{x}{\sigma^2} * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right) * I_0\left(\frac{x \nu}{\sigma^2}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$
Variance@f$2\sigma^2 + \nu^2 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$
Range@f$[0, \infty)@f$
* where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2. */ template class rice_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef rice_distribution distribution_type; param_type(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_nu(__nu_val), _M_sigma(__sigma_val) { __glibcxx_assert(_M_nu >= result_type(0)); __glibcxx_assert(_M_sigma > result_type(0)); } result_type nu() const { return _M_nu; } result_type sigma() const { return _M_sigma; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_nu; result_type _M_sigma; }; /** * @brief Constructors. */ explicit rice_distribution(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_param(__nu_val, __sigma_val), _M_ndx(__nu_val, __sigma_val), _M_ndy(result_type(0), __sigma_val) { } explicit rice_distribution(const param_type& __p) : _M_param(__p), _M_ndx(__p.nu(), __p.sigma()), _M_ndy(result_type(0), __p.sigma()) { } /** * @brief Resets the distribution state. */ void reset() { _M_ndx.reset(); _M_ndy.reset(); } /** * @brief Return the parameters of the distribution. */ result_type nu() const { return _M_param.nu(); } result_type sigma() const { return _M_param.sigma(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ndx(__urng); result_type __y = this->_M_ndy(__urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::normal_distribution::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Rice distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const rice_distribution& __d1, const rice_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ndx == __d2._M_ndx && __d1._M_ndy == __d2._M_ndy); } /** * @brief Inserts a %rice_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %rice_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const rice_distribution<_RealType1>&); /** * @brief Extracts a %rice_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %rice_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, rice_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution _M_ndx; std::normal_distribution _M_ndy; }; /** * @brief Return true if two Rice distributions are not equal. */ template inline bool operator!=(const rice_distribution<_RealType1>& __d1, const rice_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A Nakagami continuous distribution for random numbers. * * The formula for the Nakagami probability density function is * @f[ * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu} * x^{2\mu-1}e^{-\mu x / \omega} * @f] * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$ * and @f$\omega > 0@f$. */ template class nakagami_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef nakagami_distribution distribution_type; param_type(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_mu(__mu_val), _M_omega(__omega_val) { __glibcxx_assert(_M_mu >= result_type(0.5L)); __glibcxx_assert(_M_omega > result_type(0)); } result_type mu() const { return _M_mu; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_mu; result_type _M_omega; }; /** * @brief Constructors. */ explicit nakagami_distribution(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_param(__mu_val, __omega_val), _M_gd(__mu_val, __omega_val / __mu_val) { } explicit nakagami_distribution(const param_type& __p) : _M_param(__p), _M_gd(__p.mu(), __p.omega() / __p.mu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd.reset(); } /** * @brief Return the parameters of the distribution. */ result_type mu() const { return _M_param.mu(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return std::sqrt(this->_M_gd(__urng)); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution::param_type __pg(__p.mu(), __p.omega() / __p.mu()); return std::sqrt(this->_M_gd(__pg, __urng)); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Nakagami distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const nakagami_distribution& __d1, const nakagami_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd); } /** * @brief Inserts a %nakagami_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %nakagami_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const nakagami_distribution<_RealType1>&); /** * @brief Extracts a %nakagami_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %nakagami_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, nakagami_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution _M_gd; }; /** * @brief Return true if two Nakagami distributions are not equal. */ template inline bool operator!=(const nakagami_distribution<_RealType>& __d1, const nakagami_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Pareto continuous distribution for random numbers. * * The formula for the Pareto cumulative probability function is * @f[ * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha * @f] * The formula for the Pareto probability density function is * @f[ * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu} * \left(\frac{\mu}{x}\right)^{\alpha + 1} * @f] * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\alpha \mu / (\alpha - 1)@f$ * for @f$\alpha > 1@f$
Variance@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$ * for @f$\alpha > 2@f$
Range@f$[\mu, \infty)@f$
*/ template class pareto_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef pareto_distribution distribution_type; param_type(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_alpha(__alpha_val), _M_mu(__mu_val) { __glibcxx_assert(_M_alpha > result_type(0)); __glibcxx_assert(_M_mu > result_type(0)); } result_type alpha() const { return _M_alpha; } result_type mu() const { return _M_mu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_alpha; result_type _M_mu; }; /** * @brief Constructors. */ explicit pareto_distribution(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_param(__alpha_val, __mu_val), _M_ud() { } explicit pareto_distribution(const param_type& __p) : _M_param(__p), _M_ud() { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type alpha() const { return _M_param.alpha(); } result_type mu() const { return _M_param.mu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->mu(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->mu() * std::pow(this->_M_ud(__urng), -result_type(1) / this->alpha()); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { return __p.mu() * std::pow(this->_M_ud(__urng), -result_type(1) / __p.alpha()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Pareto distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const pareto_distribution& __d1, const pareto_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %pareto_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %pareto_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const pareto_distribution<_RealType1>&); /** * @brief Extracts a %pareto_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %pareto_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, pareto_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution _M_ud; }; /** * @brief Return true if two Pareto distributions are not equal. */ template inline bool operator!=(const pareto_distribution<_RealType>& __d1, const pareto_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A K continuous distribution for random numbers. * * The formula for the K probability density function is * @f[ * p(x|\lambda, \mu, \nu) = \frac{2}{x} * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}} * \frac{1}{\Gamma(\lambda)\Gamma(\nu)} * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the second kind * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$ * and @f$\nu > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\mu@f$
Variance@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$
Range@f$[0, \infty)@f$
*/ template class k_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef k_distribution distribution_type; param_type(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val) { __glibcxx_assert(_M_lambda > result_type(0)); __glibcxx_assert(_M_mu > result_type(0)); __glibcxx_assert(_M_nu > result_type(0)); } result_type lambda() const { return _M_lambda; } result_type mu() const { return _M_mu; } result_type nu() const { return _M_nu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_lambda == __p2._M_lambda && __p1._M_mu == __p2._M_mu && __p1._M_nu == __p2._M_nu; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_lambda; result_type _M_mu; result_type _M_nu; }; /** * @brief Constructors. */ explicit k_distribution(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_param(__lambda_val, __mu_val, __nu_val), _M_gd1(__lambda_val, result_type(1) / __lambda_val), _M_gd2(__nu_val, __mu_val / __nu_val) { } explicit k_distribution(const param_type& __p) : _M_param(__p), _M_gd1(__p.lambda(), result_type(1) / __p.lambda()), _M_gd2(__p.nu(), __p.mu() / __p.nu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd1.reset(); _M_gd2.reset(); } /** * @brief Return the parameters of the distribution. */ result_type lambda() const { return _M_param.lambda(); } result_type mu() const { return _M_param.mu(); } result_type nu() const { return _M_param.nu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator&); template result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two K distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const k_distribution& __d1, const k_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd1 == __d2._M_gd1 && __d1._M_gd2 == __d2._M_gd2); } /** * @brief Inserts a %k_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %k_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const k_distribution<_RealType1>&); /** * @brief Extracts a %k_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %k_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, k_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution _M_gd1; std::gamma_distribution _M_gd2; }; /** * @brief Return true if two K distributions are not equal. */ template inline bool operator!=(const k_distribution<_RealType>& __d1, const k_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief An arcsine continuous distribution for random numbers. * * The formula for the arcsine probability density function is * @f[ * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}} * @f] * where @f$x >= a@f$ and @f$x <= b@f$. * * * * * * *
Distribution Statistics
Mean@f$ (a + b) / 2 @f$
Variance@f$ (b - a)^2 / 8 @f$
Range@f$[a, b]@f$
*/ template class arcsine_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef arcsine_distribution distribution_type; param_type(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_a <= _M_b); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_a; result_type _M_b; }; /** * @brief Constructors. */ explicit arcsine_distribution(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_param(__a, __b), _M_ud(-1.5707963267948966192313216916397514L, +1.5707963267948966192313216916397514L) { } explicit arcsine_distribution(const param_type& __p) : _M_param(__p), _M_ud(-1.5707963267948966192313216916397514L, +1.5707963267948966192313216916397514L) { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->a(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return this->b(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = std::sin(this->_M_ud(__urng)); return (__x * (this->b() - this->a()) + this->a() + this->b()) / result_type(2); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { result_type __x = std::sin(this->_M_ud(__urng)); return (__x * (__p.b() - __p.a()) + __p.a() + __p.b()) / result_type(2); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two arcsine distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const arcsine_distribution& __d1, const arcsine_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %arcsine_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %arcsine_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const arcsine_distribution<_RealType1>&); /** * @brief Extracts a %arcsine_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %arcsine_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, arcsine_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution _M_ud; }; /** * @brief Return true if two arcsine distributions are not equal. */ template inline bool operator!=(const arcsine_distribution<_RealType>& __d1, const arcsine_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Hoyt continuous distribution for random numbers. * * The formula for the Hoyt probability density function is * @f[ * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega} * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right) * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$0 < q < 1@f$. * * * * * * *
Distribution Statistics
Mean@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}} * E(1 - q^2) @f$
Variance@f$ \omega \left(1 - \frac{2E^2(1 - q^2)} * {\pi (1 + q^2)}\right) @f$
Range@f$[0, \infty)@f$
* where @f$E(x)@f$ is the elliptic function of the second kind. */ template class hoyt_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef hoyt_distribution distribution_type; param_type(result_type __q = result_type(0.5L), result_type __omega = result_type(1)) : _M_q(__q), _M_omega(__omega) { __glibcxx_assert(_M_q > result_type(0)); __glibcxx_assert(_M_q < result_type(1)); } result_type q() const { return _M_q; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_q; result_type _M_omega; }; /** * @brief Constructors. */ explicit hoyt_distribution(result_type __q = result_type(0.5L), result_type __omega = result_type(1)) : _M_param(__q, __omega), _M_ad(result_type(0.5L) * (result_type(1) + __q * __q), result_type(0.5L) * (result_type(1) + __q * __q) / (__q * __q)), _M_ed(result_type(1)) { } explicit hoyt_distribution(const param_type& __p) : _M_param(__p), _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()), result_type(0.5L) * (result_type(1) + __p.q() * __p.q()) / (__p.q() * __p.q())), _M_ed(result_type(1)) { } /** * @brief Resets the distribution state. */ void reset() { _M_ad.reset(); _M_ed.reset(); } /** * @brief Return the parameters of the distribution. */ result_type q() const { return _M_param.q(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng); template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Hoyt distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const hoyt_distribution& __d1, const hoyt_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ad == __d2._M_ad && __d1._M_ed == __d2._M_ed); } /** * @brief Inserts a %hoyt_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %hoyt_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const hoyt_distribution<_RealType1>&); /** * @brief Extracts a %hoyt_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %hoyt_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, hoyt_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; __gnu_cxx::arcsine_distribution _M_ad; std::exponential_distribution _M_ed; }; /** * @brief Return true if two Hoyt distributions are not equal. */ template inline bool operator!=(const hoyt_distribution<_RealType>& __d1, const hoyt_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A triangular distribution for random numbers. * * The formula for the triangular probability density function is * @f[ * / 0 for x < a * p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b * | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c * \ 0 for c < x * @f] * * * * * * *
Distribution Statistics
Mean@f$ \frac{a+b+c}{2} @f$
Variance@f$ \frac{a^2+b^2+c^2-ab-ac-bc} * {18}@f$
Range@f$[a, c]@f$
*/ template class triangular_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { friend class triangular_distribution<_RealType>; explicit param_type(_RealType __a = _RealType(0), _RealType __b = _RealType(0.5), _RealType __c = _RealType(1)) : _M_a(__a), _M_b(__b), _M_c(__c) { __glibcxx_assert(_M_a <= _M_b); __glibcxx_assert(_M_b <= _M_c); __glibcxx_assert(_M_a < _M_c); _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a); _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a); _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a); } _RealType a() const { return _M_a; } _RealType b() const { return _M_b; } _RealType c() const { return _M_c; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b && __p1._M_c == __p2._M_c); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; _RealType _M_c; _RealType _M_r_ab; _RealType _M_f_ab_ac; _RealType _M_f_bc_ac; }; /** * @brief Constructs a triangle distribution with parameters * @f$ a @f$, @f$ b @f$ and @f$ c @f$. */ explicit triangular_distribution(result_type __a = result_type(0), result_type __b = result_type(0.5), result_type __c = result_type(1)) : _M_param(__a, __b, __c) { } explicit triangular_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$ a @f$ of the distribution. */ result_type a() const { return _M_param.a(); } /** * @brief Returns the @f$ b @f$ of the distribution. */ result_type b() const { return _M_param.b(); } /** * @brief Returns the @f$ c @f$ of the distribution. */ result_type c() const { return _M_param.c(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return _M_param._M_a; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param._M_c; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __rnd = __aurng(); if (__rnd <= __p._M_r_ab) return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac); else return __p.c() - std::sqrt((result_type(1) - __rnd) * __p._M_f_bc_ac); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two triangle distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const triangular_distribution& __d1, const triangular_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %triangular_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %triangular_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::triangular_distribution<_RealType1>& __x); /** * @brief Extracts a %triangular_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %triangular_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::triangular_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two triangle distributions are different. */ template inline bool operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1, const __gnu_cxx::triangular_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A von Mises distribution for random numbers. * * The formula for the von Mises probability density function is * @f[ * p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}} * {2\pi I_0(\kappa)} * @f] * * The generating functions use the method according to: * * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the * von Mises Distribution", Journal of the Royal Statistical Society. * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157. * * * * * * *
Distribution Statistics
Mean@f$ \mu @f$
Variance@f$ 1-I_1(\kappa)/I_0(\kappa) @f$
Range@f$[-\pi, \pi]@f$
*/ template class von_mises_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { friend class von_mises_distribution<_RealType>; explicit param_type(_RealType __mu = _RealType(0), _RealType __kappa = _RealType(1)) : _M_mu(__mu), _M_kappa(__kappa) { const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi; __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi); __glibcxx_assert(_M_kappa >= _RealType(0)); auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa + _RealType(1)) + _RealType(1); auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau)) / (_RealType(2) * _M_kappa)); _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho); } _RealType mu() const { return _M_mu; } _RealType kappa() const { return _M_kappa; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_mu; _RealType _M_kappa; _RealType _M_r; }; /** * @brief Constructs a von Mises distribution with parameters * @f$\mu@f$ and @f$\kappa@f$. */ explicit von_mises_distribution(result_type __mu = result_type(0), result_type __kappa = result_type(1)) : _M_param(__mu, __kappa) { } explicit von_mises_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$ \mu @f$ of the distribution. */ result_type mu() const { return _M_param.mu(); } /** * @brief Returns the @f$ \kappa @f$ of the distribution. */ result_type kappa() const { return _M_param.kappa(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return -__gnu_cxx::__math_constants::__pi; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return __gnu_cxx::__math_constants::__pi; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two von Mises distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const von_mises_distribution& __d1, const von_mises_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %von_mises_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %von_mises_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::von_mises_distribution<_RealType1>& __x); /** * @brief Extracts a %von_mises_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %von_mises_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::von_mises_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two von Mises distributions are different. */ template inline bool operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1, const __gnu_cxx::von_mises_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A discrete hypergeometric random number distribution. * * The hypergeometric distribution is a discrete probability distribution * that describes the probability of @p k successes in @p n draws @a without * replacement from a finite population of size @p N containing exactly @p K * successes. * * The formula for the hypergeometric probability density function is * @f[ * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}} * @f] * where @f$N@f$ is the total population of the distribution, * @f$K@f$ is the total population of the distribution. * * * * * * *
Distribution Statistics
Mean@f$ n\frac{K}{N} @f$
Variance@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1} * @f$
Range@f$[max(0, n+K-N), min(K, n)]@f$
*/ template class hypergeometric_distribution { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); public: /** The type of the range of the distribution. */ typedef _UIntType result_type; /** Parameter type. */ struct param_type { typedef hypergeometric_distribution<_UIntType> distribution_type; friend class hypergeometric_distribution<_UIntType>; explicit param_type(result_type __N = 10, result_type __K = 5, result_type __n = 1) : _M_N{__N}, _M_K{__K}, _M_n{__n} { __glibcxx_assert(_M_N >= _M_K); __glibcxx_assert(_M_N >= _M_n); } result_type total_size() const { return _M_N; } result_type successful_size() const { return _M_K; } result_type unsuccessful_size() const { return _M_N - _M_K; } result_type total_draws() const { return _M_n; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_N == __p2._M_N) && (__p1._M_K == __p2._M_K) && (__p1._M_n == __p2._M_n); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: result_type _M_N; result_type _M_K; result_type _M_n; }; // constructors and member function explicit hypergeometric_distribution(result_type __N = 10, result_type __K = 5, result_type __n = 1) : _M_param{__N, __K, __n} { } explicit hypergeometric_distribution(const param_type& __p) : _M_param{__p} { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the distribution parameter @p N, * the total number of items. */ result_type total_size() const { return this->_M_param.total_size(); } /** * @brief Returns the distribution parameter @p K, * the total number of successful items. */ result_type successful_size() const { return this->_M_param.successful_size(); } /** * @brief Returns the total number of unsuccessful items @f$ N - K @f$. */ result_type unsuccessful_size() const { return this->_M_param.unsuccessful_size(); } /** * @brief Returns the distribution parameter @p n, * the total number of draws. */ result_type total_draws() const { return this->_M_param.total_draws(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return this->_M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { this->_M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { using _IntType = typename std::make_signed::type; return static_cast(std::max(static_cast<_IntType>(0), static_cast<_IntType>(this->total_draws() - this->unsuccessful_size()))); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::min(this->successful_size(), this->total_draws()); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->_M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->_M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two hypergeometric distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const hypergeometric_distribution& __d1, const hypergeometric_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %hypergeometric_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %hypergeometric_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); /** * @brief Extracts a %hypergeometric_distribution random number * distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %hypergeometric_distribution random number generator * distribution. * * @returns The input stream with @p __x extracted or in an error * state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two hypergeometric distributions are different. */ template inline bool operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1, const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2) { return !(__d1 == __d2); } /** * @brief A logistic continuous distribution for random numbers. * * The formula for the logistic probability density function is * @f[ * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2} * @f] * where @f$b > 0@f$. * * The formula for the logistic probability function is * @f[ * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}} * @f] * where @f$b > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$a@f$
Variance@f$b^2\pi^2/3@f$
Range@f$[0, \infty)@f$
*/ template class logistic_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef logistic_distribution distribution_type; param_type(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_b > result_type(0)); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_a; result_type _M_b; }; /** * @brief Constructors. */ explicit logistic_distribution(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_param(__a, __b) { } explicit logistic_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Return the parameters of the distribution. */ result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return -std::numeric_limits::max(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->_M_param); } template result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two logistic distributions have * the same parameters and the sequences that would * be generated are equal. */ template friend bool operator==(const logistic_distribution<_RealType1>& __d1, const logistic_distribution<_RealType1>& __d2) { return __d1.param() == __d2.param(); } /** * @brief Inserts a %logistic_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %logistic_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const logistic_distribution<_RealType1>&); /** * @brief Extracts a %logistic_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %logistic_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, logistic_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two logistic distributions are not equal. */ template inline bool operator!=(const logistic_distribution<_RealType1>& __d1, const logistic_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A distribution for random coordinates on a unit sphere. * * The method used in the generation function is attributed by Donald Knuth * to G. W. Brown, Modern Mathematics for the Engineer (1956). */ template class uniform_on_sphere_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ struct param_type { explicit param_type() { } friend bool operator==(const param_type&, const param_type&) { return true; } friend bool operator!=(const param_type&, const param_type&) { return false; } }; /** * @brief Constructs a uniform on sphere distribution. */ explicit uniform_on_sphere_distribution() : _M_param(), _M_nd() { } explicit uniform_on_sphere_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. * This function makes no sense for this distribution. */ result_type min() const { result_type __res; __res.fill(0); return __res; } /** * @brief Returns the least upper bound value of the distribution. * This function makes no sense for this distribution. */ result_type max() const { result_type __res; __res.fill(0); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform on sphere distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const uniform_on_sphere_distribution& __d1, const uniform_on_sphere_distribution& __d2) { return __d1._M_nd == __d2._M_nd; } /** * @brief Inserts a %uniform_on_sphere_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_on_sphere_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %uniform_on_sphere_distribution random number * distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_on_sphere_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, _RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two uniform on sphere distributions are different. */ template inline bool operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A distribution for random coordinates inside a unit sphere. */ template class uniform_inside_sphere_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ using result_type = std::array<_RealType, _Dimen>; /** Parameter type. */ struct param_type { using distribution_type = uniform_inside_sphere_distribution<_Dimen, _RealType>; friend class uniform_inside_sphere_distribution<_Dimen, _RealType>; explicit param_type(_RealType __radius = _RealType(1)) : _M_radius(__radius) { __glibcxx_assert(_M_radius > _RealType(0)); } _RealType radius() const { return _M_radius; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_radius == __p2._M_radius; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_radius; }; /** * @brief Constructors. */ explicit uniform_inside_sphere_distribution(_RealType __radius = _RealType(1)) : _M_param(__radius), _M_uosd() { } explicit uniform_inside_sphere_distribution(const param_type& __p) : _M_param(__p), _M_uosd() { } /** * @brief Resets the distribution state. */ void reset() { _M_uosd.reset(); } /** * @brief Returns the @f$radius@f$ of the distribution. */ _RealType radius() const { return _M_param.radius(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. * This function makes no sense for this distribution. */ result_type min() const { result_type __res; __res.fill(0); return __res; } /** * @brief Returns the least upper bound value of the distribution. * This function makes no sense for this distribution. */ result_type max() const { result_type __res; __res.fill(0); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform on sphere distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const uniform_inside_sphere_distribution& __d1, const uniform_inside_sphere_distribution& __d2) { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; } /** * @brief Inserts a %uniform_inside_sphere_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_inside_sphere_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, _RealType1>& ); /** * @brief Extracts a %uniform_inside_sphere_distribution random number * distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_inside_sphere_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, _RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd; }; /** * @brief Return true if two uniform on sphere distributions are different. */ template inline bool operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #include #include #endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C #endif // C++11 #endif // _EXT_RANDOM PKgd1]E8/ext/pb_ds/tree_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy.hpp * Contains tree-related policies. */ #ifndef PB_DS_TREE_POLICY_HPP #define PB_DS_TREE_POLICY_HPP #include #include #include #include namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ tree_order_statistics_node_update #define PB_DS_BRANCH_POLICY_BASE \ detail::branch_policy /// Functor updating ranks of entrees. template class tree_order_statistics_node_update : private PB_DS_BRANCH_POLICY_BASE { private: typedef PB_DS_BRANCH_POLICY_BASE base_type; public: typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; typedef size_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; /// Finds an entry by __order. Returns a const_iterator to the /// entry with the __order order, or a const_iterator to the /// container object's end if order is at least the size of the /// container object. inline const_iterator find_by_order(size_type) const; /// Finds an entry by __order. Returns an iterator to the entry /// with the __order order, or an iterator to the container /// object's end if order is at least the size of the container /// object. inline iterator find_by_order(size_type); /// Returns the order of a key within a sequence. For exapmle, if /// r_key is the smallest key, this method will return 0; if r_key /// is a key between the smallest and next key, this method will /// return 1; if r_key is a key larger than the largest key, this /// method will return the size of r_c. inline size_type order_of_key(key_const_reference) const; private: /// Const reference to the container's value-type. typedef typename base_type::const_reference const_reference; /// Const pointer to the container's value-type. typedef typename base_type::const_pointer const_pointer; typedef typename _Alloc::template rebind::other __rebind_m; /// Const metadata reference. typedef typename __rebind_m::const_reference metadata_const_reference; /// Metadata reference. typedef typename __rebind_m::reference metadata_reference; /// Returns the node_const_iterator associated with the tree's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the tree's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual cmp_fn& get_cmp_fn() = 0; protected: /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; virtual ~tree_order_statistics_node_update(); }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_BRANCH_POLICY_BASE } // namespace __gnu_pbds #endif PKgd1] "8/ext/pb_ds/list_update_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_policy.hpp * Contains policies for list update containers. */ #ifndef PB_DS_LU_POLICY_HPP #define PB_DS_LU_POLICY_HPP #include #include #include #include namespace __gnu_pbds { /** * A list-update policy that unconditionally moves elements to the * front of the list. A null type means that each link in a * list-based container does not actually need metadata. */ template > class lu_move_to_front_policy { public: typedef _Alloc allocator_type; /// Metadata on which this functor operates. typedef null_type metadata_type; private: typedef typename _Alloc::template rebind __rebind_m; public: /// Reference to metadata on which this functor operates. typedef typename __rebind_m::other::reference metadata_reference; /// Creates a metadata object. metadata_type operator()() const { return s_metadata; } /// Decides whether a metadata object should be moved to the front /// of the list. inline bool operator()(metadata_reference r_metadata) const { return true; } private: static null_type s_metadata; }; /** * A list-update policy that moves elements to the front of the * list based on the counter algorithm. */ template > class lu_counter_policy : private detail::lu_counter_policy_base { public: typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; enum { /// When some element is accessed this number of times, it /// will be moved to the front of the list. max_count = Max_Count }; /// Metadata on which this functor operates. typedef detail::lu_counter_metadata metadata_type; private: typedef detail::lu_counter_policy_base base_type; typedef typename _Alloc::template rebind __rebind_m; public: /// Reference to metadata on which this functor operates. typedef typename __rebind_m::other::reference metadata_reference; /// Creates a metadata object. metadata_type operator()() const { return base_type::operator()(max_count); } /// Decides whether a metadata object should be moved to the front /// of the list. bool operator()(metadata_reference r_data) const { return base_type::operator()(r_data, max_count); } }; } // namespace __gnu_pbds #endif PKgd1]VF ..;8/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file direct_mod_range_hashing_imp.hpp * Contains a range-hashing policy implementation */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { mod_based_base::swap(other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type n) { mod_based_base::notify_resized(n); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type hash) const { return mod_based_base::range_hash(hash); } PKgd1]fч,8/ext/pb_ds/detail/hash_fn/probe_fn_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file probe_fn_base.hpp * Contains a probe policy base. */ #ifndef PB_DS_PROBE_FN_BASE_HPP #define PB_DS_PROBE_FN_BASE_HPP #include namespace __gnu_pbds { namespace detail { /// Probe functor base. template class probe_fn_base { protected: ~probe_fn_base() { } }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]m~{){)-8/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ranged_hash_fn.hpp * Contains a unified ranged hash functor, allowing the hash tables * to deal with a single class for ranged hashing. */ #ifndef PB_DS_RANGED_HASH_FN_HPP #define PB_DS_RANGED_HASH_FN_HPP #include #include namespace __gnu_pbds { namespace detail { /// Primary template. template class ranged_hash_fn; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 1 * The client supplies a hash function and a ranged hash function, * and requests that hash values not be stored. **/ template class ranged_hash_fn< Key, Hash_Fn, _Alloc, Comb_Hash_Fn, false> : public Hash_Fn, public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Hash_Fn hash_fn_base; typedef Comb_Hash_Fn comb_hash_fn_base; typedef typename _Alloc::template rebind< Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Hash_Fn&); ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline size_type operator()(key_const_reference) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { return (comb_hash_fn_base::operator()(hash_fn_base::operator()(r_key)));} #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 2 * The client supplies a hash function and a ranged hash function, * and requests that hash values be stored. **/ template class ranged_hash_fn : public Hash_Fn, public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef std::pair comp_hash; typedef Hash_Fn hash_fn_base; typedef Comb_Hash_Fn comb_hash_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Hash_Fn&); ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline comp_hash operator()(key_const_reference) const; inline comp_hash operator()(key_const_reference, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { const size_type hash = hash_fn_base::operator()(r_key); return std::make_pair(comb_hash_fn_base::operator()(hash), hash); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator() #ifdef _GLIBCXX_DEBUG (key_const_reference r_key, size_type hash) const #else (key_const_reference /*r_key*/, size_type hash) const #endif { _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); return std::make_pair(comb_hash_fn_base::operator()(hash), hash); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 3 * The client does not supply a hash function (by specifying * null_type as the Hash_Fn parameter), and requests that hash * values not be stored. **/ template class ranged_hash_fn : public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Hash_Fn comb_hash_fn_base; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Comb_Hash_Fn&); ranged_hash_fn(size_type, const null_type&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const null_type& r_null_type, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 4 * The client does not supply a hash function (by specifying * null_type as the Hash_Fn parameter), and requests that hash * values be stored. **/ template class ranged_hash_fn : public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Hash_Fn comb_hash_fn_base; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Comb_Hash_Fn&); ranged_hash_fn(size_type, const null_type&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const null_type& r_null_type, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]xx88<8/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file direct_mask_range_hashing_imp.hpp * Contains a range-hashing policy implementation */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { mask_based_base::swap(other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { mask_based_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type hash) const { return mask_based_base::range_hash(hash); } PKgd1]lyy28/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file linear_probe_fn_imp.hpp * Contains a probe policy implementation */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type i) const { return (i); } PKgd1]O58/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file quadratic_probe_fn_imp.hpp * Contains a probe policy implementation */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type i) const { return (i* i); } PKgd1]JX̥ 48/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_ranged_hash_fn.hpp * Contains a ranged hash policy. */ #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP #define PB_DS_SAMPLE_RANGED_HASH_FN_HPP namespace __gnu_pbds { /// A sample ranged-hash functor. class sample_ranged_hash_fn { public: typedef std::size_t size_type; /// Default constructor. sample_ranged_hash_fn(); /// Copy constructor. sample_ranged_hash_fn(const sample_ranged_hash_fn&); /// Swaps content. inline void swap(sample_ranged_hash_fn&); protected: /// Notifies the policy object that the container's __size has /// changed to size. void notify_resized(size_type); /// Transforms key_const_reference into a position within the table. inline size_type operator()(key_const_reference) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP PKgd1]45((.8/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ranged_probe_fn.hpp * Contains a unified ranged probe functor, allowing the probe tables to deal with * a single class for ranged probeing. */ #ifndef PB_DS_RANGED_PROBE_FN_HPP #define PB_DS_RANGED_PROBE_FN_HPP #include #include namespace __gnu_pbds { namespace detail { /// Primary template. template class ranged_probe_fn; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_probe_fn /** * Specialization 1 * The client supplies a probe function and a ranged probe * function, and requests that hash values not be stored. **/ template class ranged_probe_fn : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Probe_Fn comb_probe_fn_base; typedef Hash_Fn hash_fn_base; typedef Probe_Fn probe_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type); ranged_probe_fn(size_type, const Hash_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline size_type operator()(key_const_reference) const; inline size_type operator()(key_const_reference, size_type, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn, const Probe_Fn& r_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_probe_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn&)other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { return comb_probe_fn_base::operator()(hash_fn_base::operator()(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference, size_type hash, size_type i) const { return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_probe_fn /** * Specialization 2- The client supplies a probe function and a ranged * probe function, and requests that hash values not be stored. **/ template class ranged_probe_fn : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef std::pair comp_hash; typedef Comb_Probe_Fn comb_probe_fn_base; typedef Hash_Fn hash_fn_base; typedef Probe_Fn probe_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type); ranged_probe_fn(size_type, const Hash_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline comp_hash operator()(key_const_reference) const; inline size_type operator()(key_const_reference, size_type, size_type) const; inline size_type operator()(key_const_reference, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn, const Probe_Fn& r_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_probe_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { const size_type hash = hash_fn_base::operator()(r_key); return std::make_pair(comb_probe_fn_base::operator()(hash), hash); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference, size_type hash, size_type i) const { return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator() #ifdef _GLIBCXX_DEBUG (key_const_reference r_key, size_type hash) const #else (key_const_reference /*r_key*/, size_type hash) const #endif { _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); return hash; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC /** * Specialization 3 and 4 * The client does not supply a hash function or probe function, * and requests that hash values not be stored. **/ template class ranged_probe_fn : public Comb_Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Probe_Fn comb_probe_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } ranged_probe_fn(size_type, const Comb_Probe_Fn& r_comb_probe_fn) : Comb_Probe_Fn(r_comb_probe_fn) { } ranged_probe_fn(size_type, const null_type&, const Comb_Probe_Fn& r_comb_probe_fn, const null_type&) : Comb_Probe_Fn(r_comb_probe_fn) { } void swap(ranged_probe_fn& other) { comb_probe_fn_base::swap(other); } }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]vįO 38/ext/pb_ds/detail/hash_fn/sample_range_hashing.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_range_hashing.hpp * Contains a range hashing policy. */ #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP #define PB_DS_SAMPLE_RANGE_HASHING_HPP namespace __gnu_pbds { /// A sample range-hashing functor. class sample_range_hashing { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_range_hashing(); /// Copy constructor. sample_range_hashing(const sample_range_hashing& other); /// Swaps content. inline void swap(sample_range_hashing& other); protected: /// Notifies the policy object that the container's size has /// changed to argument's size. void notify_resized(size_type); /// Transforms the __hash value hash into a ranged-hash value. inline size_type operator()(size_type ) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP PKgd1]xW~W W 68/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file mod_based_range_hashing.hpp * Contains a range hashing policy base. */ #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP #define PB_DS_MOD_BASED_RANGE_HASHING_HPP namespace __gnu_pbds { namespace detail { /// Mod based range hashing. template class mod_based_range_hashing { protected: typedef Size_Type size_type; void swap(mod_based_range_hashing& other) { std::swap(m_size, other.m_size); } void notify_resized(size_type s) { m_size = s; } inline size_type range_hash(size_type s) const { return s % m_size; } private: size_type m_size; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP PKgd1] 78/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file mask_based_range_hashing.hpp * Contains a range hashing policy base. */ #ifndef PB_DS_MASK_BASED_RANGE_HASHING_HPP #define PB_DS_MASK_BASED_RANGE_HASHING_HPP namespace __gnu_pbds { namespace detail { /// Range hashing policy. template class mask_based_range_hashing { protected: typedef Size_Type size_type; void swap(mask_based_range_hashing& other) { std::swap(m_mask, other.m_mask); } void notify_resized(size_type size); inline size_type range_hash(size_type hash) const { return size_type(hash & m_mask); } private: size_type m_mask; const static size_type s_num_bits_in_size_type; const static size_type s_highest_bit_1; }; template const typename mask_based_range_hashing::size_type mask_based_range_hashing::s_num_bits_in_size_type = sizeof(typename mask_based_range_hashing::size_type) << 3; template const typename mask_based_range_hashing::size_type mask_based_range_hashing::s_highest_bit_1 = static_cast::size_type>(1) << (s_num_bits_in_size_type - 1); template void mask_based_range_hashing:: notify_resized(size_type size) { size_type i = 0; while (size ^ s_highest_bit_1) { size <<= 1; ++i; } m_mask = 1; i += 2; while (i++ < s_num_bits_in_size_type) m_mask = (m_mask << 1) ^ 1; } } // namespace detail } // namespace __gnu_pbds #endif PKgd1]-.8/ext/pb_ds/detail/hash_fn/sample_probe_fn.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_probe_fn.hpp * Contains a sample probe policy. */ #ifndef PB_DS_SAMPLE_PROBE_FN_HPP #define PB_DS_SAMPLE_PROBE_FN_HPP namespace __gnu_pbds { /// A sample probe policy. class sample_probe_fn { public: typedef std::size_t size_type; /// Default constructor. sample_probe_fn(); /// Copy constructor. sample_probe_fn(const sample_probe_fn&); /// Swaps content. inline void swap(sample_probe_fn&); protected: /// Returns the i-th offset from the hash value of some key r_key. inline size_type operator()(key_const_reference r_key, size_type i) const; }; } #endif // #ifndef PB_DS_SAMPLE_PROBE_FN_HPP PKgd1]k6& & 58/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_ranged_probe_fn.hpp * Contains a ranged probe policy. */ #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP #define PB_DS_SAMPLE_RANGED_PROBE_FN_HPP namespace __gnu_pbds { /// A sample ranged-probe functor. class sample_ranged_probe_fn { public: typedef std::size_t size_type; // Default constructor. sample_ranged_probe_fn(); // Copy constructor. sample_ranged_probe_fn(const sample_ranged_probe_fn&); // Swaps content. inline void swap(sample_ranged_probe_fn&); protected: // Notifies the policy object that the container's __size has // changed to size. void notify_resized(size_type); // Transforms the const key reference r_key into the i-th position // within the table. This method is called for each collision within // the probe sequence. inline size_type operator()(key_const_reference, std::size_t, size_type) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP PKgd1]28/ext/pb_ds/detail/branch_policy/branch_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/branch_policy.hpp * Contains a base class for branch policies. */ #ifndef PB_DS_BRANCH_POLICY_BASE_HPP #define PB_DS_BRANCH_POLICY_BASE_HPP #include namespace __gnu_pbds { namespace detail { /// Primary template, base class for branch structure policies. template struct branch_policy { protected: typedef typename Node_Itr::value_type it_type; typedef typename std::iterator_traits::value_type value_type; typedef typename value_type::first_type key_type; typedef typename remove_const::type rcvalue_type; typedef typename remove_const::type rckey_type; typedef typename _Alloc::template rebind::other rebind_v; typedef typename _Alloc::template rebind::other rebind_k; typedef typename rebind_v::reference reference; typedef typename rebind_v::const_reference const_reference; typedef typename rebind_v::const_pointer const_pointer; typedef typename rebind_k::const_reference key_const_reference; static inline key_const_reference extract_key(const_reference r_val) { return r_val.first; } virtual it_type end() = 0; it_type end_iterator() const { return const_cast(this)->end(); } virtual ~branch_policy() { } }; /// Specialization for const iterators. template struct branch_policy { protected: typedef typename Node_CItr::value_type it_type; typedef typename std::iterator_traits::value_type value_type; typedef typename remove_const::type rcvalue_type; typedef typename _Alloc::template rebind::other rebind_v; typedef typename rebind_v::reference reference; typedef typename rebind_v::const_reference const_reference; typedef typename rebind_v::const_pointer const_pointer; typedef value_type key_type; typedef typename rebind_v::const_reference key_const_reference; static inline key_const_reference extract_key(const_reference r_val) { return r_val; } virtual it_type end() const = 0; it_type end_iterator() const { return end(); } virtual ~branch_policy() { } }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BRANCH_POLICY_BASE_HPP PKgd1]) K K 78/ext/pb_ds/detail/branch_policy/null_node_metadata.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/null_node_metadata.hpp * Contains an implementation class for tree-like classes. */ #ifndef PB_DS_0_NODE_METADATA_HPP #define PB_DS_0_NODE_METADATA_HPP #include namespace __gnu_pbds { namespace detail { /// Constant node iterator. template struct dumnode_const_iterator { private: typedef types_traits __traits_type; typedef typename __traits_type::pointer const_iterator; public: typedef const_iterator value_type; typedef const_iterator const_reference; typedef const_reference reference; }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]Ho +8/ext/pb_ds/detail/branch_policy/traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/traits.hpp * Contains an implementation class for tree-like classes. */ #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP #define PB_DS_NODE_AND_IT_TRAITS_HPP #include #include #include #include #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) namespace __gnu_pbds { namespace detail { /// Tree traits class, primary template. template class Node_Update, typename Tag, typename _Alloc> struct tree_traits; /// Trie traits class, primary template. template class Node_Update, typename Tag, typename _Alloc> struct trie_traits; } // namespace detail } // namespace __gnu_pbds #include #include #include #include #undef PB_DS_DEBUG_VERIFY #endif // #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP PKgd1]%!!8/ext/pb_ds/detail/type_utils.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/type_utils.hpp * Contains utilities for handnling types. All of these classes are based on * Modern C++ by Andrei Alxandrescu. */ #ifndef PB_DS_TYPE_UTILS_HPP #define PB_DS_TYPE_UTILS_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { using std::tr1::is_same; using std::tr1::is_const; using std::tr1::is_pointer; using std::tr1::is_reference; using std::tr1::is_fundamental; using std::tr1::is_member_object_pointer; using std::tr1::is_member_pointer; using std::tr1::is_base_of; using std::tr1::remove_const; using std::tr1::remove_reference; // Need integral_const <-> integral_const, so // because of this use the following typedefs instead of importing // std::tr1's. using std::tr1::integral_constant; typedef std::tr1::integral_constant true_type; typedef std::tr1::integral_constant false_type; using __gnu_cxx::__conditional_type; using __gnu_cxx::__numeric_traits; template struct is_const_pointer { enum { value = is_const::value && is_pointer::value }; }; template struct is_const_reference { enum { value = is_const::value && is_reference::value }; }; template struct is_simple { enum { value = is_fundamental::type>::value || is_pointer::type>::value || is_member_pointer::value }; }; template class is_pair { private: template struct is_pair_imp { enum { value = 0 }; }; template struct is_pair_imp > { enum { value = 1 }; }; public: enum { value = is_pair_imp::value }; }; // Use C++11's static_assert if possible. #if __cplusplus >= 201103L #define PB_DS_STATIC_ASSERT(UNIQUE, E) static_assert(E, #UNIQUE) #else template struct __static_assert; template<> struct __static_assert { }; template struct __static_assert_dumclass { enum { v = 1 }; }; #define PB_DS_STATIC_ASSERT(UNIQUE, E) \ typedef __gnu_pbds::detail::__static_assert_dumclass)> UNIQUE##__static_assert_type #endif template struct type_to_type { typedef Type type; }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]]B" " =8/ext/pb_ds/detail/list_update_policy/lu_counter_metadata.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file lu_counter_metadata.hpp * Contains implementation of a lu counter policy's metadata. */ namespace __gnu_pbds { namespace detail { template class lu_counter_policy_base; /// A list-update metadata type that moves elements to the front of /// the list based on the counter algorithm. template class lu_counter_metadata { public: typedef Size_Type size_type; private: lu_counter_metadata(size_type init_count) : m_count(init_count) { } friend class lu_counter_policy_base; mutable size_type m_count; }; /// Base class for list-update counter policy. template class lu_counter_policy_base { protected: typedef Size_Type size_type; lu_counter_metadata operator()(size_type max_size) const { return lu_counter_metadata(std::rand() % max_size); } template bool operator()(Metadata_Reference r_data, size_type m_max_count) const { if (++r_data.m_count != m_max_count) return false; r_data.m_count = 0; return true; } }; } // namespace detail } // namespace __gnu_pbds PKgd1]#Bp p >8/ext/pb_ds/detail/list_update_policy/sample_update_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_update_policy.hpp * Contains a sample policy for list update containers. */ #ifndef PB_DS_SAMPLE_UPDATE_POLICY_HPP #define PB_DS_SAMPLE_UPDATE_POLICY_HPP namespace __gnu_pbds { /// A sample list-update policy. struct sample_update_policy { /// Default constructor. sample_update_policy(); /// Copy constructor. sample_update_policy(const sample_update_policy&); /// Swaps content. inline void swap(sample_update_policy& other); protected: /// Metadata on which this functor operates. typedef some_metadata_type metadata_type; /// Creates a metadata object. metadata_type operator()() const; /// Decides whether a metadata object should be moved to the front /// of the list. A list-update based containers object will call /// this method to decide whether to move a node to the front of /// the list. The method shoule return true if the node should be /// moved to the front of the list. bool operator()(metadata_reference) const; }; } #endif PKgd1]; #8/ext/pb_ds/detail/cond_dealtor.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/cond_dealtor.hpp * Contains a conditional deallocator. */ #ifndef PB_DS_COND_DEALTOR_HPP #define PB_DS_COND_DEALTOR_HPP namespace __gnu_pbds { namespace detail { /// Conditional deallocate constructor argument. template class cond_dealtor { typedef typename _Alloc::template rebind __rebind_e; public: typedef typename __rebind_e::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; cond_dealtor(entry_pointer p_e) : m_p_e(p_e), m_no_action_destructor(false) { } ~cond_dealtor() { if (m_no_action_destructor) return; s_alloc.deallocate(m_p_e, 1); } void set_no_action() { m_no_action_destructor = true; } private: entry_pointer m_p_e; bool m_no_action_destructor; static entry_allocator s_alloc; }; template typename cond_dealtor::entry_allocator cond_dealtor::s_alloc; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_COND_DEALTOR_HPP PKgd1] k"k"28/ext/pb_ds/detail/ov_tree_map_/node_iterators.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/node_iterators.hpp * Contains an implementation class for ov_tree_. */ #ifndef PB_DS_OV_TREE_NODE_ITERATORS_HPP #define PB_DS_OV_TREE_NODE_ITERATORS_HPP #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC \ ov_tree_node_const_it_ /// Const node reference. template class ov_tree_node_const_it_ { protected: typedef typename _Alloc::template rebind< Value_Type>::other::pointer pointer; typedef typename _Alloc::template rebind< Value_Type>::other::const_pointer const_pointer; typedef typename _Alloc::template rebind< Metadata_Type>::other::const_pointer const_metadata_pointer; typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC this_type; protected: template inline static Ptr mid_pointer(Ptr p_begin, Ptr p_end) { _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); return (p_begin + (p_end - p_begin) / 2); } public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::template rebind< Value_Type>::other::const_pointer value_type; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::const_pointer reference; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::const_pointer const_reference; typedef Metadata_Type metadata_type; typedef typename _Alloc::template rebind< metadata_type>::other::const_reference metadata_const_reference; public: inline ov_tree_node_const_it_(const_pointer p_nd = 0, const_pointer p_begin_nd = 0, const_pointer p_end_nd = 0, const_metadata_pointer p_metadata = 0) : m_p_value(const_cast(p_nd)), m_p_begin_value(const_cast(p_begin_nd)), m_p_end_value(const_cast(p_end_nd)), m_p_metadata(p_metadata) { } inline const_reference operator*() const { return m_p_value; } inline metadata_const_reference get_metadata() const { enum { has_metadata = !is_same::value }; PB_DS_STATIC_ASSERT(should_have_metadata, has_metadata); _GLIBCXX_DEBUG_ASSERT(m_p_metadata != 0); return *m_p_metadata; } /// Returns the node iterator associated with the left node. inline this_type get_l_child() const { if (m_p_begin_value == m_p_value) return (this_type(m_p_begin_value, m_p_begin_value, m_p_begin_value)); const_metadata_pointer p_begin_metadata = m_p_metadata - (m_p_value - m_p_begin_value); return (this_type(mid_pointer(m_p_begin_value, m_p_value), m_p_begin_value, m_p_value, mid_pointer(p_begin_metadata, m_p_metadata))); } /// Returns the node iterator associated with the right node. inline this_type get_r_child() const { if (m_p_value == m_p_end_value) return (this_type(m_p_end_value, m_p_end_value, m_p_end_value)); const_metadata_pointer p_end_metadata = m_p_metadata + (m_p_end_value - m_p_value); return (this_type(mid_pointer(m_p_value + 1, m_p_end_value), m_p_value + 1, m_p_end_value,(m_p_metadata == 0) ? 0 : mid_pointer(m_p_metadata + 1, p_end_metadata))); } inline bool operator==(const this_type& other) const { const bool is_end = m_p_begin_value == m_p_end_value; const bool is_other_end = other.m_p_begin_value == other.m_p_end_value; if (is_end) return (is_other_end); if (is_other_end) return (is_end); return m_p_value == other.m_p_value; } inline bool operator!=(const this_type& other) const { return !operator==(other); } public: pointer m_p_value; pointer m_p_begin_value; pointer m_p_end_value; const_metadata_pointer m_p_metadata; }; #define PB_DS_OV_TREE_NODE_ITERATOR_C_DEC \ ov_tree_node_it_ /// Node reference. template class ov_tree_node_it_ : public PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC { private: typedef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC this_type; typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC base_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::const_metadata_pointer const_metadata_pointer; public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::template rebind< Value_Type>::other::pointer value_type; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::pointer reference; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::pointer const_reference; inline ov_tree_node_it_(const_pointer p_nd = 0, const_pointer p_begin_nd = 0, const_pointer p_end_nd = 0, const_metadata_pointer p_metadata = 0) : base_type(p_nd, p_begin_nd, p_end_nd, p_metadata) { } /// Access. inline reference operator*() const { return reference(base_type::m_p_value); } /// Returns the node reference associated with the left node. inline ov_tree_node_it_ get_l_child() const { if (base_type::m_p_begin_value == base_type::m_p_value) return (this_type(base_type::m_p_begin_value, base_type::m_p_begin_value, base_type::m_p_begin_value)); const_metadata_pointer p_begin_metadata = base_type::m_p_metadata - (base_type::m_p_value - base_type::m_p_begin_value); return (this_type(base_type::mid_pointer(base_type::m_p_begin_value, base_type::m_p_value), base_type::m_p_begin_value, base_type::m_p_value, base_type::mid_pointer(p_begin_metadata, base_type::m_p_metadata))); } /// Returns the node reference associated with the right node. inline ov_tree_node_it_ get_r_child() const { if (base_type::m_p_value == base_type::m_p_end_value) return this_type(base_type::m_p_end_value, base_type::m_p_end_value, base_type::m_p_end_value); const_metadata_pointer p_end_metadata = base_type::m_p_metadata + (base_type::m_p_end_value - base_type::m_p_value); return (this_type(base_type::mid_pointer(base_type::m_p_value + 1, base_type::m_p_end_value), base_type::m_p_value + 1, base_type::m_p_end_value,(base_type::m_p_metadata == 0)? 0 : base_type::mid_pointer(base_type::m_p_metadata + 1, p_end_metadata))); } }; #undef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC #undef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]}$<<08/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/ov_tree_map_.hpp * Contains an implementation class for ov_tree. */ #include #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #include #include #include #include #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_OV_TREE_NAME ov_tree_map #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_OV_TREE_NAME ov_tree_set #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_OV_TREE_NAME #define PB_DS_OV_TREE_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base, \ typename _Alloc::template rebind::other::const_reference> #endif #ifdef PB_DS_TREE_TRACE #define PB_DS_TREE_TRACE_BASE_C_DEC \ tree_trace_base #endif #ifndef PB_DS_CHECK_KEY_EXISTS # error Missing definition #endif /** * @brief Ordered-vector tree associative-container. * @ingroup branch-detail */ template class PB_DS_OV_TREE_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif #ifdef PB_DS_TREE_TRACE public PB_DS_TREE_TRACE_BASE_C_DEC, #endif public Cmp_Fn, public Node_And_It_Traits::node_update, public PB_DS_OV_TREE_TRAITS_BASE { private: typedef PB_DS_OV_TREE_TRAITS_BASE traits_base; typedef Node_And_It_Traits traits_type; typedef typename remove_const::type non_const_value_type; typedef typename _Alloc::template rebind::other value_allocator; typedef typename value_allocator::pointer value_vector; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif #ifdef PB_DS_TREE_TRACE typedef PB_DS_TREE_TRACE_BASE_C_DEC trace_base; #endif typedef typename traits_base::pointer mapped_pointer_; typedef typename traits_base::const_pointer mapped_const_pointer_; typedef typename traits_type::metadata_type metadata_type; typedef typename _Alloc::template rebind::other metadata_allocator; typedef typename metadata_allocator::pointer metadata_pointer; typedef typename metadata_allocator::const_reference metadata_const_reference; typedef typename metadata_allocator::reference metadata_reference; typedef typename traits_type::null_node_update_pointer null_node_update_pointer; public: typedef ov_tree_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Cmp_Fn cmp_fn; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef const_pointer point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef pointer point_iterator; #else typedef point_const_iterator point_iterator; #endif typedef point_iterator iterator; typedef point_const_iterator const_iterator; /// Conditional destructor. template class cond_dtor { public: cond_dtor(value_vector a_vec, iterator& r_last_it, Size_Type total_size) : m_a_vec(a_vec), m_r_last_it(r_last_it), m_max_size(total_size), m_no_action(false) { } ~cond_dtor() { if (m_no_action) return; iterator it = m_a_vec; while (it != m_r_last_it) { it->~value_type(); ++it; } if (m_max_size > 0) value_allocator().deallocate(m_a_vec, m_max_size); } inline void set_no_action() { m_no_action = true; } protected: value_vector m_a_vec; iterator& m_r_last_it; const Size_Type m_max_size; bool m_no_action; }; typedef typename traits_type::node_update node_update; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; PB_DS_OV_TREE_NAME(); PB_DS_OV_TREE_NAME(const Cmp_Fn&); PB_DS_OV_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC&); ~PB_DS_OV_TREE_NAME(); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); inline size_type max_size() const; inline bool empty() const; inline size_type size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_ASSERT_VALID((*this)) point_iterator it = lower_bound(r_key); if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) { PB_DS_CHECK_KEY_EXISTS(r_key) PB_DS_ASSERT_VALID((*this)) return it->second; } return insert_new_val(it, std::make_pair(r_key, mapped_type()))->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline std::pair insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) key_const_reference r_key = PB_DS_V2F(r_value); point_iterator it = lower_bound(r_key); if (it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) { PB_DS_ASSERT_VALID((*this)) PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(it, false); } return std::make_pair(insert_new_val(it, r_value), true); } inline point_iterator lower_bound(key_const_reference r_key) { pointer it = m_a_values; pointer e_it = m_a_values + m_size; while (it != e_it) { pointer mid_it = it + ((e_it - it) >> 1); if (cmp_fn::operator()(PB_DS_V2F(*mid_it), r_key)) it = ++mid_it; else e_it = mid_it; } return it; } inline point_const_iterator lower_bound(key_const_reference r_key) const { return const_cast(*this).lower_bound(r_key); } inline point_iterator upper_bound(key_const_reference r_key) { iterator pot_it = lower_bound(r_key); if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) { PB_DS_CHECK_KEY_EXISTS(r_key) return ++pot_it; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return pot_it; } inline point_const_iterator upper_bound(key_const_reference r_key) const { return const_cast(*this).upper_bound(r_key); } inline point_iterator find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator pot_it = lower_bound(r_key); if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) { PB_DS_CHECK_KEY_EXISTS(r_key) return pot_it; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } inline point_const_iterator find(key_const_reference r_key) const { return (const_cast(*this).find(r_key)); } bool erase(key_const_reference); template inline size_type erase_if(Pred); inline iterator erase(iterator it) { return erase_imp(it); } void clear(); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); inline iterator begin() { return m_a_values; } inline const_iterator begin() const { return m_a_values; } inline iterator end() { return m_end_it; } inline const_iterator end() const { return m_end_it; } /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); private: inline void update(node_iterator, null_node_update_pointer); template void update(node_iterator, Node_Update*); void reallocate_metadata(null_node_update_pointer, size_type); template void reallocate_metadata(Node_Update_*, size_type); template void copy_from_ordered_range(It, It); void value_swap(PB_DS_CLASS_C_DEC&); template void copy_from_ordered_range(It, It, It, It); template inline static Ptr mid_pointer(Ptr p_begin, Ptr p_end) { _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); return (p_begin + (p_end - p_begin) / 2); } inline iterator insert_new_val(iterator it, const_reference r_value) { #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) value_vector a_values = s_value_alloc.allocate(m_size + 1); iterator source_it = begin(); iterator source_end_it = end(); iterator target_it = a_values; iterator ret_it; cond_dtor cd(a_values, target_it, m_size + 1); while (source_it != it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } new (const_cast(static_cast(ret_it = target_it))) value_type(r_value); ++target_it; while (source_it != source_end_it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update*)this, m_size + 1); cd.set_no_action(); if (m_size != 0) { cond_dtor cd1(m_a_values, m_end_it, m_size); } ++m_size; m_a_values = a_values; m_end_it = m_a_values + m_size; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value))); update(node_begin(), (node_update* )this); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_iterators(const char*, int) const; #endif template It erase_imp(It); inline node_const_iterator PB_DS_node_begin_imp() const; inline node_const_iterator PB_DS_node_end_imp() const; inline node_iterator PB_DS_node_begin_imp(); inline node_iterator PB_DS_node_end_imp(); private: static value_allocator s_value_alloc; static metadata_allocator s_metadata_alloc; value_vector m_a_values; metadata_pointer m_a_metadata; iterator m_end_it; size_type m_size; }; #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_OV_TREE_NAME #undef PB_DS_OV_TREE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #ifdef PB_DS_TREE_TRACE #undef PB_DS_TREE_TRACE_BASE_C_DEC #endif #undef PB_DS_CONST_NODE_ITERATOR_NAME } // namespace detail } // namespace __gnu_pbds PKgd1]1p__98/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/policy_access_fn_imps.hpp * Contains an implementation class for ov_tree. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return *this; } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return *this; } PKgd1]7/C8/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/constructors_destructor_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::value_allocator PB_DS_CLASS_C_DEC::s_value_alloc; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::metadata_allocator PB_DS_CLASS_C_DEC::s_metadata_alloc; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME() : m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const Cmp_Fn& r_cmp_fn) : cmp_fn(r_cmp_fn), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_nodeu) : cmp_fn(r_cmp_fn), node_update(r_nodeu), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef PB_DS_TREE_TRACE trace_base(other), #endif cmp_fn(other), node_update(other), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { copy_from_ordered_range(other.begin(), other.end()); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { #ifdef PB_DS_DATA_TRUE_INDICATOR typedef std::map::other> map_type; #else typedef std::set::other> map_type; #endif map_type m(first_it, last_it); copy_from_ordered_range(m.begin(), m.end()); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_ordered_range(It first_it, It last_it) { const size_type len = std::distance(first_it, last_it); if (len == 0) return; value_vector a_values = s_value_alloc.allocate(len); iterator target_it = a_values; It source_it = first_it; It source_end_it = last_it; cond_dtor cd(a_values, target_it, len); while (source_it != source_end_it) { void* __v = const_cast(static_cast(target_it)); new (__v) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update*)this, len); cd.set_no_action(); m_a_values = a_values; m_size = len; m_end_it = m_a_values + m_size; update(PB_DS_node_begin_imp(), (node_update*)this); #ifdef _GLIBCXX_DEBUG for (const_iterator dbg_it = m_a_values; dbg_it != m_end_it; ++dbg_it) debug_base::insert_new(PB_DS_V2F(*dbg_it)); #endif } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_ordered_range(It first_it, It last_it, It other_first_it, It other_last_it) { clear(); const size_type len = std::distance(first_it, last_it) + std::distance(other_first_it, other_last_it); value_vector a_values = s_value_alloc.allocate(len); iterator target_it = a_values; It source_it = first_it; It source_end_it = last_it; cond_dtor cd(a_values, target_it, len); while (source_it != source_end_it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } source_it = other_first_it; source_end_it = other_last_it; while (source_it != source_end_it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update* )this, len); cd.set_no_action(); m_a_values = a_values; m_size = len; m_end_it = m_a_values + m_size; update(PB_DS_node_begin_imp(), (node_update* )this); #ifdef _GLIBCXX_DEBUG for (const_iterator dbg_it = m_a_values; dbg_it != m_end_it; ++dbg_it) debug_base::insert_new(PB_DS_V2F(*dbg_it)); #endif } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap(static_cast(*this), static_cast(other)); std::swap(static_cast(*this), static_cast(other)); PB_DS_ASSERT_VALID(other) PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_a_values, other.m_a_values); std::swap(m_a_metadata, other.m_a_metadata); std::swap(m_size, other.m_size); std::swap(m_end_it, other.m_end_it); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_OV_TREE_NAME() { PB_DS_ASSERT_VALID((*this)) cond_dtor cd(m_a_values, m_end_it, m_size); reallocate_metadata((node_update*)this, 0); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update(node_iterator, null_node_update_pointer) { } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: update(node_iterator nd_it, Node_Update* p_update) { node_const_iterator end_it = PB_DS_node_end_imp(); if (nd_it != end_it) { update(nd_it.get_l_child(), p_update); update(nd_it.get_r_child(), p_update); node_update::operator()(nd_it, end_it); } } PKgd1]cC$$08/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/info_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { PB_DS_ASSERT_VALID((*this)) return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_value_alloc.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return size() == 0; } PKgd1]m?! ! 58/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/iterators_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return PB_DS_node_begin_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return PB_DS_node_end_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return PB_DS_node_begin_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return PB_DS_node_end_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_begin_imp() const { return node_const_iterator(const_cast(mid_pointer(begin(), end())), const_cast(begin()), const_cast(end()),(m_a_metadata == 0)? 0 : mid_pointer(m_a_metadata, m_a_metadata + m_size)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_end_imp() const { return node_const_iterator(end(), end(), end(), (m_a_metadata == 0) ? 0 : m_a_metadata + m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_begin_imp() { return node_iterator(mid_pointer(begin(), end()), begin(), end(), (m_a_metadata == 0) ? 0 : mid_pointer(m_a_metadata, m_a_metadata + m_size)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_end_imp() { return node_iterator(end(), end(), end(),(m_a_metadata == 0) ? 0 : m_a_metadata + m_size); } PKgd1]&;  18/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/debug_fn_imps.hpp * Contains an implementation class for ov_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { if (m_a_values == 0 || m_end_it == 0 || m_size == 0) PB_DS_DEBUG_VERIFY(m_a_values == 0 && m_end_it == 0 && m_size == 0); assert_iterators(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { debug_base::check_size(m_size, __file, __line); size_type iterated_num = 0; const_iterator prev_it = end(); PB_DS_DEBUG_VERIFY(m_end_it == m_a_values + m_size); for (const_iterator it = begin(); it != end(); ++it) { ++iterated_num; debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)) == it); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it == it); if (prev_it != end()) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), PB_DS_V2F(*it))); prev_it = it; } PB_DS_DEBUG_VERIFY(iterated_num == m_size); } #endif PKgd1][>m 28/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/insert_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: reallocate_metadata(null_node_update_pointer, size_type) { } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: reallocate_metadata(Node_Update_* , size_type new_size) { metadata_pointer a_new_metadata_vec =(new_size == 0) ? 0 : s_metadata_alloc.allocate(new_size); if (m_a_metadata != 0) { for (size_type i = 0; i < m_size; ++i) m_a_metadata[i].~metadata_type(); s_metadata_alloc.deallocate(m_a_metadata, m_size); } std::swap(m_a_metadata, a_new_metadata_vec); } PKgd1]k1_tuu18/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/erase_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_ASSERT_VALID((*this)) if (m_size == 0) { return; } else { reallocate_metadata((node_update* )this, 0); cond_dtor cd(m_a_values, m_end_it, m_size); } _GLIBCXX_DEBUG_ONLY(debug_base::clear();) m_a_values = 0; m_size = 0; m_end_it = m_a_values; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif size_type new_size = 0; size_type num_val_ersd = 0; for (iterator source_it = begin(); source_it != m_end_it; ++source_it) if (!pred(*source_it)) ++new_size; else ++num_val_ersd; if (new_size == 0) { clear(); return num_val_ersd; } value_vector a_new_values = s_value_alloc.allocate(new_size); iterator target_it = a_new_values; cond_dtor cd(a_new_values, target_it, new_size); _GLIBCXX_DEBUG_ONLY(debug_base::clear()); for (iterator source_it = begin(); source_it != m_end_it; ++source_it) { if (!pred(*source_it)) { new (const_cast(static_cast(target_it))) value_type(*source_it); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(*source_it))); ++target_it; } } reallocate_metadata((node_update*)this, new_size); cd.set_no_action(); { cond_dtor cd1(m_a_values, m_end_it, m_size); } m_a_values = a_new_values; m_size = new_size; m_end_it = target_it; update(node_begin(), (node_update*)this); PB_DS_ASSERT_VALID((*this)) return num_val_ersd; } PB_DS_CLASS_T_DEC template It PB_DS_CLASS_C_DEC:: erase_imp(It it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return end(); PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(*it)) #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif _GLIBCXX_DEBUG_ASSERT(m_size > 0); value_vector a_values = s_value_alloc.allocate(m_size - 1); iterator source_it = begin(); iterator source_end_it = end(); iterator target_it = a_values; iterator ret_it = end(); cond_dtor cd(a_values, target_it, m_size - 1); _GLIBCXX_DEBUG_ONLY(size_type cnt = 0;) while (source_it != source_end_it) { if (source_it != it) { _GLIBCXX_DEBUG_ONLY(++cnt;) _GLIBCXX_DEBUG_ASSERT(cnt != m_size); new (const_cast(static_cast(target_it))) value_type(*source_it); ++target_it; } else ret_it = target_it; ++source_it; } _GLIBCXX_DEBUG_ASSERT(m_size > 0); reallocate_metadata((node_update*)this, m_size - 1); cd.set_no_action(); _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(*it));) { cond_dtor cd1(m_a_values, m_end_it, m_size); } m_a_values = a_values; --m_size; m_end_it = m_a_values + m_size; update(node_begin(), (node_update*)this); PB_DS_ASSERT_VALID((*this)) return It(ret_it); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = find(r_key); if (it == end()) return false; erase(it); return true; } PKgd1]L68/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/split_join_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (m_size == 0) { other.clear(); return; } if (Cmp_Fn::operator()(r_key, PB_DS_V2F(*begin()))) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(*(end() - 1)))) { return; } if (m_size == 1) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } iterator it = upper_bound(r_key); PB_DS_CLASS_C_DEC new_other(other, other); new_other.copy_from_ordered_range(it, end()); PB_DS_CLASS_C_DEC new_this(*this, *this); new_this.copy_from_ordered_range(begin(), it); // No exceptions from this point. other.update(other.node_begin(), (node_update*)(&other)); update(node_begin(), (node_update*)this); other.value_swap(new_other); value_swap(new_this); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return; if (m_size == 0) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } const bool greater = Cmp_Fn::operator()(PB_DS_V2F(*(end() - 1)), PB_DS_V2F(*other.begin())); const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(*(other.end() - 1)), PB_DS_V2F(*begin())); if (!greater && !lesser) __throw_join_error(); PB_DS_CLASS_C_DEC new_this(*this, *this); if (greater) new_this.copy_from_ordered_range(begin(), end(), other.begin(), other.end()); else new_this.copy_from_ordered_range(other.begin(), other.end(), begin(), end()); // No exceptions from this point. value_swap(new_this); other.clear(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1]4Y*8/ext/pb_ds/detail/ov_tree_map_/traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/traits.hpp * Contains an implementation class for ov_tree_. */ #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { /// Tree traits. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits< Key, Mapped, Cmp_Fn, Node_Update, ov_tree_tag, _Alloc> { private: typedef typename types_traits< Key, Mapped, _Alloc, false>::value_type value_type; public: typedef typename tree_node_metadata_dispatch< Key, Mapped, Cmp_Fn, Node_Update, _Alloc>::type metadata_type; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef ov_tree_node_const_it_< value_type, metadata_type, _Alloc> node_const_iterator; typedef ov_tree_node_it_< value_type, metadata_type, _Alloc> node_iterator; typedef Node_Update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits< Key, null_type, Cmp_Fn, Node_Update, ov_tree_tag, _Alloc> { private: typedef typename types_traits< Key, null_type, _Alloc, false>::value_type value_type; public: typedef typename tree_node_metadata_dispatch< Key, null_type, Cmp_Fn, Node_Update, _Alloc>::type metadata_type; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef ov_tree_node_const_it_< value_type, metadata_type, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; typedef Node_Update< node_const_iterator, node_const_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP PKgd1])28/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/pairing_heap_.hpp * Contains an implementation class for a pairing heap. */ /* * Pairing heap: * Michael L. Fredman, Robert Sedgewick, Daniel Dominic Sleator, * and Robert Endre Tarjan, The Pairing Heap: * A New Form of Self-Adjusting Heap, Algorithmica, 1(1):111-129, 1986. */ #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ pairing_heap #ifdef _GLIBCXX_DEBUG #define PB_DS_P_HEAP_BASE \ left_child_next_sibling_heap #else #define PB_DS_P_HEAP_BASE \ left_child_next_sibling_heap #endif /** * Pairing heap. * * @ingroup heap-detail */ template class pairing_heap : public PB_DS_P_HEAP_BASE { private: typedef PB_DS_P_HEAP_BASE base_type; typedef typename base_type::node_pointer node_pointer; typedef typename _Alloc::template rebind::other __rebind_a; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_a::pointer pointer; typedef typename __rebind_a::const_pointer const_pointer; typedef typename __rebind_a::reference reference; typedef typename __rebind_a::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; pairing_heap(); pairing_heap(const Cmp_Fn&); pairing_heap(const pairing_heap&); void swap(pairing_heap&); ~pairing_heap(); inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); template size_type erase_if(Pred); template void split(Pred, pairing_heap&); void join(pairing_heap&); protected: template void copy_from_range(It, It); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif private: inline void push_imp(node_pointer); node_pointer join_node_children(node_pointer); node_pointer forward_join(node_pointer, node_pointer); node_pointer back_join(node_pointer, node_pointer); void remove_node(node_pointer); }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #include #include #include #include #include #include #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_P_HEAP_BASE } // namespace detail } // namespace __gnu_pbds PKgd1] D8/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~pairing_heap() { } PKgd1]6;18/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/find_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); return base_type::m_p_root->m_value; } PKgd1]1o28/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/debug_fn_imps.hpp * Contains an implementation class for a pairing heap. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_p_root == 0 || base_type::m_p_root->m_p_next_sibling == 0); base_type::assert_valid(__file, __line); } #endif PKgd1]i_ W 38/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/insert_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_new_nd = base_type::get_new_node_for_insert(r_val); push_imp(p_new_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_new_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: push_imp(node_pointer p_nd) { p_nd->m_p_l_child = 0; if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; } else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) { p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = 0; base_type::make_child_of(base_type::m_p_root, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) base_type::m_p_root = p_nd; } else { base_type::make_child_of(p_nd, base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) remove_node(it.m_p_nd); it.m_p_nd->m_value = r_new_val; push_imp(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) } PKgd1]6228/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/erase_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_new_root = join_node_children(base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(p_new_root, false) if (p_new_root != 0) p_new_root->m_p_prev_or_parent = 0; base_type::actual_erase_node(base_type::m_p_root); base_type::m_p_root = p_new_root; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); remove_node(it.m_p_nd); base_type::actual_erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_nd) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_new_child = join_node_children(p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_new_child, false) if (p_nd == base_type::m_p_root) { if (p_new_child != 0) p_new_child->m_p_prev_or_parent = 0; base_type::m_p_root = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) return; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent != 0); if (p_nd->m_p_prev_or_parent->m_p_l_child == p_nd) { if (p_new_child != 0) { p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_new_child->m_p_next_sibling != 0) p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; p_nd->m_p_prev_or_parent->m_p_l_child = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } p_nd->m_p_prev_or_parent->m_p_l_child = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } if (p_new_child != 0) { p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_new_child->m_p_next_sibling != 0) p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; p_new_child->m_p_prev_or_parent->m_p_next_sibling = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: join_node_children(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); node_pointer p_ret = p_nd->m_p_l_child; if (p_ret == 0) return 0; while (p_ret->m_p_next_sibling != 0) p_ret = forward_join(p_ret, p_ret->m_p_next_sibling); while (p_ret->m_p_prev_or_parent != p_nd) p_ret = back_join(p_ret->m_p_prev_or_parent, p_ret); PB_DS_ASSERT_NODE_CONSISTENT(p_ret, false) return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: forward_join(node_pointer p_nd, node_pointer p_next) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == p_next); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; base_type::make_child_of(p_nd, p_next); return p_next->m_p_next_sibling == 0 ? p_next : p_next->m_p_next_sibling; } if (p_next->m_p_next_sibling != 0) { p_next->m_p_next_sibling->m_p_prev_or_parent = p_nd; p_nd->m_p_next_sibling = p_next->m_p_next_sibling; base_type::make_child_of(p_next, p_nd); return p_nd->m_p_next_sibling; } p_nd->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) return p_nd; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: back_join(node_pointer p_nd, node_pointer p_next) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == 0); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; base_type::make_child_of(p_nd, p_next); PB_DS_ASSERT_NODE_CONSISTENT(p_next, false) return p_next; } p_nd->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) return p_nd; } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = 0; push_imp(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) return ersd; } PKgd1]`zz78/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/split_join_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; p_out->m_p_l_child = p_out->m_p_next_sibling = p_out->m_p_prev_or_parent = 0; other.push_imp(p_out); p_out = p_next; } PB_DS_ASSERT_VALID(other) node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = 0; push_imp(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_p_root == 0) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } if (base_type::m_p_root == 0) base_type::m_p_root = other.m_p_root; else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, other.m_p_root->m_value)) { base_type::make_child_of(base_type::m_p_root, other.m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(other.m_p_root, false) base_type::m_p_root = other.m_p_root; } else { base_type::make_child_of(other.m_p_root, base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) } base_type::m_size += other.m_size; other.m_p_root = 0; other.m_size = 0; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1]~@3@3.8/ext/pb_ds/detail/container_base_dispatch.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file container_base_dispatch.hpp * Contains associative container dispatching. */ #ifndef PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP #define PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP #include #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #define PB_DS_CHECK_KEY_EXISTS(_Key) \ _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(_Key, __FILE__, __LINE__);) #define PB_DS_CHECK_KEY_DOES_NOT_EXIST(_Key) \ _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(_Key, \ __FILE__, __LINE__);) #define PB_DS_DATA_TRUE_INDICATOR #define PB_DS_V2F(X) (X).first #define PB_DS_V2S(X) (X).second #define PB_DS_EP2VP(X)& ((X)->m_value) #include #include #include #include #include #include #include #include #undef PB_DS_DATA_TRUE_INDICATOR #undef PB_DS_V2F #undef PB_DS_V2S #undef PB_DS_EP2VP #define PB_DS_DATA_FALSE_INDICATOR #define PB_DS_V2F(X) (X) #define PB_DS_V2S(X) Mapped_Data() #define PB_DS_EP2VP(X)& ((X)->m_value.first) #include #include #include #include #include #include #include #include #undef PB_DS_DATA_FALSE_INDICATOR #undef PB_DS_V2F #undef PB_DS_V2S #undef PB_DS_EP2VP #undef PB_DS_CHECK_KEY_DOES_NOT_EXIST #undef PB_DS_CHECK_KEY_EXISTS #undef PB_DS_DEBUG_VERIFY #undef PB_DS_ASSERT_VALID namespace __gnu_pbds { namespace detail { /// Specialization for list-update map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef lu_map type; }; /// Specialization for list-update set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef lu_set type; }; /// Specialization for PATRICIA trie map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: typedef pat_trie_map type; }; /// Specialization for PATRICIA trie set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef pat_trie_set type; }; /// Specialization for R-B tree map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef rb_tree_map type; }; /// Specialization for R-B tree set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: typedef rb_tree_set type; }; /// Specialization splay tree map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef splay_tree_map type; }; /// Specialization splay tree set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef splay_tree_set type; }; /// Specialization ordered-vector tree map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef ov_tree_map type; }; /// Specialization ordered-vector tree set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef ov_tree_set type; }; /// Specialization colision-chaining hash map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; public: /// Dispatched type. typedef cc_ht_map type; }; /// Specialization colision-chaining hash set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; public: /// Dispatched type. typedef cc_ht_set type; }; /// Specialization general-probe hash map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; typedef __gnu_cxx::typelist::at_index at5; typedef typename at5::type at5t; public: /// Dispatched type. typedef gp_ht_map type; }; /// Specialization general-probe hash set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; typedef __gnu_cxx::typelist::at_index at5; typedef typename at5::type at5t; public: /// Dispatched type. typedef gp_ht_set type; }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]RR48/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_.hpp * Contains an implementation class for a binomial heap. */ /* * Binomial heap. * Vuillemin J is the mastah. * Modified from CLRS. */ #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ binomial_heap /** * Binomial heap. * * @ingroup heap-detail */ template class binomial_heap : public binomial_heap_base { private: typedef binomial_heap_base base_type; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::cmp_fn cmp_fn; typedef typename base_type::allocator_type allocator_type; binomial_heap(); binomial_heap(const Cmp_Fn&); binomial_heap(const binomial_heap&); ~binomial_heap(); protected: #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif }; #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC } // namespace detail } // namespace __gnu_pbds PKgd1]tggE8/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/binomial_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for binomial_heap_. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binomial_heap() { } PKgd1]_Eii38/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/binomial_heap_/debug_fn_imps.hpp * Contains an implementation for binomial_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(true, __file, __line); } #endif PKgd1]N^^68/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/rotate_fn_imps.hpp * Contains imps for rotating nodes. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_left(node_pointer p_x) { node_pointer p_y = p_x->m_p_right; p_x->m_p_right = p_y->m_p_left; if (p_y->m_p_left != 0) p_y->m_p_left->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_left) p_x->m_p_parent->m_p_left = p_y; else p_x->m_p_parent->m_p_right = p_y; p_y->m_p_left = p_x; p_x->m_p_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_x) PB_DS_ASSERT_NODE_CONSISTENT(p_y) apply_update(p_x, (node_update* )this); apply_update(p_x->m_p_parent, (node_update* )this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_right(node_pointer p_x) { node_pointer p_y = p_x->m_p_left; p_x->m_p_left = p_y->m_p_right; if (p_y->m_p_right != 0) p_y->m_p_right->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_right) p_x->m_p_parent->m_p_right = p_y; else p_x->m_p_parent->m_p_left = p_y; p_y->m_p_right = p_x; p_x->m_p_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_x) PB_DS_ASSERT_NODE_CONSISTENT(p_y) apply_update(p_x, (node_update* )this); apply_update(p_x->m_p_parent, (node_update* )this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_parent(node_pointer p_nd) { node_pointer p_parent = p_nd->m_p_parent; if (p_nd == p_parent->m_p_left) rotate_right(p_parent); else rotate_left(p_parent); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) { } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) { node_update::operator()(node_iterator(p_nd), node_const_iterator(static_cast(0))); } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer p_nd, Node_Update_* p_update) { while (p_nd != m_p_head) { apply_update(p_nd, p_update); p_nd = p_nd->m_p_parent; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) { } PKgd1]C] ] 78/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/r_erase_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value));) p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~Node(); s_node_allocator.deallocate(p_nd, 1); } PKgd1]Mj$mm68/ext/pb_ds/detail/bin_search_tree_/node_iterators.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/node_iterators.hpp * Contains an implementation class for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP #define PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP #include namespace __gnu_pbds { namespace detail { #define PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC \ bin_search_tree_const_node_it_ /// Const node iterator. template class bin_search_tree_const_node_it_ { private: typedef typename _Alloc::template rebind< Node>::other::pointer node_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef Const_Iterator value_type; /// Iterator's reference type. typedef Const_Iterator reference; /// Iterator's __const reference type. typedef Const_Iterator const_reference; /// Metadata type. typedef typename Node::metadata_type metadata_type; /// Const metadata reference type. typedef typename _Alloc::template rebind::other::const_reference metadata_const_reference; bin_search_tree_const_node_it_(const node_pointer p_nd = 0) : m_p_nd(const_cast(p_nd)) { } /// Access. const_reference operator*() const { return Const_Iterator(m_p_nd); } /// Metadata access. metadata_const_reference get_metadata() const { return m_p_nd->get_metadata(); } /// Returns the __const node iterator associated with the left node. PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC get_l_child() const { return PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_left); } /// Returns the __const node iterator associated with the right node. PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC get_r_child() const { return PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_right); } /// Compares to a different iterator object. bool operator==(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const { return m_p_nd == other.m_p_nd; } /// Compares (negatively) to a different iterator object. bool operator!=(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; }; #define PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC \ bin_search_tree_node_it_ /// Node iterator. template class bin_search_tree_node_it_ : public PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC { private: typedef typename _Alloc::template rebind< Node>::other::pointer node_pointer; public: /// Iterator's value type. typedef Iterator value_type; /// Iterator's reference type. typedef Iterator reference; /// Iterator's __const reference type. typedef Iterator const_reference; inline bin_search_tree_node_it_(const node_pointer p_nd = 0) : PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(const_cast(p_nd)) { } /// Access. Iterator operator*() const { return Iterator(PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd); } /// Returns the node iterator associated with the left node. PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC get_l_child() const { return PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_left); } /// Returns the node iterator associated with the right node. PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC get_r_child() const { return PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_right); } }; #undef PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC #undef PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP PKgd1]ҿqq=8/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/policy_access_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return (*this); } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return (*this); } PKgd1]Z"G8/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/constructors_destructor_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_allocator PB_DS_CLASS_C_DEC::s_node_allocator; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn) : Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : Cmp_Fn(r_cmp_fn), node_update(r_node_update), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif #ifdef PB_DS_TREE_TRACE PB_DS_TREE_TRACE_BASE_C_DEC(other), #endif Cmp_Fn(other), node_update(other), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); m_size = other.m_size; PB_DS_STRUCT_ONLY_ASSERT_VALID(other) __try { m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); if (m_p_head->m_p_parent != 0) m_p_head->m_p_parent->m_p_parent = m_p_head; m_size = other.m_size; initialize_min_max(); } __catch(...) { _GLIBCXX_DEBUG_ONLY(debug_base::clear();) s_node_allocator.deallocate(m_p_head, 1); __throw_exception_again; } PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) value_swap(other); std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_head, other.m_p_head); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_BIN_TREE_NAME() { clear(); s_node_allocator.deallocate(m_p_head, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { m_p_head->m_p_parent = 0; m_p_head->m_p_left = m_p_head; m_p_head->m_p_right = m_p_head; m_size = 0; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(const node_pointer p_nd) { if (p_nd == 0) return (0); node_pointer p_ret = s_node_allocator.allocate(1); __try { new (p_ret) node(*p_nd); } __catch(...) { s_node_allocator.deallocate(p_ret, 1); __throw_exception_again; } p_ret->m_p_left = p_ret->m_p_right = 0; __try { p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left); p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right); } __catch(...) { clear_imp(p_ret); __throw_exception_again; } if (p_ret->m_p_left != 0) p_ret->m_p_left->m_p_parent = p_ret; if (p_ret->m_p_right != 0) p_ret->m_p_right->m_p_parent = p_ret; PB_DS_ASSERT_NODE_CONSISTENT(p_ret) return p_ret; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize_min_max() { if (m_p_head->m_p_parent == 0) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } { node_pointer p_min = m_p_head->m_p_parent; while (p_min->m_p_left != 0) p_min = p_min->m_p_left; m_p_head->m_p_left = p_min; } { node_pointer p_max = m_p_head->m_p_parent; while (p_max->m_p_right != 0) p_max = p_max->m_p_right; m_p_head->m_p_right = p_max; } } PKgd1]Y  48/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/info_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return (m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return (s_node_allocator.max_size()); } PKgd1]0VGG48/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/find_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) const { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) p_nd = p_nd->m_p_right; else { p_pot = p_nd; p_nd = p_nd->m_p_left; } return iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) p_nd = p_nd->m_p_right; else { p_pot = p_nd; p_nd = p_nd->m_p_left; } return iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) const { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return const_iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return point_iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; node_pointer ret = p_pot; if (p_pot != m_p_head) { const bool __cmp = Cmp_Fn::operator()(r_key, PB_DS_V2F(p_pot->m_value)); if (__cmp) ret = m_p_head; } return point_iterator(ret); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; node_pointer ret = p_pot; if (p_pot != m_p_head) { const bool __cmp = Cmp_Fn::operator()(r_key, PB_DS_V2F(p_pot->m_value)); if (__cmp) ret = m_p_head; } return point_const_iterator(ret); } PKgd1]B 98/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/iterators_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return (iterator(m_p_head->m_p_left)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return (const_iterator(m_p_head->m_p_left)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return (iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return (const_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() const { return (const_reverse_iterator(m_p_head->m_p_right)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() { return (reverse_iterator(m_p_head->m_p_right)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rend() { return (reverse_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rend() const { return (const_reverse_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return (node_const_iterator(m_p_head->m_p_parent)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return (node_iterator(m_p_head->m_p_parent)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return (node_const_iterator(0)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return (node_iterator(0)); } PKgd1]*`##78/ext/pb_ds/detail/bin_search_tree_/point_iterators.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/point_iterators.hpp * Contains an implementation class for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP #define PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_TREE_CONST_IT_C_DEC \ bin_search_tree_const_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_CONST_ODIR_IT_C_DEC \ bin_search_tree_const_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ !Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_IT_C_DEC \ bin_search_tree_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_ODIR_IT_C_DEC \ bin_search_tree_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ !Is_Forward_Iterator, \ _Alloc> /// Const iterator. template class bin_search_tree_const_it_ { public: typedef std::bidirectional_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef Value_Type value_type; typedef Pointer pointer; typedef Const_Pointer const_pointer; typedef Reference reference; typedef Const_Reference const_reference; inline bin_search_tree_const_it_(const Node_Pointer p_nd = 0) : m_p_nd(const_cast(p_nd)) { } inline bin_search_tree_const_it_(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) : m_p_nd(other.m_p_nd) { } inline PB_DS_TREE_CONST_IT_C_DEC& operator=(const PB_DS_TREE_CONST_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } inline PB_DS_TREE_CONST_IT_C_DEC& operator=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } inline const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return &m_p_nd->m_value; } inline const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return m_p_nd->m_value; } inline bool operator==(const PB_DS_TREE_CONST_IT_C_DEC & other) const { return m_p_nd == other.m_p_nd; } inline bool operator==(const PB_DS_TREE_CONST_ODIR_IT_C_DEC & other) const { return m_p_nd == other.m_p_nd; } inline bool operator!=(const PB_DS_TREE_CONST_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } inline bool operator!=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } inline PB_DS_TREE_CONST_IT_C_DEC& operator++() { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); inc(integral_constant()); return *this; } inline PB_DS_TREE_CONST_IT_C_DEC operator++(int) { PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); operator++(); return ret_it; } inline PB_DS_TREE_CONST_IT_C_DEC& operator--() { dec(integral_constant()); return *this; } inline PB_DS_TREE_CONST_IT_C_DEC operator--(int) { PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); operator--(); return ret_it; } protected: inline void inc(false_type) { dec(true_type()); } void inc(true_type) { if (m_p_nd->special()&& m_p_nd->m_p_parent->m_p_parent == m_p_nd) { m_p_nd = m_p_nd->m_p_left; return; } if (m_p_nd->m_p_right != 0) { m_p_nd = m_p_nd->m_p_right; while (m_p_nd->m_p_left != 0) m_p_nd = m_p_nd->m_p_left; return; } Node_Pointer p_y = m_p_nd->m_p_parent; while (m_p_nd == p_y->m_p_right) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (m_p_nd->m_p_right != p_y) m_p_nd = p_y; } inline void dec(false_type) { inc(true_type()); } void dec(true_type) { if (m_p_nd->special() && m_p_nd->m_p_parent->m_p_parent == m_p_nd) { m_p_nd = m_p_nd->m_p_right; return; } if (m_p_nd->m_p_left != 0) { Node_Pointer p_y = m_p_nd->m_p_left; while (p_y->m_p_right != 0) p_y = p_y->m_p_right; m_p_nd = p_y; return; } Node_Pointer p_y = m_p_nd->m_p_parent; while (m_p_nd == p_y->m_p_left) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (m_p_nd->m_p_left != p_y) m_p_nd = p_y; } public: Node_Pointer m_p_nd; }; /// Iterator. template class bin_search_tree_it_ : public PB_DS_TREE_CONST_IT_C_DEC { public: inline bin_search_tree_it_(const Node_Pointer p_nd = 0) : PB_DS_TREE_CONST_IT_C_DEC((Node_Pointer)p_nd) { } inline bin_search_tree_it_(const PB_DS_TREE_ODIR_IT_C_DEC& other) : PB_DS_TREE_CONST_IT_C_DEC(other.m_p_nd) { } inline PB_DS_TREE_IT_C_DEC& operator=(const PB_DS_TREE_IT_C_DEC& other) { base_it_type::m_p_nd = other.m_p_nd; return *this; } inline PB_DS_TREE_IT_C_DEC& operator=(const PB_DS_TREE_ODIR_IT_C_DEC& other) { base_it_type::m_p_nd = other.m_p_nd; return *this; } inline typename PB_DS_TREE_CONST_IT_C_DEC::pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != 0); return &base_it_type::m_p_nd->m_value; } inline typename PB_DS_TREE_CONST_IT_C_DEC::reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != 0); return base_it_type::m_p_nd->m_value; } inline PB_DS_TREE_IT_C_DEC& operator++() { PB_DS_TREE_CONST_IT_C_DEC:: operator++(); return *this; } inline PB_DS_TREE_IT_C_DEC operator++(int) { PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); operator++(); return ret_it; } inline PB_DS_TREE_IT_C_DEC& operator--() { PB_DS_TREE_CONST_IT_C_DEC:: operator--(); return *this; } inline PB_DS_TREE_IT_C_DEC operator--(int) { PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); operator--(); return ret_it; } protected: typedef PB_DS_TREE_CONST_IT_C_DEC base_it_type; }; #undef PB_DS_TREE_CONST_IT_C_DEC #undef PB_DS_TREE_CONST_ODIR_IT_C_DEC #undef PB_DS_TREE_IT_C_DEC #undef PB_DS_TREE_ODIR_IT_C_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]58/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/debug_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { structure_only_assert_valid(__file, __line); assert_consistent_with_debug_base(__file, __line); assert_size(__file, __line); assert_iterators(__file, __line); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_size == 0); } else { PB_DS_DEBUG_VERIFY(m_size > 0); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: structure_only_assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_p_head != 0); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_left == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_right == m_p_head); } else { PB_DS_DEBUG_VERIFY(m_p_head->m_p_parent->m_p_parent == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_left != m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_right != m_p_head); } if (m_p_head->m_p_parent != 0) assert_node_consistent(m_p_head->m_p_parent, __file, __line); assert_min(__file, __line); assert_max(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(const node_pointer p_nd, const char* __file, int __line) const { assert_node_consistent_(p_nd, __file, __line); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_consistent_t PB_DS_CLASS_C_DEC:: assert_node_consistent_(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return (std::make_pair((const_pointer)0,(const_pointer)0)); assert_node_consistent_with_left(p_nd, __file, __line); assert_node_consistent_with_right(p_nd, __file, __line); const std::pair l_range = assert_node_consistent_(p_nd->m_p_left, __file, __line); if (l_range.second != 0) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*l_range.second), PB_DS_V2F(p_nd->m_value))); const std::pair r_range = assert_node_consistent_(p_nd->m_p_right, __file, __line); if (r_range.first != 0) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(*r_range.first))); return std::make_pair((l_range.first != 0) ? l_range.first : &p_nd->m_value, (r_range.second != 0)? r_range.second : &p_nd->m_value); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent_with_left(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd->m_p_left == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_p_left->m_p_parent == p_nd); PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(p_nd->m_p_left->m_value))); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent_with_right(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd->m_p_right == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_p_right->m_p_parent == p_nd); PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_p_right->m_value), PB_DS_V2F(p_nd->m_value))); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_min(const char* __file, int __line) const { assert_min_imp(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_min_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_left == m_p_head); return; } if (p_nd->m_p_left == 0) { PB_DS_DEBUG_VERIFY(p_nd == m_p_head->m_p_left); return; } assert_min_imp(p_nd->m_p_left, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { assert_max_imp(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_right == m_p_head); return; } if (p_nd->m_p_right == 0) { PB_DS_DEBUG_VERIFY(p_nd == m_p_head->m_p_right); return; } assert_max_imp(p_nd->m_p_right, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { size_type iterated_num = 0; const_iterator prev_it = end(); for (const_iterator it = begin(); it != end(); ++it) { ++iterated_num; PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)).m_p_nd == it.m_p_nd); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it.m_p_nd == it.m_p_nd); if (prev_it != end()) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), PB_DS_V2F(*it))); prev_it = it; } PB_DS_DEBUG_VERIFY(iterated_num == m_size); size_type reverse_iterated_num = 0; const_reverse_iterator reverse_prev_it = rend(); for (const_reverse_iterator reverse_it = rbegin(); reverse_it != rend(); ++reverse_it) { ++reverse_iterated_num; PB_DS_DEBUG_VERIFY(lower_bound( PB_DS_V2F(*reverse_it)).m_p_nd == reverse_it.m_p_nd); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*reverse_it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it.m_p_nd == reverse_it.m_p_nd); if (reverse_prev_it != rend()) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(*reverse_prev_it), PB_DS_V2F(*reverse_it))); reverse_prev_it = reverse_it; } PB_DS_DEBUG_VERIFY(reverse_iterated_num == m_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_consistent_with_debug_base(const char* __file, int __line) const { debug_base::check_size(m_size, __file, __line); assert_consistent_with_debug_base(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_consistent_with_debug_base(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return; debug_base::check_key_exists(PB_DS_V2F(p_nd->m_value), __file, __line); assert_consistent_with_debug_base(p_nd->m_p_left, __file, __line); assert_consistent_with_debug_base(p_nd->m_p_right, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_size(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(recursive_count(m_p_head->m_p_parent) == m_size); } #endif PKgd1]Vii68/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/insert_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_leaf(const_reference r_value) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) if (m_size == 0) return std::make_pair(insert_imp_empty(r_value), true); node_pointer p_nd = m_p_head->m_p_parent; node_pointer p_pot = m_p_head; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; if (p_pot == m_p_head) return std::make_pair(insert_leaf_new(r_value, m_p_head->m_p_right, false), true); if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_pot->m_value))) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_value)) return std::make_pair(p_pot, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) p_nd = p_pot->m_p_left; if (p_nd == 0) return std::make_pair(insert_leaf_new(r_value, p_pot, true), true); while (p_nd->m_p_right != 0) p_nd = p_nd->m_p_right; return std::make_pair(insert_leaf_new(r_value, p_nd, false), true); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd) { node_pointer p_new_nd = get_new_node_for_leaf_insert(r_value, traits_base::m_no_throw_copies_indicator); if (left_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == 0); _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))); p_nd->m_p_left = p_new_nd; if (m_p_head->m_p_left == p_nd) m_p_head->m_p_left = p_new_nd; } else { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right == 0); _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))); p_nd->m_p_right = p_new_nd; if (m_p_head->m_p_right == p_nd) m_p_head->m_p_right = p_new_nd; } p_new_nd->m_p_parent = p_nd; p_new_nd->m_p_left = p_new_nd->m_p_right = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_nd) update_to_top(p_new_nd, (node_update* )this); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value));) return iterator(p_new_nd); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: insert_imp_empty(const_reference r_value) { node_pointer p_new_node = get_new_node_for_leaf_insert(r_value, traits_base::m_no_throw_copies_indicator); m_p_head->m_p_left = m_p_head->m_p_right = m_p_head->m_p_parent = p_new_node; p_new_node->m_p_parent = m_p_head; p_new_node->m_p_left = p_new_node->m_p_right = 0; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value));) update_to_top(m_p_head->m_p_parent, (node_update*)this); return iterator(p_new_node); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_leaf_insert(const_reference r_val, false_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); cond_dealtor_t cond(p_new_nd); new (const_cast(static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); cond.set_no_action(); p_new_nd->m_p_left = p_new_nd->m_p_right = 0; ++m_size; return p_new_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_leaf_insert(const_reference r_val, true_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); new (const_cast(static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); p_new_nd->m_p_left = p_new_nd->m_p_right = 0; ++m_size; return p_new_nd; } PKgd1]g g 58/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/erase_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_z->m_value));) p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~node(); s_node_allocator.deallocate(p_nd, 1); } PKgd1]E0088/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/bin_search_tree_.hpp * Contains an implementation class for binary search tree. */ #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #include #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_BIN_TREE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_BIN_TREE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_BIN_TREE_NAME #define PB_DS_BIN_TREE_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base, \ typename _Alloc::template rebind::other::const_reference> #endif #ifdef PB_DS_TREE_TRACE #define PB_DS_TREE_TRACE_BASE_C_DEC \ tree_trace_base #endif /* * @brief Binary search tree (BST). * * This implementation uses an idea from the SGI STL (using a @a * header node which is needed for efficient iteration). */ template class PB_DS_BIN_TREE_NAME : #ifdef _GLIBCXX_DEBUG public PB_DS_DEBUG_MAP_BASE_C_DEC, #endif #ifdef PB_DS_TREE_TRACE public PB_DS_TREE_TRACE_BASE_C_DEC, #endif public Cmp_Fn, public PB_DS_BIN_TREE_TRAITS_BASE, public Node_And_It_Traits::node_update { typedef Node_And_It_Traits traits_type; protected: typedef PB_DS_BIN_TREE_TRAITS_BASE traits_base; typedef typename _Alloc::template rebind::other node_allocator; typedef typename node_allocator::value_type node; typedef typename node_allocator::pointer node_pointer; typedef typename traits_type::null_node_update_pointer null_node_update_pointer; private: typedef cond_dealtor cond_dealtor_t; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; #endif typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef typename traits_type::point_const_iterator point_const_iterator; typedef point_const_iterator const_iterator; typedef typename traits_type::point_iterator point_iterator; typedef point_iterator iterator; typedef typename traits_type::const_reverse_iterator const_reverse_iterator; typedef typename traits_type::reverse_iterator reverse_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_update node_update; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; PB_DS_BIN_TREE_NAME(); PB_DS_BIN_TREE_NAME(const Cmp_Fn&); PB_DS_BIN_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~PB_DS_BIN_TREE_NAME(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline point_iterator lower_bound(key_const_reference); inline point_const_iterator lower_bound(key_const_reference) const; inline point_iterator upper_bound(key_const_reference); inline point_const_iterator upper_bound(key_const_reference) const; inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline reverse_iterator rbegin(); inline const_reverse_iterator rbegin() const; inline reverse_iterator rend(); inline const_reverse_iterator rend() const; /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); void clear(); protected: void value_swap(PB_DS_CLASS_C_DEC&); void initialize_min_max(); inline iterator insert_imp_empty(const_reference); inline iterator insert_leaf_new(const_reference, node_pointer, bool); inline node_pointer get_new_node_for_leaf_insert(const_reference, false_type); inline node_pointer get_new_node_for_leaf_insert(const_reference, true_type); inline void actual_erase_node(node_pointer); inline std::pair erase(node_pointer); inline void update_min_max_for_erased_node(node_pointer); static void clear_imp(node_pointer); inline std::pair insert_leaf(const_reference); inline void rotate_left(node_pointer); inline void rotate_right(node_pointer); inline void rotate_parent(node_pointer); inline void apply_update(node_pointer, null_node_update_pointer); template inline void apply_update(node_pointer, Node_Update_*); inline void update_to_top(node_pointer, null_node_update_pointer); template inline void update_to_top(node_pointer, Node_Update_*); bool join_prep(PB_DS_CLASS_C_DEC&); void join_finish(PB_DS_CLASS_C_DEC&); bool split_prep(key_const_reference, PB_DS_CLASS_C_DEC&); void split_finish(PB_DS_CLASS_C_DEC&); size_type recursive_count(node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void structure_only_assert_valid(const char*, int) const; void assert_node_consistent(const node_pointer, const char*, int) const; #endif private: #ifdef _GLIBCXX_DEBUG void assert_iterators(const char*, int) const; void assert_consistent_with_debug_base(const char*, int) const; void assert_node_consistent_with_left(const node_pointer, const char*, int) const; void assert_node_consistent_with_right(const node_pointer, const char*, int) const; void assert_consistent_with_debug_base(const node_pointer, const char*, int) const; void assert_min(const char*, int) const; void assert_min_imp(const node_pointer, const char*, int) const; void assert_max(const char*, int) const; void assert_max_imp(const node_pointer, const char*, int) const; void assert_size(const char*, int) const; typedef std::pair node_consistent_t; node_consistent_t assert_node_consistent_(const node_pointer, const char*, int) const; #endif void initialize(); node_pointer recursive_copy_node(const node_pointer); protected: node_pointer m_p_head; size_type m_size; static node_allocator s_node_allocator; }; #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);) #define PB_DS_ASSERT_NODE_CONSISTENT(_Node) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, __FILE__, __LINE__);) #include #include #include #include #include #include #include #include #include #include #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_STRUCT_ONLY_ASSERT_VALID #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_BIN_TREE_NAME #undef PB_DS_BIN_TREE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #ifdef PB_DS_TREE_TRACE #undef PB_DS_TREE_TRACE_BASE_C_DEC #endif } // namespace detail } // namespace __gnu_pbds PKgd1]/:8/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/split_join_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: join_prep(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return false; if (m_size == 0) { value_swap(other); return false; } const bool greater = Cmp_Fn::operator()(PB_DS_V2F(m_p_head->m_p_right->m_value), PB_DS_V2F(other.m_p_head->m_p_left->m_value)); const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(other.m_p_head->m_p_right->m_value), PB_DS_V2F(m_p_head->m_p_left->m_value)); if (!greater && !lesser) __throw_join_error(); if (lesser) value_swap(other); m_size += other.m_size; _GLIBCXX_DEBUG_ONLY(debug_base::join(other);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join_finish(PB_DS_CLASS_C_DEC& other) { initialize_min_max(); other.initialize(); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (m_size == 0) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_left->m_value))) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_right->m_value))) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (m_size == 1) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(Cmp_Fn& )(*this), other);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_finish(PB_DS_CLASS_C_DEC& other) { other.initialize_min_max(); other.m_size = std::distance(other.begin(), other.end()); m_size -= other.m_size; initialize_min_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: recursive_count(node_pointer p) const { if (p == 0) return 0; return 1 + recursive_count(p->m_p_left) + recursive_count(p->m_p_right); } PKgd1]i.8/ext/pb_ds/detail/bin_search_tree_/traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/traits.hpp * Contains an implementation for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP #include #include namespace __gnu_pbds { namespace detail { /// Binary search tree traits, primary template /// @ingroup traits template class Node_Update, class Node, typename _Alloc> struct bin_search_tree_traits { private: typedef types_traits type_traits; public: typedef Node node; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_const_iterator; typedef bin_search_tree_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_iterator; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> const_reverse_iterator; typedef bin_search_tree_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef bin_search_tree_const_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_const_iterator; typedef bin_search_tree_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_iterator; typedef Node_Update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template class Node_Update, class Node, typename _Alloc> struct bin_search_tree_traits { private: typedef types_traits type_traits; public: typedef Node node; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_const_iterator; typedef point_const_iterator point_iterator; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef bin_search_tree_const_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; typedef Node_Update node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP PKgd1]GQ=JJ:8/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_resize_trigger.hpp * Contains a sample resize trigger policy class. */ #ifndef PB_DS_SAMPLE_RESIZE_TRIGGER_HPP #define PB_DS_SAMPLE_RESIZE_TRIGGER_HPP namespace __gnu_pbds { /// A sample resize trigger policy. class sample_resize_trigger { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_resize_trigger(); /// Copy constructor. sample_range_hashing(const sample_resize_trigger&); /// Swaps content. inline void swap(sample_resize_trigger&); protected: /// Notifies a search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies a search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. the total number of entries in /// the table is num_entries. inline void notify_inserted(size_type num_entries); /// Notifies an element was erased. inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); /// Notifies the table was resized externally. void notify_externally_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries whether a grow is needed. inline bool is_grow_needed(size_type size, size_type num_entries) const; private: /// Resizes to new_size. virtual void do_resize(size_type); }; } #endif PKgd1]у E8/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_exponential_size_policy_imp.hpp * Contains a resize size policy implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_exponential_size_policy(size_type start_size, size_type grow_factor) : m_start_size(start_size), m_grow_factor(grow_factor) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_start_size, other.m_start_size); std::swap(m_grow_factor, other.m_grow_factor); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_larger_size(size_type size) const { size_type ret = m_start_size; while (ret <= size) { const size_type next_ret = ret* m_grow_factor; if (next_ret < ret) __throw_insert_error(); ret = next_ret; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_smaller_size(size_type size) const { size_type ret = m_start_size; while (true) { const size_type next_ret = ret* m_grow_factor; if (next_ret < ret) __throw_resize_error(); if (next_ret >= size) return (ret); ret = next_ret; } return ret; } PKgd1]8{ { 78/ext/pb_ds/detail/resize_policy/sample_size_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_size_policy.hpp * Contains a sample size resize-policy. */ #ifndef PB_DS_SAMPLE_SIZE_POLICY_HPP #define PB_DS_SAMPLE_SIZE_POLICY_HPP namespace __gnu_pbds { /// A sample size policy. class sample_size_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_size_policy(); /// Copy constructor. sample_range_hashing(const sample_size_policy&); /// Swaps content. inline void swap(sample_size_policy& other); protected: /// Given a __size size, returns a __size that is larger. inline size_type get_nearest_larger_size(size_type size) const; /// Given a __size size, returns a __size that is smaller. inline size_type get_nearest_smaller_size(size_type size) const; }; } #endif PKgd1]g3##S8/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_max_collision_check_resize_trigger_imp.hpp * Contains a resize trigger implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: cc_hash_max_collision_check_resize_trigger(float load) : m_load(load), m_size(0), m_num_col(0), m_max_col(0), m_resize_needed(false) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { m_num_col = 0; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { ++m_num_col; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { calc_resize_needed(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type) { m_resize_needed = true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { m_resize_needed = false; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { return m_resize_needed; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_grow_needed(size_type /*size*/, size_type /*num_used_e*/) const { return m_num_col >= m_max_col; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { m_size = new_size; #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "chmccrt::notify_resized " << static_cast(new_size) << std::endl; #endif calc_max_num_coll(); calc_resize_needed(); m_num_col = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: calc_max_num_coll() { // max_col <-- \sqrt{2 load \ln( 2 m \ln( m ) ) } const double ln_arg = 2 * m_size * std::log(double(m_size)); m_max_col = size_type(std::ceil(std::sqrt(2 * m_load * std::log(ln_arg)))); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "chmccrt::calc_max_num_coll " << static_cast(m_size) << " " << static_cast(m_max_col) << std::endl; #endif } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_externally_resized(size_type new_size) { notify_resized(new_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_load, other.m_load); std::swap(m_size, other.m_size); std::swap(m_num_col, other.m_num_col); std::swap(m_max_col, other.m_max_col); std::swap(m_resize_needed, other.m_resize_needed); } PB_DS_CLASS_T_DEC inline float PB_DS_CLASS_C_DEC:: get_load() const { PB_DS_STATIC_ASSERT(access, external_load_access); return m_load; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: calc_resize_needed() { m_resize_needed = m_resize_needed || m_num_col >= m_max_col; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: set_load(float load) { PB_DS_STATIC_ASSERT(access, external_load_access); m_load = load; calc_max_num_coll(); calc_resize_needed(); } PKgd1]#f 98/ext/pb_ds/detail/resize_policy/sample_resize_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_resize_policy.hpp * Contains a sample resize policy for hash tables. */ #ifndef PB_DS_SAMPLE_RESIZE_POLICY_HPP #define PB_DS_SAMPLE_RESIZE_POLICY_HPP namespace __gnu_pbds { /// A sample resize policy. class sample_resize_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_resize_policy(); /// Copy constructor. sample_range_hashing(const sample_resize_policy& other); /// Swaps content. inline void swap(sample_resize_policy& other); protected: /// Notifies a search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies a search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. inline void notify_inserted(size_type num_e); /// Notifies an element was erased. inline void notify_erased(size_type num_e); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized to new_size. void notify_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries what the new size should be. size_type get_new_size(size_type size, size_type num_used_e) const; }; } #endif PKgd1]4 HHG8/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_load_check_resize_trigger_imp.hpp * Contains a resize trigger implementation. */ #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_load_check_resize_trigger(float load_min, float load_max) : m_load_min(load_min), m_load_max(load_max), m_next_shrink_size(0), m_next_grow_size(0), m_resize_needed(false) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type num_entries) { m_resize_needed = (num_entries >= m_next_grow_size); size_base::set_size(num_entries); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type num_entries) { size_base::set_size(num_entries); m_resize_needed = num_entries <= m_next_shrink_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { PB_DS_ASSERT_VALID((*this)) return m_resize_needed; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_grow_needed(size_type /*size*/, size_type num_entries) const { _GLIBCXX_DEBUG_ASSERT(m_resize_needed); return num_entries >= m_next_grow_size; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~hash_load_check_resize_trigger() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { m_resize_needed = false; m_next_grow_size = size_type(m_load_max * new_size - 1); m_next_shrink_size = size_type(m_load_min * new_size); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "hlcrt::notify_resized " << std::endl << "1 " << new_size << std::endl << "2 " << m_load_min << std::endl << "3 " << m_load_max << std::endl << "4 " << m_next_shrink_size << std::endl << "5 " << m_next_grow_size << std::endl; #endif PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_externally_resized(size_type new_size) { m_resize_needed = false; size_type new_grow_size = size_type(m_load_max * new_size - 1); size_type new_shrink_size = size_type(m_load_min * new_size); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "hlcrt::notify_externally_resized " << std::endl << "1 " << new_size << std::endl << "2 " << m_load_min << std::endl << "3 " << m_load_max << std::endl << "4 " << m_next_shrink_size << std::endl << "5 " << m_next_grow_size << std::endl << "6 " << new_shrink_size << std::endl << "7 " << new_grow_size << std::endl; #endif if (new_grow_size >= m_next_grow_size) { _GLIBCXX_DEBUG_ASSERT(new_shrink_size >= m_next_shrink_size); m_next_grow_size = new_grow_size; } else { _GLIBCXX_DEBUG_ASSERT(new_shrink_size <= m_next_shrink_size); m_next_shrink_size = new_shrink_size; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { PB_DS_ASSERT_VALID((*this)) size_base::set_size(0); m_resize_needed = (0 < m_next_shrink_size); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) size_base::swap(other); std::swap(m_load_min, other.m_load_min); std::swap(m_load_max, other.m_load_max); std::swap(m_resize_needed, other.m_resize_needed); std::swap(m_next_grow_size, other.m_next_grow_size); std::swap(m_next_shrink_size, other.m_next_shrink_size); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: get_loads() const { PB_DS_STATIC_ASSERT(access, external_load_access); return std::make_pair(m_load_min, m_load_max); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: set_loads(std::pair load_pair) { PB_DS_STATIC_ASSERT(access, external_load_access); const float old_load_min = m_load_min; const float old_load_max = m_load_max; const size_type old_next_shrink_size = m_next_shrink_size; const size_type old_next_grow_size = m_next_grow_size; const bool old_resize_needed = m_resize_needed; __try { m_load_min = load_pair.first; m_load_max = load_pair.second; do_resize(static_cast(size_base::get_size() / ((m_load_min + m_load_max) / 2))); } __catch(...) { m_load_min = old_load_min; m_load_max = old_load_max; m_next_shrink_size = old_next_shrink_size; m_next_grow_size = old_next_grow_size; m_resize_needed = old_resize_needed; __throw_exception_again; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type) { std::abort(); } #ifdef _GLIBCXX_DEBUG # define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_load_max > m_load_min); PB_DS_DEBUG_VERIFY(m_next_grow_size >= m_next_shrink_size); } # undef PB_DS_DEBUG_VERIFY #endif #undef PB_DS_ASSERT_VALID PKgd1]18D8/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_standard_resize_policy_imp.hpp * Contains a resize policy implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy() : m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy(const Size_Policy& r_size_policy) : Size_Policy(r_size_policy), m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy(const Size_Policy& r_size_policy, const Trigger_Policy& r_trigger_policy) : Size_Policy(r_size_policy), Trigger_Policy(r_trigger_policy), m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~hash_standard_resize_policy() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { trigger_policy_base::swap(other); size_policy_base::swap(other); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { trigger_policy_base::notify_find_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { trigger_policy_base::notify_find_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { trigger_policy_base::notify_find_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { trigger_policy_base::notify_insert_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { trigger_policy_base::notify_insert_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { trigger_policy_base::notify_insert_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { trigger_policy_base::notify_erase_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { trigger_policy_base::notify_erase_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { trigger_policy_base::notify_erase_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type num_e) { trigger_policy_base::notify_inserted(num_e); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type num_e) { trigger_policy_base::notify_erased(num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { trigger_policy_base::notify_cleared(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { return trigger_policy_base::is_resize_needed(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_new_size(size_type size, size_type num_used_e) const { if (trigger_policy_base::is_grow_needed(size, num_used_e)) return size_policy_base::get_nearest_larger_size(size); return size_policy_base::get_nearest_smaller_size(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { trigger_policy_base::notify_resized(new_size); m_size = new_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_actual_size() const { PB_DS_STATIC_ASSERT(access, external_size_access); return m_size; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize(size_type new_size) { PB_DS_STATIC_ASSERT(access, external_size_access); size_type actual_size = size_policy_base::get_nearest_larger_size(1); while (actual_size < new_size) { const size_type pot = size_policy_base::get_nearest_larger_size(actual_size); if (pot == actual_size && pot < new_size) __throw_resize_error(); actual_size = pot; } if (actual_size > 0) --actual_size; const size_type old_size = m_size; __try { do_resize(actual_size - 1); } __catch(insert_error& ) { m_size = old_size; __throw_resize_error(); } __catch(...) { m_size = old_size; __throw_exception_again; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type) { // Do nothing } PB_DS_CLASS_T_DEC Trigger_Policy& PB_DS_CLASS_C_DEC:: get_trigger_policy() { return *this; } PB_DS_CLASS_T_DEC const Trigger_Policy& PB_DS_CLASS_C_DEC:: get_trigger_policy() const { return *this; } PB_DS_CLASS_T_DEC Size_Policy& PB_DS_CLASS_C_DEC:: get_size_policy() { return *this; } PB_DS_CLASS_T_DEC const Size_Policy& PB_DS_CLASS_C_DEC:: get_size_policy() const { return *this; } PKgd1]cy?8/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_prime_size_policy_imp.hpp * Contains a resize size policy implementation. */ #pragma GCC system_header namespace detail { enum { num_distinct_sizes_32_bit = 30, num_distinct_sizes_64_bit = 62, num_distinct_sizes = sizeof(std::size_t) != 8 ? num_distinct_sizes_32_bit : num_distinct_sizes_64_bit, }; // Originally taken from the SGI implementation; acknowledged in the docs. // Further modified (for 64 bits) from tr1's hashtable. static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] = { /* 0 */ 5ul, /* 1 */ 11ul, /* 2 */ 23ul, /* 3 */ 47ul, /* 4 */ 97ul, /* 5 */ 199ul, /* 6 */ 409ul, /* 7 */ 823ul, /* 8 */ 1741ul, /* 9 */ 3469ul, /* 10 */ 6949ul, /* 11 */ 14033ul, /* 12 */ 28411ul, /* 13 */ 57557ul, /* 14 */ 116731ul, /* 15 */ 236897ul, /* 16 */ 480881ul, /* 17 */ 976369ul, /* 18 */ 1982627ul, /* 19 */ 4026031ul, /* 20 */ 8175383ul, /* 21 */ 16601593ul, /* 22 */ 33712729ul, /* 23 */ 68460391ul, /* 24 */ 139022417ul, /* 25 */ 282312799ul, /* 26 */ 573292817ul, /* 27 */ 1164186217ul, /* 28 */ 2364114217ul, /* 29 */ 4294967291ul, /* 30 */ (std::size_t)8589934583ull, /* 31 */ (std::size_t)17179869143ull, /* 32 */ (std::size_t)34359738337ull, /* 33 */ (std::size_t)68719476731ull, /* 34 */ (std::size_t)137438953447ull, /* 35 */ (std::size_t)274877906899ull, /* 36 */ (std::size_t)549755813881ull, /* 37 */ (std::size_t)1099511627689ull, /* 38 */ (std::size_t)2199023255531ull, /* 39 */ (std::size_t)4398046511093ull, /* 40 */ (std::size_t)8796093022151ull, /* 41 */ (std::size_t)17592186044399ull, /* 42 */ (std::size_t)35184372088777ull, /* 43 */ (std::size_t)70368744177643ull, /* 44 */ (std::size_t)140737488355213ull, /* 45 */ (std::size_t)281474976710597ull, /* 46 */ (std::size_t)562949953421231ull, /* 47 */ (std::size_t)1125899906842597ull, /* 48 */ (std::size_t)2251799813685119ull, /* 49 */ (std::size_t)4503599627370449ull, /* 50 */ (std::size_t)9007199254740881ull, /* 51 */ (std::size_t)18014398509481951ull, /* 52 */ (std::size_t)36028797018963913ull, /* 53 */ (std::size_t)72057594037927931ull, /* 54 */ (std::size_t)144115188075855859ull, /* 55 */ (std::size_t)288230376151711717ull, /* 56 */ (std::size_t)576460752303423433ull, /* 57 */ (std::size_t)1152921504606846883ull, /* 58 */ (std::size_t)2305843009213693951ull, /* 59 */ (std::size_t)4611686018427387847ull, /* 60 */ (std::size_t)9223372036854775783ull, /* 61 */ (std::size_t)18446744073709551557ull, }; } // namespace detail PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC:: hash_prime_size_policy(size_type n) : m_start_size(n) { m_start_size = get_nearest_larger_size(n); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_start_size, other.m_start_size); } PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_larger_size(size_type n) const { const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, detail::g_a_sizes + detail::num_distinct_sizes, n); if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes) __throw_resize_error(); return *p_upper; } PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_smaller_size(size_type n) const { const std::size_t* p_lower = std::lower_bound(detail::g_a_sizes, detail::g_a_sizes + detail::num_distinct_sizes, n); if (*p_lower >= n && p_lower != detail::g_a_sizes) --p_lower; if (*p_lower < m_start_size) return m_start_size; return *p_lower; } PKgd1])O M8/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_load_check_resize_trigger_size_base.hpp * Contains an base holding size for some resize policies. */ #ifndef PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP #define PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP namespace __gnu_pbds { namespace detail { /// Primary template. template class hash_load_check_resize_trigger_size_base; /// Specializations. template class hash_load_check_resize_trigger_size_base { protected: typedef Size_Type size_type; hash_load_check_resize_trigger_size_base(): m_size(0) { } inline void swap(hash_load_check_resize_trigger_size_base& other) { std::swap(m_size, other.m_size); } inline void set_size(size_type size) { m_size = size; } inline size_type get_size() const { return m_size; } private: size_type m_size; }; template class hash_load_check_resize_trigger_size_base { protected: typedef Size_Type size_type; protected: inline void swap(hash_load_check_resize_trigger_size_base& other) { } inline void set_size(size_type size) { } }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]278/ext/pb_ds/detail/tree_policy/order_statistics_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/order_statistics_imp.hpp * Contains forward declarations for order_statistics_key */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) { node_iterator it = node_begin(); node_iterator end_it = node_end(); while (it != end_it) { node_iterator l_it = it.get_l_child(); const size_type o = (l_it == end_it)? 0 : l_it.get_metadata(); if (order == o) return *it; else if (order < o) it = l_it; else { order -= o + 1; it = it.get_r_child(); } } return base_type::end_iterator(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) const { return const_cast(this)->find_by_order(order); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_key(key_const_reference r_key) const { node_const_iterator it = node_begin(); node_const_iterator end_it = node_end(); const cmp_fn& r_cmp_fn = const_cast(this)->get_cmp_fn(); size_type ord = 0; while (it != end_it) { node_const_iterator l_it = it.get_l_child(); if (r_cmp_fn(r_key, this->extract_key(*(*it)))) it = l_it; else if (r_cmp_fn(this->extract_key(*(*it)), r_key)) { ord += (l_it == end_it)? 1 : 1 + l_it.get_metadata(); it = it.get_r_child(); } else { ord += (l_it == end_it)? 0 : l_it.get_metadata(); it = end_it; } } return ord; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator node_it, node_const_iterator end_nd_it) const { node_iterator l_it = node_it.get_l_child(); const size_type l_rank = (l_it == end_nd_it) ? 0 : l_it.get_metadata(); node_iterator r_it = node_it.get_r_child(); const size_type r_rank = (r_it == end_nd_it) ? 0 : r_it.get_metadata(); const_cast(node_it.get_metadata())= 1 + l_rank + r_rank; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~tree_order_statistics_node_update() { } PKgd1]a( 98/ext/pb_ds/detail/tree_policy/node_metadata_selector.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/node_metadata_selector.hpp * Contains an implementation class for trees. */ #ifndef PB_DS_TREE_NODE_METADATA_DISPATCH_HPP #define PB_DS_TREE_NODE_METADATA_DISPATCH_HPP #include #include namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Tree metadata helper. template struct tree_metadata_helper; /// Specialization, false. template struct tree_metadata_helper { typedef typename Node_Update::metadata_type type; }; /// Specialization, true. template struct tree_metadata_helper { typedef null_type type; }; /// Tree node metadata dispatch. template class Node_Update, typename _Alloc> struct tree_node_metadata_dispatch { private: typedef dumnode_const_iterator __it_type; typedef Node_Update<__it_type, __it_type, Cmp_Fn, _Alloc> __node_u; typedef null_node_update<__it_type, __it_type, Cmp_Fn, _Alloc> __nnode_u; enum { null_update = is_same<__node_u, __nnode_u>::value }; public: typedef typename tree_metadata_helper<__node_u, null_update>::type type; }; //@} } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TREE_NODE_METADATA_DISPATCH_HPP PKgd1]5'* * :8/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/sample_tree_node_update.hpp * Contains a samle node update functor. */ #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP #define PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP namespace __gnu_pbds { /// A sample node updator. template class sample_tree_node_update { typedef std::size_t metadata_type; /// Default constructor. sample_tree_node_update(); /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator node_it, node_const_iterator end_nd_it) const; }; } #endif // #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP PKgd1]Ld  '8/ext/pb_ds/detail/eq_fn/eq_by_less.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file eq_by_less.hpp * Contains an equivalence function. */ #ifndef PB_DS_EQ_BY_LESS_HPP #define PB_DS_EQ_BY_LESS_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { /// Equivalence function. template struct eq_by_less : private Cmp_Fn { bool operator()(const Key& r_lhs, const Key& r_rhs) const { const bool l = Cmp_Fn::operator()(r_lhs, r_rhs); const bool g = Cmp_Fn::operator()(r_rhs, r_lhs); return !(l || g); } }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_EQ_BY_LESS_HPP PKgd1]d9'8/ext/pb_ds/detail/eq_fn/hash_eq_fn.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_eq_fn.hpp * Contains 2 eqivalence functions, one employing a hash value, * and one ignoring it. */ #ifndef PB_DS_HASH_EQ_FN_HPP #define PB_DS_HASH_EQ_FN_HPP #include #include namespace __gnu_pbds { namespace detail { /// Primary template. template struct hash_eq_fn; /// Specialization 1 - The client requests that hash values not be stored. template struct hash_eq_fn : public Eq_Fn { typedef Eq_Fn eq_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; hash_eq_fn() { } hash_eq_fn(const Eq_Fn& r_eq_fn) : Eq_Fn(r_eq_fn) { } bool operator()(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return eq_fn_base::operator()(r_lhs_key, r_rhs_key); } void swap(const hash_eq_fn& other) { std::swap((Eq_Fn&)(*this), (Eq_Fn&)other); } }; /// Specialization 2 - The client requests that hash values be stored. template struct hash_eq_fn : public Eq_Fn { typedef typename _Alloc::size_type size_type; typedef Eq_Fn eq_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; hash_eq_fn() { } hash_eq_fn(const Eq_Fn& r_eq_fn) : Eq_Fn(r_eq_fn) { } bool operator()(key_const_reference r_lhs_key, size_type lhs_hash, key_const_reference r_rhs_key, size_type rhs_hash) const { _GLIBCXX_DEBUG_ASSERT(!eq_fn_base::operator()(r_lhs_key, r_rhs_key) || lhs_hash == rhs_hash); return (lhs_hash == rhs_hash && eq_fn_base::operator()(r_lhs_key, r_rhs_key)); } void swap(const hash_eq_fn& other) { std::swap((Eq_Fn&)(*this), (Eq_Fn&)(other)); } }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]ko<<C8/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap_const_iterator_ #define PB_DS_BASIC_HEAP_CIT_BASE \ left_child_next_sibling_heap_node_point_const_iterator_ /// Const point-type iterator. template class left_child_next_sibling_heap_const_iterator_ : public PB_DS_BASIC_HEAP_CIT_BASE { private: typedef PB_DS_BASIC_HEAP_CIT_BASE base_type; typedef typename base_type::node_pointer node_pointer; public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef typename base_type::value_type value_type; /// Iterator's pointer type. typedef typename base_type::pointer pointer; /// Iterator's const pointer type. typedef typename base_type::const_pointer const_pointer; /// Iterator's reference type. typedef typename base_type::reference reference; /// Iterator's const reference type. typedef typename base_type::const_reference const_reference; inline left_child_next_sibling_heap_const_iterator_(node_pointer p_nd) : base_type(p_nd) { } /// Default constructor. inline left_child_next_sibling_heap_const_iterator_() { } /// Copy constructor. inline left_child_next_sibling_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) { } /// Compares content to a different iterator object. bool operator==(const PB_DS_CLASS_C_DEC& other) const { return (base_type::m_p_nd == other.m_p_nd); } /// Compares content (negatively) to a different iterator object. bool operator!=(const PB_DS_CLASS_C_DEC& other) const { return (base_type::m_p_nd != other.m_p_nd); } PB_DS_CLASS_C_DEC& operator++() { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd != 0); inc(); return (*this); } PB_DS_CLASS_C_DEC operator++(int) { PB_DS_CLASS_C_DEC ret_it(base_type::m_p_nd); operator++(); return (ret_it); } private: void inc() { if (base_type::m_p_nd->m_p_next_sibling != 0) { base_type::m_p_nd = base_type::m_p_nd->m_p_next_sibling; while (base_type::m_p_nd->m_p_l_child != 0) base_type::m_p_nd = base_type::m_p_nd->m_p_l_child; return; } while (true) { node_pointer p_next = base_type::m_p_nd; base_type::m_p_nd = base_type::m_p_nd->m_p_prev_or_parent; if (base_type::m_p_nd == 0 || base_type::m_p_nd->m_p_l_child == p_next) return; } } }; #undef PB_DS_CLASS_C_DEC #undef PB_DS_BASIC_HEAP_CIT_BASE } // namespace detail } // namespace __gnu_pbds #endif PKgd1][ht 98/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/node.hpp * Contains an implementation struct for this type of heap's node. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP namespace __gnu_pbds { namespace detail { /// Node. template struct left_child_next_sibling_heap_node_ { private: typedef left_child_next_sibling_heap_node_<_Value, _Metadata, _Alloc> this_type; public: typedef _Value value_type; typedef typename _Alloc::size_type size_type; typedef _Metadata metadata_type; typedef typename _Alloc::template rebind::other::pointer node_pointer; value_type m_value; metadata_type m_metadata; node_pointer m_p_l_child; node_pointer m_p_next_sibling; node_pointer m_p_prev_or_parent; }; template struct left_child_next_sibling_heap_node_<_Value, null_type, _Alloc> { private: typedef left_child_next_sibling_heap_node_<_Value, null_type, _Alloc> this_type; public: typedef _Value value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::template rebind::other::pointer node_pointer; value_type m_value; node_pointer m_p_l_child; node_pointer m_p_next_sibling; node_pointer m_p_prev_or_parent; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP PKgd1]sR B8/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/trace_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef PB_DS_LC_NS_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; trace_node(m_p_root, 0); std::cerr << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_pointer p_nd, size_type level) { while (p_nd != 0) { for (size_type i = 0; i < level; ++i) std::cerr << ' '; std::cerr << p_nd << " prev = " << p_nd->m_p_prev_or_parent << " next " << p_nd->m_p_next_sibling << " left = " << p_nd->m_p_l_child << " "; trace_node_metadata(p_nd, type_to_type()); std::cerr << p_nd->m_value << std::endl; trace_node(p_nd->m_p_l_child, level + 1); p_nd = p_nd->m_p_next_sibling; } } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer p_nd, type_to_type) { std::cerr << "(" << p_nd->m_metadata << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer, type_to_type) { } #endif // #ifdef PB_DS_LC_NS_HEAP_TRACE_ PKgd1]ՇJ8/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/policy_access_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return *this; } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return *this; } PKgd1] T8/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_allocator PB_DS_CLASS_C_DEC::s_node_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::no_throw_copies_t PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap() : m_p_root(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap(const Cmp_Fn& r_cmp_fn) : Cmp_Fn(r_cmp_fn), m_p_root(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap(const PB_DS_CLASS_C_DEC& other) : Cmp_Fn(other), m_p_root(0), m_size(0) { m_size = other.m_size; PB_DS_ASSERT_VALID(other) m_p_root = recursive_copy_node(other.m_p_root); m_size = other.m_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_p_root, other.m_p_root); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~left_child_next_sibling_heap() { clear(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(node_const_pointer p_nd) { if (p_nd == 0) return (0); node_pointer p_ret = s_node_allocator.allocate(1); __try { new (p_ret) node(*p_nd); } __catch(...) { s_node_allocator.deallocate(p_ret, 1); __throw_exception_again; } p_ret->m_p_l_child = p_ret->m_p_next_sibling = p_ret->m_p_prev_or_parent = 0; __try { p_ret->m_p_l_child = recursive_copy_node(p_nd->m_p_l_child); p_ret->m_p_next_sibling = recursive_copy_node(p_nd->m_p_next_sibling); } __catch(...) { clear_imp(p_ret); __throw_exception_again; } if (p_ret->m_p_l_child != 0) p_ret->m_p_l_child->m_p_prev_or_parent = p_ret; if (p_ret->m_p_next_sibling != 0) p_ret->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd ? p_ret : 0; return p_ret; } PKgd1]k͐I8/ext/pb_ds/detail/left_child_next_sibling_heap_/point_const_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/point_const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap_node_point_const_iterator_ /// Const point-type iterator. template class left_child_next_sibling_heap_node_point_const_iterator_ { protected: typedef typename _Alloc::template rebind::other::pointer node_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef typename Node::value_type value_type; /// Iterator's pointer type. typedef typename _Alloc::template rebind< value_type>::other::pointer pointer; /// Iterator's const pointer type. typedef typename _Alloc::template rebind< value_type>::other::const_pointer const_pointer; /// Iterator's reference type. typedef typename _Alloc::template rebind< value_type>::other::reference reference; /// Iterator's const reference type. typedef typename _Alloc::template rebind< value_type>::other::const_reference const_reference; inline left_child_next_sibling_heap_node_point_const_iterator_(node_pointer p_nd) : m_p_nd(p_nd) { } /// Default constructor. inline left_child_next_sibling_heap_node_point_const_iterator_() : m_p_nd(0) { } /// Copy constructor. inline left_child_next_sibling_heap_node_point_const_iterator_(const PB_DS_CLASS_C_DEC& other) : m_p_nd(other.m_p_nd) { } /// Access. const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return &m_p_nd->m_value; } /// Access. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return m_p_nd->m_value; } /// Compares content to a different iterator object. bool operator==(const PB_DS_CLASS_C_DEC& other) const { return m_p_nd == other.m_p_nd; } /// Compares content (negatively) to a different iterator object. bool operator!=(const PB_DS_CLASS_C_DEC& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; }; #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]H:::A8/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/info_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return (m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return (s_node_allocator.max_size()); } PKgd1]^y8 F8/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/iterators_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { node_pointer p_nd = m_p_root; if (p_nd == 0) return (iterator(0)); while (p_nd->m_p_l_child != 0) p_nd = p_nd->m_p_l_child; return (iterator(p_nd)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { node_pointer p_nd = m_p_root; if (p_nd == 0) return (const_iterator(0)); while (p_nd->m_p_l_child != 0) p_nd = p_nd->m_p_l_child; return (const_iterator(p_nd)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return (iterator(0)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return (const_iterator(0)); } PKgd1]XjB8/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/debug_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_p_root == 0 || m_p_root->m_p_prev_or_parent == 0); if (m_p_root != 0) assert_node_consistent(m_p_root, Single_Link_Roots, __file, __line); assert_size(__file, __line); assert_iterators(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool single_link, const char* __file, int __line) const { if (p_nd == 0) return; assert_node_consistent(p_nd->m_p_l_child, false, __file, __line); assert_node_consistent(p_nd->m_p_next_sibling, single_link, __file, __line); if (single_link) PB_DS_DEBUG_VERIFY(p_nd->m_p_prev_or_parent == 0); else if (p_nd->m_p_next_sibling != 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd); if (p_nd->m_p_l_child == 0) return; node_const_pointer p_child = p_nd->m_p_l_child; while (p_child != 0) { node_const_pointer p_next_child = p_child->m_p_next_sibling; PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(p_nd->m_value, p_child->m_value)); p_child = p_next_child; } PB_DS_DEBUG_VERIFY(p_nd->m_p_l_child->m_p_prev_or_parent == p_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) == size()); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_size(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(size_from_node(m_p_root) == m_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size_under_node(node_const_pointer p_nd) { return 1 + size_from_node(p_nd->m_p_l_child); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size_from_node(node_const_pointer p_nd) { size_type ret = 0; while (p_nd != 0) { ret += 1 + size_from_node(p_nd->m_p_l_child); p_nd = p_nd->m_p_next_sibling; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: degree(node_const_pointer p_nd) { size_type ret = 0; node_const_pointer p_child = p_nd->m_p_l_child; while (p_child != 0) { ++ret; p_child = p_child->m_p_next_sibling; } return ret; } #endif PKgd1]jQQC8/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/insert_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val) { return get_new_node_for_insert(r_val, s_no_throw_copies_ind); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val, false_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); cond_dealtor_t cond(p_new_nd); new (const_cast( static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); cond.set_no_action(); ++m_size; return (p_new_nd); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val, true_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); new (const_cast( static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); ++m_size; return (p_new_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_child_of(node_pointer p_nd, node_pointer p_new_parent) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_new_parent != 0); p_nd->m_p_next_sibling = p_new_parent->m_p_l_child; if (p_new_parent->m_p_l_child != 0) p_new_parent->m_p_l_child->m_p_prev_or_parent = p_nd; p_nd->m_p_prev_or_parent = p_new_parent; p_new_parent->m_p_l_child = p_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: parent(node_pointer p_nd) { while (true) { node_pointer p_pot = p_nd->m_p_prev_or_parent; if (p_pot == 0 || p_pot->m_p_l_child == p_nd) return p_pot; p_nd = p_pot; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_with_parent(node_pointer p_nd, node_pointer p_parent) { if (p_parent == m_p_root) m_p_root = p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_parent != 0); _GLIBCXX_DEBUG_ASSERT(parent(p_nd) == p_parent); const bool nd_direct_child = p_parent->m_p_l_child == p_nd; const bool parent_root = p_parent->m_p_prev_or_parent == 0; const bool parent_direct_child = !parent_root&& p_parent->m_p_prev_or_parent->m_p_l_child == p_parent; std::swap(p_parent->m_p_prev_or_parent, p_nd->m_p_prev_or_parent); std::swap(p_parent->m_p_next_sibling, p_nd->m_p_next_sibling); std::swap(p_parent->m_p_l_child, p_nd->m_p_l_child); std::swap(p_parent->m_metadata, p_nd->m_metadata); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child != 0); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent != 0); if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; if (p_parent->m_p_next_sibling != 0) p_parent->m_p_next_sibling->m_p_prev_or_parent = p_parent; if (p_parent->m_p_l_child != 0) p_parent->m_p_l_child->m_p_prev_or_parent = p_parent; if (parent_direct_child) p_nd->m_p_prev_or_parent->m_p_l_child = p_nd; else if (!parent_root) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd; if (!nd_direct_child) { p_nd->m_p_l_child->m_p_prev_or_parent = p_nd; p_parent->m_p_prev_or_parent->m_p_next_sibling = p_parent; } else { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child == p_nd); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent == p_parent); p_nd->m_p_l_child = p_parent; p_parent->m_p_prev_or_parent = p_nd; } _GLIBCXX_DEBUG_ASSERT(parent(p_parent) == p_nd); } PKgd1]wwB8/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/erase_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { clear_imp(m_p_root); _GLIBCXX_DEBUG_ASSERT(m_size == 0); m_p_root = 0; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; p_nd->~node(); s_node_allocator.deallocate(p_nd, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { while (p_nd != 0) { clear_imp(p_nd->m_p_l_child); node_pointer p_next = p_nd->m_p_next_sibling; actual_erase_node(p_nd); p_nd = p_next; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: to_linked_list() { PB_DS_ASSERT_VALID((*this)) node_pointer p_cur = m_p_root; while (p_cur != 0) if (p_cur->m_p_l_child != 0) { node_pointer p_child_next = p_cur->m_p_l_child->m_p_next_sibling; p_cur->m_p_l_child->m_p_next_sibling = p_cur->m_p_next_sibling; p_cur->m_p_next_sibling = p_cur->m_p_l_child; p_cur->m_p_l_child = p_child_next; } else p_cur = p_cur->m_p_next_sibling; #ifdef _GLIBCXX_DEBUG node_const_pointer p_counter = m_p_root; size_type count = 0; while (p_counter != 0) { ++count; _GLIBCXX_DEBUG_ASSERT(p_counter->m_p_l_child == 0); p_counter = p_counter->m_p_next_sibling; } _GLIBCXX_DEBUG_ASSERT(count == m_size); #endif } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: prune(Pred pred) { node_pointer p_cur = m_p_root; m_p_root = 0; node_pointer p_out = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; if (pred(p_cur->m_value)) { p_cur->m_p_next_sibling = p_out; if (p_out != 0) p_out->m_p_prev_or_parent = p_cur; p_out = p_cur; } else { p_cur->m_p_next_sibling = m_p_root; if (m_p_root != 0) m_p_root->m_p_prev_or_parent = p_cur; m_p_root = p_cur; } p_cur = p_next; } return p_out; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: bubble_to_top(node_pointer p_nd) { node_pointer p_parent = parent(p_nd); while (p_parent != 0) { swap_with_parent(p_nd, p_parent); p_parent = parent(p_nd); } } PKgd1]XˆR8/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp * Contains an implementation class for a basic heap. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP /* * Based on CLRS. */ #include #include #include #include #include #include #ifdef PB_DS_LC_NS_HEAP_TRACE_ #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef _GLIBCXX_DEBUG #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap #else #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap #endif /// Base class for a basic heap. template #else > #endif class left_child_next_sibling_heap : public Cmp_Fn { protected: typedef typename _Alloc::template rebind< left_child_next_sibling_heap_node_ >::other node_allocator; typedef typename node_allocator::value_type node; typedef typename node_allocator::pointer node_pointer; typedef typename node_allocator::const_pointer node_const_pointer; typedef Node_Metadata node_metadata; typedef std::pair< node_pointer, node_pointer> node_pointer_pair; private: typedef cond_dealtor< node, _Alloc> cond_dealtor_t; enum { simple_value = is_simple::value }; typedef integral_constant no_throw_copies_t; typedef typename _Alloc::template rebind __rebind_v; public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Value_Type value_type; typedef typename __rebind_v::other::pointer pointer; typedef typename __rebind_v::other::const_pointer const_pointer; typedef typename __rebind_v::other::reference reference; typedef typename __rebind_v::other::const_reference const_reference; typedef left_child_next_sibling_heap_node_point_const_iterator_ point_const_iterator; typedef point_const_iterator point_iterator; typedef left_child_next_sibling_heap_const_iterator_ const_iterator; typedef const_iterator iterator; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; left_child_next_sibling_heap(); left_child_next_sibling_heap(const Cmp_Fn&); left_child_next_sibling_heap(const left_child_next_sibling_heap&); void swap(PB_DS_CLASS_C_DEC&); ~left_child_next_sibling_heap(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; void clear(); #ifdef PB_DS_LC_NS_HEAP_TRACE_ void trace() const; #endif protected: inline node_pointer get_new_node_for_insert(const_reference); inline static void make_child_of(node_pointer, node_pointer); void value_swap(left_child_next_sibling_heap&); inline static node_pointer parent(node_pointer); inline void swap_with_parent(node_pointer, node_pointer); void bubble_to_top(node_pointer); inline void actual_erase_node(node_pointer); void clear_imp(node_pointer); void to_linked_list(); template node_pointer prune(Pred); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_node_consistent(node_const_pointer, bool, const char*, int) const; static size_type size_under_node(node_const_pointer); static size_type degree(node_const_pointer); #endif #ifdef PB_DS_LC_NS_HEAP_TRACE_ static void trace_node(node_const_pointer, size_type); #endif private: #ifdef _GLIBCXX_DEBUG void assert_iterators(const char*, int) const; void assert_size(const char*, int) const; static size_type size_from_node(node_const_pointer); #endif node_pointer recursive_copy_node(node_const_pointer); inline node_pointer get_new_node_for_insert(const_reference, false_type); inline node_pointer get_new_node_for_insert(const_reference, true_type); #ifdef PB_DS_LC_NS_HEAP_TRACE_ template static void trace_node_metadata(node_const_pointer, type_to_type); static void trace_node_metadata(node_const_pointer, type_to_type); #endif static node_allocator s_node_allocator; static no_throw_copies_t s_no_throw_copies_ind; protected: node_pointer m_p_root; size_type m_size; }; #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]O{EE;8/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/entry_metadata_base.hpp * Contains an implementation for a list update map. */ #ifndef PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP #define PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP namespace __gnu_pbds { namespace detail { template struct lu_map_entry_metadata_base { Metadata m_update_metadata; }; template<> struct lu_map_entry_metadata_base { }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]U|58/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/trace_fn_imps.hpp * Contains implementations of lu_map_. */ #ifdef PB_DS_LU_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << m_p_l << std::endl << std::endl; const_entry_pointer p_l = m_p_l; while (p_l != 0) { std::cerr << PB_DS_V2F(p_l->m_value) << std::endl; p_l = p_l->m_p_next; } std::cerr << std::endl; } #endif PKgd1]^ F8/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/constructor_destructor_fn_imps.hpp */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC Eq_Fn PB_DS_CLASS_C_DEC::s_eq_fn; PB_DS_CLASS_T_DEC null_type PB_DS_CLASS_C_DEC::s_null_type; PB_DS_CLASS_T_DEC Update_Policy PB_DS_CLASS_C_DEC::s_update_policy; PB_DS_CLASS_T_DEC type_to_type< typename PB_DS_CLASS_C_DEC::update_metadata> PB_DS_CLASS_C_DEC::s_metadata_type_indicator; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME() : m_p_l(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME(It first_it, It last_it) : m_p_l(0) { copy_from_range(first_it, last_it); PB_DS_ASSERT_VALID((*this)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME(const PB_DS_CLASS_C_DEC& other) : m_p_l(0) { __try { for (const_iterator it = other.begin(); it != other.end(); ++it) { entry_pointer p_l = allocate_new_entry(*it, traits_base::m_no_throw_copies_indicator); p_l->m_p_next = m_p_l; m_p_l = p_l; } } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_l, other.m_p_l); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { entry_pointer p_l = m_p_l; while (p_l != 0) { entry_pointer p_next_l = p_l->m_p_next; actual_erase_entry(p_l); p_l = p_next_l; } m_p_l = 0; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_LU_NAME() { deallocate_all(); } PKgd1]dX((/8/ext/pb_ds/detail/list_update_map_/lu_map_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/lu_map_.hpp * Contains a list update map. */ #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #ifdef PB_DS_LU_MAP_TRACE_ #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_LU_NAME lu_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_LU_NAME lu_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_LU_NAME #define PB_DS_LU_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base::other::const_reference> #endif /// list-based (with updates) associative container. /// Skip to the lu, my darling. template class PB_DS_LU_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_LU_TRAITS_BASE { private: typedef PB_DS_LU_TRAITS_BASE traits_base; struct entry : public lu_map_entry_metadata_base { typename traits_base::value_type m_value; typename _Alloc::template rebind::other::pointer m_p_next; }; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename _Alloc::template rebind::other entry_pointer_allocator; typedef typename entry_pointer_allocator::pointer entry_pointer_array; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; #define PB_DS_GEN_POS entry_pointer #include #include #include #include #undef PB_DS_GEN_POS #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef cond_dealtor cond_dealtor_t; public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Eq_Fn eq_fn; typedef Update_Policy update_policy; typedef typename Update_Policy::metadata_type update_metadata; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; public: PB_DS_LU_NAME(); PB_DS_LU_NAME(const PB_DS_CLASS_C_DEC&); virtual ~PB_DS_LU_NAME(); template PB_DS_LU_NAME(It, It); void swap(PB_DS_CLASS_C_DEC&); inline size_type size() const; inline size_type max_size() const; inline bool empty() const; inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return insert(std::make_pair(r_key, mapped_type())).first->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline std::pair insert(const_reference); inline point_iterator find(key_const_reference r_key) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) entry_pointer p_e = find_imp(r_key); return point_iterator(p_e == 0 ? 0: &p_e->m_value); } inline point_const_iterator find(key_const_reference r_key) const { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) entry_pointer p_e = find_imp(r_key); return point_const_iterator(p_e == 0 ? 0: &p_e->m_value); } inline bool erase(key_const_reference); template inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; #endif #ifdef PB_DS_LU_MAP_TRACE_ void trace() const; #endif protected: template void copy_from_range(It, It); private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; inline entry_pointer allocate_new_entry(const_reference, false_type); inline entry_pointer allocate_new_entry(const_reference, true_type); template inline static void init_entry_metadata(entry_pointer, type_to_type); inline static void init_entry_metadata(entry_pointer, type_to_type); void deallocate_all(); void erase_next(entry_pointer); void actual_erase_entry(entry_pointer); void inc_it_state(const_pointer& r_p_value, entry_pointer& r_pos) const { r_pos = r_pos->m_p_next; r_p_value = (r_pos == 0) ? 0 : &r_pos->m_value; } template inline static bool apply_update(entry_pointer, type_to_type); inline static bool apply_update(entry_pointer, type_to_type); inline entry_pointer find_imp(key_const_reference) const; static entry_allocator s_entry_allocator; static Eq_Fn s_eq_fn; static Update_Policy s_update_policy; static type_to_type s_metadata_type_indicator; static null_type s_null_type; mutable entry_pointer m_p_l; }; #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_LU_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_LU_NAME } // namespace detail } // namespace __gnu_pbds PKgd1] 48/ext/pb_ds/detail/list_update_map_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/info_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return std::distance(begin(), end()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_p_l == 0); } PKgd1] C- - 48/ext/pb_ds/detail/list_update_map_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/find_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) const { if (m_p_l == 0) return 0; if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) { apply_update(m_p_l, s_metadata_type_indicator); PB_DS_CHECK_KEY_EXISTS(r_key) return m_p_l; } entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) { entry_pointer p_next = p_l->m_p_next; if (s_eq_fn(r_key, PB_DS_V2F(p_next->m_value))) { if (apply_update(p_next, s_metadata_type_indicator)) { p_l->m_p_next = p_next->m_p_next; p_next->m_p_next = m_p_l; m_p_l = p_next; return m_p_l; } return p_next; } else p_l = p_next; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return 0; } PB_DS_CLASS_T_DEC template inline bool PB_DS_CLASS_C_DEC:: apply_update(entry_pointer p_l, type_to_type) { return s_update_policy(p_l->m_update_metadata); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: apply_update(entry_pointer, type_to_type) { return s_update_policy(s_null_type); } PKgd1]Ԯ_ 98/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/iterators_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { if (m_p_l == 0) { _GLIBCXX_DEBUG_ASSERT(empty()); return end(); } return iterator(&m_p_l->m_value, m_p_l, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { if (m_p_l == 0) { _GLIBCXX_DEBUG_ASSERT(empty()); return end(); } return iterator(&m_p_l->m_value, m_p_l, const_cast(this)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(0, 0, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(0, 0, const_cast(this)); } PKgd1]K//58/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/debug_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { size_type calc_size = 0; for (const_iterator it = begin(); it != end(); ++it) { debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); ++calc_size; } debug_base::check_size(calc_size, __file, __line); } #endif PKgd1]56 68/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/insert_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline std::pair< typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_l = find_imp(PB_DS_V2F(r_val)); if (p_l != 0) { PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val)) return std::make_pair(point_iterator(&p_l->m_value), false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val)) p_l = allocate_new_entry(r_val, traits_base::m_no_throw_copies_indicator); p_l->m_p_next = m_p_l; m_p_l = p_l; PB_DS_ASSERT_VALID((*this)) return std::make_pair(point_iterator(&p_l->m_value), true); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: allocate_new_entry(const_reference r_val, false_type) { entry_pointer p_l = s_entry_allocator.allocate(1); cond_dealtor_t cond(p_l); new (const_cast(static_cast(&p_l->m_value))) value_type(r_val); cond.set_no_action(); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) init_entry_metadata(p_l, s_metadata_type_indicator); return p_l; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: allocate_new_entry(const_reference r_val, true_type) { entry_pointer p_l = s_entry_allocator.allocate(1); new (&p_l->m_value) value_type(r_val); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) init_entry_metadata(p_l, s_metadata_type_indicator); return p_l; } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: init_entry_metadata(entry_pointer p_l, type_to_type) { new (&p_l->m_update_metadata) Metadata(s_update_policy()); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: init_entry_metadata(entry_pointer, type_to_type) { } PKgd1] 58/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/erase_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) if (m_p_l == 0) return false; if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) { entry_pointer p_next = m_p_l->m_p_next; actual_erase_entry(m_p_l); m_p_l = p_next; return true; } entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) if (s_eq_fn(r_key, PB_DS_V2F(p_l->m_p_next->m_value))) { erase_next(p_l); return true; } else p_l = p_l->m_p_next; return false; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { deallocate_all(); } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; while (m_p_l != 0 && pred(m_p_l->m_value)) { entry_pointer p_next = m_p_l->m_p_next; ++num_ersd; actual_erase_entry(m_p_l); m_p_l = p_next; } if (m_p_l == 0) return num_ersd; entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) { if (pred(p_l->m_p_next->m_value)) { ++num_ersd; erase_next(p_l); } else p_l = p_l->m_p_next; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_next(entry_pointer p_l) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_l->m_p_next != 0); entry_pointer p_next_l = p_l->m_p_next->m_p_next; actual_erase_entry(p_l->m_p_next); p_l->m_p_next = p_next_l; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: actual_erase_entry(entry_pointer p_l) { _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->m_value));) p_l->~entry(); s_entry_allocator.deallocate(p_l, 1); } PKgd1]R  88/ext/pb_ds/detail/unordered_iterator/const_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file unordered_iterator/const_iterator.hpp * Contains an iterator class used for const ranging over the elements of the * table. */ /// Const range-type iterator. class const_iterator_ : public point_const_iterator_ { public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. const_iterator_() : m_p_tbl(0) { } /// Increments. const_iterator_& operator++() { m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); return *this; } /// Increments. const_iterator_ operator++(int) { const_iterator_ ret =* this; m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); return ret; } protected: typedef point_const_iterator_ base_type; /** * Constructor used by the table to initiate the generalized * pointer and position (e.g., this is called from within a find() * of a table. * */ const_iterator_(const_pointer_ p_value, PB_DS_GEN_POS pos, const PB_DS_CLASS_C_DEC* p_tbl) : point_const_iterator_(p_value), m_p_tbl(p_tbl), m_pos(pos) { } /** * Pointer to the table object which created the iterator (used for * incrementing its position. * */ const PB_DS_CLASS_C_DEC* m_p_tbl; PB_DS_GEN_POS m_pos; friend class PB_DS_CLASS_C_DEC; }; PKgd1]0z 88/ext/pb_ds/detail/unordered_iterator/point_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file point_iterator.hpp * Contains an iterator class returned by the tables' find and insert * methods. */ /// Find type iterator. class point_iterator_ { public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. inline point_iterator_() : m_p_value(0) { } /// Copy constructor. inline point_iterator_(const point_iterator_& other) : m_p_value(other.m_p_value) { } /// Access. pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return (m_p_value); } /// Access. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return (*m_p_value); } /// Compares content to a different iterator object. bool operator==(const point_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_const_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator!=(const point_iterator_& other) const { return m_p_value != other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_const_iterator_& other) const { return m_p_value != other.m_p_value; } inline point_iterator_(pointer p_value) : m_p_value(p_value) { } protected: friend class point_const_iterator_; friend class PB_DS_CLASS_C_DEC; protected: pointer m_p_value; }; PKgd1]|28/ext/pb_ds/detail/unordered_iterator/iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file iterator.hpp * Contains an iterator_ class used for ranging over the elements of the * table. */ /// Range-type iterator. class iterator_ : public const_iterator_ { public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. inline iterator_() : const_iterator_(0, PB_DS_GEN_POS(), 0) { } /// Conversion to a point-type iterator. inline operator point_iterator_() { return point_iterator_(const_cast(const_iterator_::m_p_value)); } /// Conversion to a point-type iterator. inline operator const point_iterator_() const { return point_iterator_(const_cast(const_iterator_::m_p_value)); } /// Access. pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != 0); return (const_cast(base_type::m_p_value)); } /// Access. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != 0); return (const_cast(*base_type::m_p_value)); } /// Increments. iterator_& operator++() { base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); return *this; } /// Increments. iterator_ operator++(int) { iterator_ ret =* this; base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); return ret; } protected: typedef const_iterator_ base_type; /** * Constructor used by the table to initiate the generalized * pointer and position (e.g., this is called from within a find() * of a table. * */ inline iterator_(pointer p_value, PB_DS_GEN_POS pos, PB_DS_CLASS_C_DEC* p_tbl) : const_iterator_(p_value, pos, p_tbl) { } friend class PB_DS_CLASS_C_DEC; }; PKgd1]#a>8/ext/pb_ds/detail/unordered_iterator/point_const_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file unordered_iterator/point_const_iterator.hpp * Contains an iterator class returned by the tables' const find and insert * methods. */ class point_iterator_; /// Const point-type iterator. class point_const_iterator_ { public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; inline point_const_iterator_(const_pointer p_value) : m_p_value(p_value) { } /// Default constructor. inline point_const_iterator_() : m_p_value(0) { } /// Copy constructor. inline point_const_iterator_(const point_const_iterator_& other) : m_p_value(other.m_p_value) { } /// Copy constructor. inline point_const_iterator_(const point_iterator_& other) : m_p_value(other.m_p_value) { } /// Access. const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return m_p_value; } /// Access. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return *m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_const_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_iterator_& other) const { return m_p_value != other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_const_iterator_& other) const { return m_p_value != other.m_p_value; } protected: const_pointer m_p_value; friend class point_iterator_; friend class PB_DS_CLASS_C_DEC; }; PKgd1](lq/8/ext/pb_ds/detail/pat_trie_/update_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/update_fn_imps.hpp * Contains an implementation class for pat_trie_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer, null_node_update_pointer) { } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_*) { Node_Update_::operator()(node_iterator(p_nd, this), node_const_iterator(0, this)); } PKgd1]ա/8/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/rotate_fn_imps.hpp * Contains imps for rotating nodes. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_left(node_pointer p_x) { node_pointer p_y = p_x->m_p_right; p_x->m_p_right = p_y->m_p_left; if (p_y->m_p_left != 0) p_y->m_p_left->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_left) p_x->m_p_parent->m_p_left = p_y; else p_x->m_p_parent->m_p_right = p_y; p_y->m_p_left = p_x; p_x->m_p_parent = p_y; _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) apply_update(p_x, (Node_Update*)this); apply_update(p_x->m_p_parent, (Node_Update*)this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_right(node_pointer p_x) { node_pointer p_y = p_x->m_p_left; p_x->m_p_left = p_y->m_p_right; if (p_y->m_p_right != 0) p_y->m_p_right->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_right) p_x->m_p_parent->m_p_right = p_y; else p_x->m_p_parent->m_p_left = p_y; p_y->m_p_right = p_x; p_x->m_p_parent = p_y; _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) apply_update(p_x, (Node_Update*)this); apply_update(p_x->m_p_parent, (Node_Update*)this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_parent(node_pointer p_nd) { node_pointer p_parent = p_nd->m_p_parent; if (p_nd == p_parent->m_p_left) rotate_right(p_parent); else rotate_left(p_parent); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer /*p_nd*/, __gnu_pbds::null_node_update* /*p_update*/) { } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_* p_update) { p_update->operator()(& PB_DS_V2F(p_nd->m_value),(p_nd->m_p_left == 0) ? 0 : & PB_DS_V2F(p_nd->m_p_left->m_value),(p_nd->m_p_right == 0) ? 0 : & PB_DS_V2F(p_nd->m_p_right->m_value)); } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer p_nd, Node_Update_* p_update) { while (p_nd != m_p_head) { apply_update(p_nd, p_update); p_nd = p_nd->m_p_parent; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer /*p_nd*/, __gnu_pbds::null_node_update* /*p_update*/) { } PKgd1]I% h h 08/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/r_erase_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_z->m_value))); p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~Node(); s_node_allocator.deallocate(p_nd, 1); } PKgd1]:8848/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/insert_join_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) branch_bag bag; if (!join_prep(other, bag)) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, other.m_p_head->m_p_parent, 0, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; m_size += other.m_size; other.initialize(); PB_DS_ASSERT_VALID(other) m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: join_prep(PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return false; if (m_size == 0) { value_swap(other); return false; } const bool greater = synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(m_p_head->m_p_max)->value()), PB_DS_V2F(static_cast(other.m_p_head->m_p_min)->value())); const bool lesser = synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(other.m_p_head->m_p_max)->value()), PB_DS_V2F(static_cast(m_p_head->m_p_min)->value())); if (!greater && !lesser) __throw_join_error(); rec_join_prep(m_p_head->m_p_parent, other.m_p_head->m_p_parent, r_bag); _GLIBCXX_DEBUG_ONLY(debug_base::join(other, false);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(node_const_pointer p_l, node_const_pointer p_r, branch_bag& r_bag) { if (p_l->m_type == leaf_node) { if (p_r->m_type == leaf_node) { rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node); if (p_r->m_type == leaf_node) { rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(leaf_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(leaf_const_pointer /*p_l*/, inode_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(inode_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(inode_const_pointer p_l, inode_const_pointer p_r, branch_bag& r_bag) { if (p_l->get_e_ind() == p_r->get_e_ind() && synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), p_r->pref_b_it(), p_r->pref_e_it())) { for (typename inode::const_iterator it = p_r->begin(); it != p_r->end(); ++ it) { node_const_pointer p_l_join_child = p_l->get_join_child(*it, this); if (p_l_join_child != 0) rec_join_prep(p_l_join_child, * it, r_bag); } return; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this); if (p_r_join_child != 0) rec_join_prep(p_r_join_child, p_l, r_bag); return; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this); if (p_r_join_child != 0) rec_join_prep(p_r_join_child, p_l, r_bag); return; } r_bag.add_branch(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_r != 0); if (p_l == 0) { apply_update(p_r, (node_update*)this); return (p_r); } if (p_l->m_type == leaf_node) { if (p_r->m_type == leaf_node) { node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), checked_ind, r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node); if (p_r->m_type == leaf_node) { node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), checked_ind, r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(leaf_pointer p_l, leaf_pointer p_r, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_r != 0); if (p_l == 0) return (p_r); node_pointer p_ret = insert_branch(p_l, p_r, r_bag); _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == 2); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(leaf_pointer p_l, inode_pointer p_r, size_type checked_ind, branch_bag& r_bag) { #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif _GLIBCXX_DEBUG_ASSERT(p_r != 0); node_pointer p_ret = rec_join(p_r, p_l, checked_ind, r_bag); _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(inode_pointer p_l, leaf_pointer p_r, size_type checked_ind, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_r != 0); #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif if (!p_l->should_be_mine(pref_begin(p_r), pref_end(p_r), checked_ind, this)) { node_pointer p_ret = insert_branch(p_l, p_r, r_bag); PB_DS_ASSERT_NODE_VALID(p_ret) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } node_pointer p_pot_child = p_l->add_child(p_r, pref_begin(p_r), pref_end(p_r), this); if (p_pot_child != p_r) { node_pointer p_new_child = rec_join(p_pot_child, p_r, p_l->get_e_ind(), r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } PB_DS_ASSERT_NODE_VALID(p_l) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs); return p_l; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(inode_pointer p_l, inode_pointer p_r, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_r != 0); #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif if (p_l->get_e_ind() == p_r->get_e_ind() && synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), p_r->pref_b_it(), p_r->pref_e_it())) { for (typename inode::iterator it = p_r->begin(); it != p_r->end(); ++ it) { node_pointer p_new_child = rec_join(p_l->get_join_child(*it, this), * it, 0, r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } p_r->~inode(); s_inode_allocator.deallocate(p_r, 1); PB_DS_ASSERT_NODE_VALID(p_l) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs); return p_l; } if (p_l->get_e_ind() < p_r->get_e_ind() && p_l->should_be_mine(p_r->pref_b_it(), p_r->pref_e_it(), 0, this)) { node_pointer p_new_child = rec_join(p_l->get_join_child(p_r, this), p_r, 0, r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); PB_DS_ASSERT_NODE_VALID(p_l) return p_l; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_pointer p_new_child = rec_join(p_r->get_join_child(p_l, this), p_l, 0, r_bag); p_r->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); PB_DS_ASSERT_NODE_VALID(p_r) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_r) == lhs_leafs + rhs_leafs); return p_r; } node_pointer p_ret = insert_branch(p_l, p_r, r_bag); PB_DS_ASSERT_NODE_VALID(p_ret) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert(const_reference r_val) { node_pointer p_lf = find_imp(PB_DS_V2F(r_val)); if (p_lf != 0 && p_lf->m_type == leaf_node && synth_access_traits::equal_keys(PB_DS_V2F(static_cast(p_lf)->value()), PB_DS_V2F(r_val))) { PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val)) PB_DS_ASSERT_VALID((*this)) return std::make_pair(iterator(p_lf), false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val)) leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); cond_dealtor cond(p_new_lf); new (p_new_lf) leaf(r_val); apply_update(p_new_lf, (node_update*)this); cond.set_call_destructor(); branch_bag bag; bag.add_branch(); m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; cond.set_no_action_dtor(); ++m_size; update_min_max_for_inserted_leaf(p_new_lf); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) PB_DS_ASSERT_VALID((*this)) return std::make_pair(point_iterator(p_new_lf), true); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: keys_diff_ind(typename access_traits::const_iterator b_l, typename access_traits::const_iterator e_l, typename access_traits::const_iterator b_r, typename access_traits::const_iterator e_r) { size_type diff_pos = 0; while (b_l != e_l) { if (b_r == e_r) return (diff_pos); if (access_traits::e_pos(*b_l) != access_traits::e_pos(*b_r)) return (diff_pos); ++b_l; ++b_r; ++diff_pos; } _GLIBCXX_DEBUG_ASSERT(b_r != e_r); return diff_pos; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::inode_pointer PB_DS_CLASS_C_DEC:: insert_branch(node_pointer p_l, node_pointer p_r, branch_bag& r_bag) { typename synth_access_traits::const_iterator left_b_it = pref_begin(p_l); typename synth_access_traits::const_iterator left_e_it = pref_end(p_l); typename synth_access_traits::const_iterator right_b_it = pref_begin(p_r); typename synth_access_traits::const_iterator right_e_it = pref_end(p_r); const size_type diff_ind = keys_diff_ind(left_b_it, left_e_it, right_b_it, right_e_it); inode_pointer p_new_nd = r_bag.get_branch(); new (p_new_nd) inode(diff_ind, left_b_it); p_new_nd->add_child(p_l, left_b_it, left_e_it, this); p_new_nd->add_child(p_r, right_b_it, right_e_it, this); p_l->m_p_parent = p_new_nd; p_r->m_p_parent = p_new_nd; PB_DS_ASSERT_NODE_VALID(p_new_nd) return (p_new_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_min_max_for_inserted_leaf(leaf_pointer p_new_lf) { if (m_p_head->m_p_min == m_p_head || synth_access_traits::cmp_keys(PB_DS_V2F(p_new_lf->value()), PB_DS_V2F(static_cast(m_p_head->m_p_min)->value()))) m_p_head->m_p_min = p_new_lf; if (m_p_head->m_p_max == m_p_head || synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(m_p_head->m_p_max)->value()), PB_DS_V2F(p_new_lf->value()))) m_p_head->m_p_max = p_new_lf; } PKgd1]'--.8/ext/pb_ds/detail/pat_trie_/split_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/split_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) branch_bag bag; leaf_pointer p_split_lf = split_prep(r_key, other, bag); if (p_split_lf == 0) { _GLIBCXX_DEBUG_ASSERT(bag.empty()); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } _GLIBCXX_DEBUG_ASSERT(!bag.empty()); other.clear(); m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent, pref_begin(p_split_lf), pref_end(p_split_lf), other, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; head_pointer __ohead = other.m_p_head; __ohead->m_p_max = m_p_head->m_p_max; m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); __ohead->m_p_min = other.leftmost_descendant(__ohead->m_p_parent); other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(), other.PB_DS_CLASS_C_DEC::end()); m_size -= other.m_size; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(r_bag.empty()); if (m_size == 0) { other.clear(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } if (synth_access_traits::cmp_keys(r_key, PB_DS_V2F(static_cast(m_p_head->m_p_min)->value()))) { other.clear(); value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } if (!synth_access_traits::cmp_keys(r_key, PB_DS_V2F(static_cast(m_p_head->m_p_max)->value()))) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } iterator it = lower_bound(r_key); if (!synth_access_traits::equal_keys(PB_DS_V2F(*it), r_key)) --it; node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); leaf_pointer p_ret_l = static_cast(p_nd); while (p_nd->m_type != head_node) { r_bag.add_branch(); p_nd = p_nd->m_p_parent; } _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(synth_access_traits&)(*this), other);) return p_ret_l; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_split(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { if (p_nd->m_type == leaf_node) { _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == 0); return p_nd; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); inode_pointer p_ind = static_cast(p_nd); node_pointer pfirst = p_ind->get_child_node(b_it, e_it, this); node_pointer p_child_ret = rec_split(pfirst, b_it, e_it, other, r_bag); PB_DS_ASSERT_NODE_VALID(p_child_ret) p_ind->replace_child(p_child_ret, b_it, e_it, this); apply_update(p_ind, (node_update*)this); inode_iterator child_it = p_ind->get_child_it(b_it, e_it, this); const size_type lhs_dist = std::distance(p_ind->begin(), child_it); const size_type lhs_num_children = lhs_dist + 1; _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0); const size_type rhs_dist = std::distance(p_ind->begin(), p_ind->end()); size_type rhs_num_children = rhs_dist - lhs_num_children; if (rhs_num_children == 0) { apply_update(p_ind, (node_update*)this); return p_ind; } other.split_insert_branch(p_ind->get_e_ind(), b_it, child_it, rhs_num_children, r_bag); child_it = p_ind->get_child_it(b_it, e_it, this); while (rhs_num_children != 0) { ++child_it; p_ind->remove_child(child_it); --rhs_num_children; } apply_update(p_ind, (node_update*)this); const size_type int_dist = std::distance(p_ind->begin(), p_ind->end()); _GLIBCXX_DEBUG_ASSERT(int_dist >= 1); if (int_dist > 1) { p_ind->update_prefixes(this); PB_DS_ASSERT_NODE_VALID(p_ind) apply_update(p_ind, (node_update*)this); return p_ind; } node_pointer p_ret = *p_ind->begin(); p_ind->~inode(); s_inode_allocator.deallocate(p_ind, 1); apply_update(p_ret, (node_update*)this); return p_ret; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_insert_branch(size_type e_ind, a_const_iterator b_it, inode_iterator child_b_it, size_type num_children, branch_bag& r_bag) { #ifdef _GLIBCXX_DEBUG if (m_p_head->m_p_parent != 0) PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) #endif const size_type start = m_p_head->m_p_parent == 0 ? 0 : 1; const size_type total_num_children = start + num_children; if (total_num_children == 0) { _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0); return; } if (total_num_children == 1) { if (m_p_head->m_p_parent != 0) { PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) return; } _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0); ++child_b_it; m_p_head->m_p_parent = *child_b_it; m_p_head->m_p_parent->m_p_parent = m_p_head; apply_update(m_p_head->m_p_parent, (node_update*)this); PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) return; } _GLIBCXX_DEBUG_ASSERT(total_num_children > 1); inode_pointer p_new_root = r_bag.get_branch(); new (p_new_root) inode(e_ind, b_it); size_type num_inserted = 0; while (num_inserted++ < num_children) { ++child_b_it; PB_DS_ASSERT_NODE_VALID((*child_b_it)) p_new_root->add_child(*child_b_it, pref_begin(*child_b_it), pref_end(*child_b_it), this); } if (m_p_head->m_p_parent != 0) p_new_root->add_child(m_p_head->m_p_parent, pref_begin(m_p_head->m_p_parent), pref_end(m_p_head->m_p_parent), this); m_p_head->m_p_parent = p_new_root; p_new_root->m_p_parent = m_p_head; apply_update(m_p_head->m_p_parent, (node_update*)this); PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) } PKgd1]11I I .8/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/trace_fn_imps.hpp * Contains an implementation class for pat_trie_. */ #ifdef PB_DS_PAT_TRIE_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; if (m_p_head->m_p_parent == 0) return; trace_node(m_p_head->m_p_parent, 0); std::cerr << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_pointer p_nd, size_type level) { for (size_type i = 0; i < level; ++i) std::cerr << ' '; std::cerr << p_nd << " "; std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i "); trace_node_metadata(p_nd, type_to_type()); typename access_traits::const_iterator el_it = pref_begin(p_nd); while (el_it != pref_end(p_nd)) { std::cerr <<* el_it; ++el_it; } if (p_nd->m_type == pat_trie_leaf_node_type) { std::cerr << std::endl; return; } inode_const_pointer p_internal = static_cast(p_nd); std::cerr << " " << static_cast(p_internal->get_e_ind()) << std::endl; const size_type num_children = std::distance(p_internal->begin(), p_internal->end()); for (size_type child_i = 0; child_i < num_children; ++child_i) { typename inode::const_iterator child_it = p_internal->begin(); std::advance(child_it, num_children - child_i - 1); trace_node(*child_it, level + 1); } } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer p_nd, type_to_type) { std::cerr << "(" << static_cast(p_nd->get_metadata()) << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer, type_to_type) { } #endif PKgd1]9ݧ68/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/policy_access_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::access_traits& PB_DS_CLASS_C_DEC:: get_access_traits() { return *this; } PB_DS_CLASS_T_DEC const typename PB_DS_CLASS_C_DEC::access_traits& PB_DS_CLASS_C_DEC:: get_access_traits() const { return *this; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_update& PB_DS_CLASS_C_DEC:: get_node_update() { return *this; } PB_DS_CLASS_T_DEC const typename PB_DS_CLASS_C_DEC::node_update& PB_DS_CLASS_C_DEC:: get_node_update() const { return *this; } PKgd1]]hPP@8/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hppnu[ // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/constructors_destructor_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::head_allocator PB_DS_CLASS_C_DEC::s_head_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::inode_allocator PB_DS_CLASS_C_DEC::s_inode_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_allocator PB_DS_CLASS_C_DEC::s_leaf_allocator; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME() : m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME(const access_traits& r_access_traits) : synth_access_traits(r_access_traits), m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif synth_access_traits(other), node_update(other), m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); m_size = other.m_size; PB_DS_ASSERT_VALID(other) if (other.m_p_head->m_p_parent == 0) { PB_DS_ASSERT_VALID((*this)) return; } __try { m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); } __catch(...) { s_head_allocator.deallocate(m_p_head, 1); __throw_exception_again; } m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_parent->m_p_parent = m_p_head; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap((access_traits& )(*this), (access_traits& )other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_head, other.m_p_head); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_PAT_TRIE_NAME() { clear(); s_head_allocator.deallocate(m_p_head, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { new (m_p_head) head(); m_p_head->m_p_parent = 0; m_p_head->m_p_min = m_p_head; m_p_head->m_p_max = m_p_head; m_size = 0; } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(node_const_pointer p_ncp) { _GLIBCXX_DEBUG_ASSERT(p_ncp != 0); if (p_ncp->m_type == leaf_node) { leaf_const_pointer p_other_lf = static_cast(p_ncp); leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); cond_dealtor cond(p_new_lf); new (p_new_lf) leaf(p_other_lf->value()); apply_update(p_new_lf, (node_update*)this); cond.set_no_action_dtor(); return (p_new_lf); } _GLIBCXX_DEBUG_ASSERT(p_ncp->m_type == i_node); node_pointer a_p_children[inode::arr_size]; size_type child_i = 0; inode_const_pointer p_icp = static_cast(p_ncp); typename inode::const_iterator child_it = p_icp->begin(); inode_pointer p_ret; __try { while (child_it != p_icp->end()) { a_p_children[child_i] = recursive_copy_node(*(child_it)); child_i++; child_it++; } p_ret = s_inode_allocator.allocate(1); } __catch(...) { while (child_i-- > 0) clear_imp(a_p_children[child_i]); __throw_exception_again; } new (p_ret) inode(p_icp->get_e_ind(), pref_begin(a_p_children[0])); --child_i; _GLIBCXX_DEBUG_ASSERT(child_i >= 1); do p_ret->add_child(a_p_children[child_i], pref_begin(a_p_children[child_i]), pref_end(a_p_children[child_i]), this); while (child_i-- > 0); apply_update(p_ret, (node_update*)this); return p_ret; } PKgd1]`-8/ext/pb_ds/detail/pat_trie_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/info_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_inode_allocator.max_size(); } PKgd1]<-8/ext/pb_ds/detail/pat_trie_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/find_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = find_imp(r_key); if (p_nd == 0 || p_nd->m_type != leaf_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_EXISTS(r_key) return iterator(p_nd); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) node_const_pointer p_nd = const_cast(this)->find_imp(r_key); if (p_nd == 0 || p_nd->m_type != leaf_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_EXISTS(r_key) return const_iterator(const_cast(p_nd)); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) { if (empty()) return 0; typename synth_access_traits::const_iterator b_it = synth_access_traits::begin(r_key); typename synth_access_traits::const_iterator e_it = synth_access_traits::end(r_key); node_pointer p_nd = m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); while (p_nd->m_type != leaf_node) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); node_pointer p_next_nd = static_cast(p_nd)->get_child_node(b_it, e_it, this); if (p_next_nd == 0) return p_nd; p_nd = p_next_nd; } return p_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: lower_bound_imp(key_const_reference r_key) { if (empty()) return (m_p_head); node_pointer p_nd = m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); typename PB_DS_CLASS_C_DEC::a_const_iterator b_it = synth_access_traits::begin(r_key); typename PB_DS_CLASS_C_DEC::a_const_iterator e_it = synth_access_traits::end(r_key); size_type checked_ind = 0; while (true) { if (p_nd->m_type == leaf_node) { if (!synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(p_nd)->value()), r_key)) return p_nd; iterator it(p_nd); ++it; return it.m_p_nd; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); const size_type new_checked_ind = static_cast(p_nd)->get_e_ind(); p_nd = static_cast(p_nd)->get_lower_bound_child_node( b_it, e_it, checked_ind, this); checked_ind = new_checked_ind; } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) { return point_iterator(lower_bound_imp(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) const { return point_const_iterator(const_cast(this)->lower_bound_imp(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) { point_iterator l_bound_it = lower_bound(r_key); _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), r_key)); if (l_bound_it == end() || synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) return l_bound_it; return ++l_bound_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) const { point_const_iterator l_bound_it = lower_bound(r_key); _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), r_key)); if (l_bound_it == end() || synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) return l_bound_it; return ++l_bound_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_begin(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return (synth_access_traits::begin(PB_DS_V2F(static_cast(p_nd)->value()))); _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); return static_cast(p_nd)->pref_b_it(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_end(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return (synth_access_traits::end(PB_DS_V2F(static_cast(p_nd)->value()))); _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); return static_cast(p_nd)->pref_e_it(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->leftmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->leftmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->rightmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->rightmost_descendant(); } PKgd1]0? 28/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/iterators_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_p_head->m_p_min); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return const_iterator(m_p_head->m_p_min); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() const { if (empty()) return rend(); return --end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() { if (empty()) return rend(); return --end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rend() { return reverse_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rend() const { return const_reverse_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return node_const_iterator(m_p_head->m_p_parent, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return node_iterator(m_p_head->m_p_parent, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return node_const_iterator(0, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return node_iterator(0, this); } PKgd1]ļ.8/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/debug_fn_imps.hpp * Contains an implementation class for pat_trie_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { if (m_p_head->m_p_parent != 0) m_p_head->m_p_parent->assert_valid(this, __file, __line); assert_iterators(__file, __line); assert_reverse_iterators(__file, __line); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_min == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_max == m_p_head); PB_DS_DEBUG_VERIFY(empty()); return; } PB_DS_DEBUG_VERIFY(m_p_head->m_p_min->m_type == leaf_node); PB_DS_DEBUG_VERIFY(m_p_head->m_p_max->m_type == leaf_node); PB_DS_DEBUG_VERIFY(!empty()); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { size_type calc_size = 0; for (const_iterator it = begin(); it != end(); ++it) { ++calc_size; debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)) == it); PB_DS_DEBUG_VERIFY(--upper_bound(PB_DS_V2F(*it)) == it); } PB_DS_DEBUG_VERIFY(calc_size == m_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_reverse_iterators(const char* __file, int __line) const { size_type calc_size = 0; for (const_reverse_iterator it = rbegin(); it != rend(); ++it) { ++calc_size; node_const_pointer p_nd = const_cast(this)->find_imp(PB_DS_V2F(*it)); PB_DS_DEBUG_VERIFY(p_nd == it.m_p_nd); } PB_DS_DEBUG_VERIFY(calc_size == m_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: recursive_count_leafs(node_const_pointer p_nd, const char* __file, int __line) { if (p_nd == 0) return (0); if (p_nd->m_type == leaf_node) return (1); PB_DS_DEBUG_VERIFY(p_nd->m_type == i_node); size_type ret = 0; for (typename inode::const_iterator it = static_cast(p_nd)->begin(); it != static_cast(p_nd)->end(); ++it) ret += recursive_count_leafs(*it, __file, __line); return ret; } #endif PKgd1]lZz  .8/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/erase_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { node_pointer p_nd = find_imp(r_key); if (p_nd == 0 || p_nd->m_type == i_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); if (!synth_access_traits::equal_keys(PB_DS_V2F(reinterpret_cast(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } PB_DS_CHECK_KEY_EXISTS(r_key) erase_leaf(static_cast(p_nd)); PB_DS_ASSERT_VALID((*this)) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_fixup(inode_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) >= 1); if (std::distance(p_nd->begin(), p_nd->end()) == 1) { node_pointer p_parent = p_nd->m_p_parent; if (p_parent == m_p_head) m_p_head->m_p_parent = *p_nd->begin(); else { _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node); node_pointer p_new_child = *p_nd->begin(); typedef inode_pointer inode_ptr; inode_ptr p_internal = static_cast(p_parent); p_internal->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } (*p_nd->begin())->m_p_parent = p_nd->m_p_parent; p_nd->~inode(); s_inode_allocator.deallocate(p_nd, 1); if (p_parent == m_p_head) return; _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node); p_nd = static_cast(p_parent); } while (true) { _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) > 1); p_nd->update_prefixes(this); apply_update(p_nd, (node_update*)this); PB_DS_ASSERT_NODE_VALID(p_nd) if (p_nd->m_p_parent->m_type == head_node) return; _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent->m_type == i_node); p_nd = static_cast(p_nd->m_p_parent); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_leaf(leaf_pointer p_l) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->value()))); p_l->~leaf(); s_leaf_allocator.deallocate(p_l, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { if (!empty()) { clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_ASSERT_VALID((*this)) } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd->m_type == i_node) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); for (typename inode::iterator it = static_cast(p_nd)->begin(); it != static_cast(p_nd)->end(); ++it) { node_pointer p_child =* it; clear_imp(p_child); } s_inode_allocator.deallocate(static_cast(p_nd), 1); return; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); static_cast(p_nd)->~leaf(); s_leaf_allocator.deallocate(static_cast(p_nd), 1); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: erase(const_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return it; const_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return it; iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: erase(const_reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == m_p_head) return it; const_reverse_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == m_p_head) return it; reverse_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { size_type num_ersd = 0; PB_DS_ASSERT_VALID((*this)) iterator it = begin(); while (it != end()) { PB_DS_ASSERT_VALID((*this)) if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_leaf(leaf_pointer p_l) { update_min_max_for_erased_leaf(p_l); if (p_l->m_p_parent->m_type == head_node) { _GLIBCXX_DEBUG_ASSERT(size() == 1); clear(); return; } _GLIBCXX_DEBUG_ASSERT(size() > 1); _GLIBCXX_DEBUG_ASSERT(p_l->m_p_parent->m_type == i_node); inode_pointer p_parent = static_cast(p_l->m_p_parent); p_parent->remove_child(p_l); erase_fixup(p_parent); actual_erase_leaf(p_l); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_leaf(leaf_pointer p_l) { if (m_size == 1) { m_p_head->m_p_min = m_p_head; m_p_head->m_p_max = m_p_head; return; } if (p_l == static_cast(m_p_head->m_p_min)) { iterator it(p_l); ++it; m_p_head->m_p_min = it.m_p_nd; return; } if (p_l == static_cast(m_p_head->m_p_max)) { iterator it(p_l); --it; m_p_head->m_p_max = it.m_p_nd; } } PKgd1]'j>>48/ext/pb_ds/detail/pat_trie_/synth_access_traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/synth_access_traits.hpp * Contains an implementation class for a patricia tree. */ #ifndef PB_DS_SYNTH_E_ACCESS_TRAITS_HPP #define PB_DS_SYNTH_E_ACCESS_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { #define PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC \ template #define PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC \ synth_access_traits /// Synthetic element access traits. template struct synth_access_traits : public _ATraits { typedef _ATraits base_type; typedef typename base_type::const_iterator const_iterator; typedef Type_Traits type_traits; typedef typename type_traits::const_reference const_reference; typedef typename type_traits::key_const_reference key_const_reference; synth_access_traits(); synth_access_traits(const base_type&); inline bool equal_prefixes(const_iterator, const_iterator, const_iterator, const_iterator, bool compare_after = true) const; bool equal_keys(key_const_reference, key_const_reference) const; bool cmp_prefixes(const_iterator, const_iterator, const_iterator, const_iterator, bool compare_after = false) const; bool cmp_keys(key_const_reference, key_const_reference) const; inline static key_const_reference extract_key(const_reference); #ifdef _GLIBCXX_DEBUG bool operator()(key_const_reference, key_const_reference); #endif private: inline static key_const_reference extract_key(const_reference, true_type); inline static key_const_reference extract_key(const_reference, false_type); static integral_constant s_set_ind; }; PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC integral_constant PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::s_set_ind; PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: synth_access_traits() { } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: synth_access_traits(const _ATraits& r_traits) : _ATraits(r_traits) { } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: equal_prefixes(const_iterator b_l, const_iterator e_l, const_iterator b_r, const_iterator e_r, bool compare_after /*= false */) const { while (b_l != e_l) { if (b_r == e_r) return false; if (base_type::e_pos(*b_l) != base_type::e_pos(*b_r)) return false; ++b_l; ++b_r; } return (!compare_after || b_r == e_r); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: equal_keys(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return equal_prefixes(base_type::begin(r_lhs_key), base_type::end(r_lhs_key), base_type::begin(r_rhs_key), base_type::end(r_rhs_key), true); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: cmp_prefixes(const_iterator b_l, const_iterator e_l, const_iterator b_r, const_iterator e_r, bool compare_after /* = false*/) const { while (b_l != e_l) { if (b_r == e_r) return false; const typename base_type::size_type l_pos = base_type::e_pos(*b_l); const typename base_type::size_type r_pos = base_type::e_pos(*b_r); if (l_pos != r_pos) return l_pos < r_pos; ++b_l; ++b_r; } if (!compare_after) return false; return b_r != e_r; } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: cmp_keys(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return cmp_prefixes(base_type::begin(r_lhs_key), base_type::end(r_lhs_key), base_type::begin(r_rhs_key), base_type::end(r_rhs_key), true); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val) { return extract_key(r_val, s_set_ind); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val, true_type) { return r_val; } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val, false_type) { return r_val.first; } #ifdef _GLIBCXX_DEBUG PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: operator()(key_const_reference r_lhs, key_const_reference r_rhs) { return cmp_keys(r_lhs, r_rhs); } #endif #undef PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC #undef PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]ڂj.8/ext/pb_ds/detail/pat_trie_/pat_trie_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/pat_trie_base.hpp * Contains the base class for a patricia tree. */ #ifndef PB_DS_PAT_TRIE_BASE #define PB_DS_PAT_TRIE_BASE #include namespace __gnu_pbds { namespace detail { /// Base type for PATRICIA trees. struct pat_trie_base { /** * @brief Three types of nodes. * * i_node is used by _Inode, leaf_node by _Leaf, and head_node by _Head. */ enum node_type { i_node, leaf_node, head_node }; /// Metadata base primary template. template struct _Metadata { typedef Metadata metadata_type; typedef _Alloc allocator_type; typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other::const_reference const_reference; const_reference get_metadata() const { return m_metadata; } metadata_type m_metadata; }; /// Specialization for null metadata. template struct _Metadata { typedef null_type metadata_type; typedef _Alloc allocator_type; }; /// Node base. template struct _Node_base : public Metadata { private: typedef typename Metadata::allocator_type _Alloc; public: typedef _Alloc allocator_type; typedef _ATraits access_traits; typedef typename _ATraits::type_traits type_traits; typedef typename _Alloc::template rebind<_Node_base> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; node_pointer m_p_parent; const node_type m_type; _Node_base(node_type type) : m_type(type) { } typedef typename _Alloc::template rebind<_ATraits> __rebind_at; typedef typename __rebind_at::other::const_pointer a_const_pointer; typedef typename _ATraits::const_iterator a_const_iterator; #ifdef _GLIBCXX_DEBUG typedef std::pair node_debug_info; void assert_valid(a_const_pointer p_traits, const char* __file, int __line) const { assert_valid_imp(p_traits, __file, __line); } virtual node_debug_info assert_valid_imp(a_const_pointer, const char*, int) const = 0; #endif }; /// Head node for PATRICIA tree. template struct _Head : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename base_type::node_pointer node_pointer; node_pointer m_p_min; node_pointer m_p_max; _Head() : base_type(head_node) { } #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; typedef typename base_type::a_const_pointer a_const_pointer; virtual node_debug_info assert_valid_imp(a_const_pointer, const char* __file, int __line) const { _GLIBCXX_DEBUG_VERIFY_AT(false, _M_message("Assertion from %1;:%2;") ._M_string(__FILE__)._M_integer(__LINE__), __file, __line); return node_debug_info(); } #endif }; /// Leaf node for PATRICIA tree. template struct _Leaf : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename type_traits::value_type value_type; typedef typename type_traits::reference reference; typedef typename type_traits::const_reference const_reference; private: value_type m_value; _Leaf(const _Leaf&); public: _Leaf(const_reference other) : base_type(leaf_node), m_value(other) { } reference value() { return m_value; } const_reference value() const { return m_value; } #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; typedef typename base_type::a_const_pointer a_const_pointer; virtual node_debug_info assert_valid_imp(a_const_pointer p_traits, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_type == leaf_node); node_debug_info ret; const_reference r_val = value(); return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)), p_traits->end(p_traits->extract_key(r_val))); } virtual ~_Leaf() { } #endif }; /// Internal node type, PATRICIA tree. template struct _Inode : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename base_type::access_traits access_traits; typedef typename type_traits::value_type value_type; typedef typename base_type::allocator_type _Alloc; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; private: typedef typename base_type::a_const_pointer a_const_pointer; typedef typename base_type::a_const_iterator a_const_iterator; typedef typename base_type::node_pointer node_pointer; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::const_pointer node_const_pointer; typedef _Leaf<_ATraits, Metadata> leaf; typedef typename _Alloc::template rebind::other __rebind_l; typedef typename __rebind_l::pointer leaf_pointer; typedef typename __rebind_l::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind<_Inode>::other __rebind_in; typedef typename __rebind_in::pointer inode_pointer; typedef typename __rebind_in::const_pointer inode_const_pointer; inline size_type get_pref_pos(a_const_iterator, a_const_iterator, a_const_pointer) const; public: typedef typename _Alloc::template rebind::other __rebind_np; typedef typename __rebind_np::pointer node_pointer_pointer; typedef typename __rebind_np::reference node_pointer_reference; enum { arr_size = _ATraits::max_size + 1 }; PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2); /// Constant child iterator. struct const_iterator { node_pointer_pointer m_p_p_cur; node_pointer_pointer m_p_p_end; typedef std::forward_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef node_pointer value_type; typedef node_pointer_pointer pointer; typedef node_pointer_reference reference; const_iterator(node_pointer_pointer p_p_cur = 0, node_pointer_pointer p_p_end = 0) : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end) { } bool operator==(const const_iterator& other) const { return m_p_p_cur == other.m_p_p_cur; } bool operator!=(const const_iterator& other) const { return m_p_p_cur != other.m_p_p_cur; } const_iterator& operator++() { do ++m_p_p_cur; while (m_p_p_cur != m_p_p_end && *m_p_p_cur == 0); return *this; } const_iterator operator++(int) { const_iterator ret_it(*this); operator++(); return ret_it; } const node_pointer_pointer operator->() const { _GLIBCXX_DEBUG_ONLY(assert_referencible();) return m_p_p_cur; } node_const_pointer operator*() const { _GLIBCXX_DEBUG_ONLY(assert_referencible();) return *m_p_p_cur; } protected: #ifdef _GLIBCXX_DEBUG void assert_referencible() const { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end && *m_p_p_cur != 0); } #endif }; /// Child iterator. struct iterator : public const_iterator { public: typedef std::forward_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef node_pointer value_type; typedef node_pointer_pointer pointer; typedef node_pointer_reference reference; inline iterator(node_pointer_pointer p_p_cur = 0, node_pointer_pointer p_p_end = 0) : const_iterator(p_p_cur, p_p_end) { } bool operator==(const iterator& other) const { return const_iterator::m_p_p_cur == other.m_p_p_cur; } bool operator!=(const iterator& other) const { return const_iterator::m_p_p_cur != other.m_p_p_cur; } iterator& operator++() { const_iterator::operator++(); return *this; } iterator operator++(int) { iterator ret_it(*this); operator++(); return ret_it; } node_pointer_pointer operator->() { _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) return const_iterator::m_p_p_cur; } node_pointer operator*() { _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) return *const_iterator::m_p_p_cur; } }; _Inode(size_type, const a_const_iterator); void update_prefixes(a_const_pointer); const_iterator begin() const; iterator begin(); const_iterator end() const; iterator end(); inline node_pointer get_child_node(a_const_iterator, a_const_iterator, a_const_pointer); inline node_const_pointer get_child_node(a_const_iterator, a_const_iterator, a_const_pointer) const; inline iterator get_child_it(a_const_iterator, a_const_iterator, a_const_pointer); inline node_pointer get_lower_bound_child_node(a_const_iterator, a_const_iterator, size_type, a_const_pointer); inline node_pointer add_child(node_pointer, a_const_iterator, a_const_iterator, a_const_pointer); inline node_const_pointer get_join_child(node_const_pointer, a_const_pointer) const; inline node_pointer get_join_child(node_pointer, a_const_pointer); void remove_child(node_pointer); void remove_child(iterator); void replace_child(node_pointer, a_const_iterator, a_const_iterator, a_const_pointer); inline a_const_iterator pref_b_it() const; inline a_const_iterator pref_e_it() const; bool should_be_mine(a_const_iterator, a_const_iterator, size_type, a_const_pointer) const; leaf_pointer leftmost_descendant(); leaf_const_pointer leftmost_descendant() const; leaf_pointer rightmost_descendant(); leaf_const_pointer rightmost_descendant() const; #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; virtual node_debug_info assert_valid_imp(a_const_pointer, const char*, int) const; #endif size_type get_e_ind() const { return m_e_ind; } private: _Inode(const _Inode&); size_type get_begin_pos() const; static __rebind_l s_leaf_alloc; static __rebind_in s_inode_alloc; const size_type m_e_ind; a_const_iterator m_pref_b_it; a_const_iterator m_pref_e_it; node_pointer m_a_p_children[arr_size]; }; #define PB_DS_CONST_IT_C_DEC \ _CIter #define PB_DS_CONST_ODIR_IT_C_DEC \ _CIter #define PB_DS_IT_C_DEC \ _Iter #define PB_DS_ODIR_IT_C_DEC \ _Iter /// Const iterator. template class _CIter { public: // These types are all the same for the first four template arguments. typedef typename Node::allocator_type allocator_type; typedef typename Node::type_traits type_traits; typedef std::bidirectional_iterator_tag iterator_category; typedef typename allocator_type::difference_type difference_type; typedef typename type_traits::value_type value_type; typedef typename type_traits::pointer pointer; typedef typename type_traits::reference reference; typedef typename type_traits::const_pointer const_pointer; typedef typename type_traits::const_reference const_reference; typedef allocator_type _Alloc; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind __rebind_l; typedef typename __rebind_l::other::pointer leaf_pointer; typedef typename __rebind_l::other::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind __rebind_h; typedef typename __rebind_h::other::pointer head_pointer; typedef typename _Alloc::template rebind __rebind_in; typedef typename __rebind_in::other::pointer inode_pointer; typedef typename Inode::iterator inode_iterator; node_pointer m_p_nd; _CIter(node_pointer p_nd = 0) : m_p_nd(p_nd) { } _CIter(const PB_DS_CONST_ODIR_IT_C_DEC& other) : m_p_nd(other.m_p_nd) { } _CIter& operator=(const _CIter& other) { m_p_nd = other.m_p_nd; return *this; } _CIter& operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node); return &static_cast(m_p_nd)->value(); } const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node); return static_cast(m_p_nd)->value(); } bool operator==(const _CIter& other) const { return m_p_nd == other.m_p_nd; } bool operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd == other.m_p_nd; } bool operator!=(const _CIter& other) const { return m_p_nd != other.m_p_nd; } bool operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } _CIter& operator++() { inc(integral_constant()); return *this; } _CIter operator++(int) { _CIter ret_it(m_p_nd); operator++(); return ret_it; } _CIter& operator--() { dec(integral_constant()); return *this; } _CIter operator--(int) { _CIter ret_it(m_p_nd); operator--(); return ret_it; } protected: void inc(false_type) { dec(true_type()); } void inc(true_type) { if (m_p_nd->m_type == head_node) { m_p_nd = static_cast(m_p_nd)->m_p_min; return; } node_pointer p_y = m_p_nd->m_p_parent; while (p_y->m_type != head_node && get_larger_sibling(m_p_nd) == 0) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (p_y->m_type == head_node) { m_p_nd = p_y; return; } m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd)); } void dec(false_type) { inc(true_type()); } void dec(true_type) { if (m_p_nd->m_type == head_node) { m_p_nd = static_cast(m_p_nd)->m_p_max; return; } node_pointer p_y = m_p_nd->m_p_parent; while (p_y->m_type != head_node && get_smaller_sibling(m_p_nd) == 0) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (p_y->m_type == head_node) { m_p_nd = p_y; return; } m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd)); } static node_pointer get_larger_sibling(node_pointer p_nd) { inode_pointer p_parent = static_cast(p_nd->m_p_parent); inode_iterator it = p_parent->begin(); while (*it != p_nd) ++it; inode_iterator next_it = it; ++next_it; return (next_it == p_parent->end())? 0 : *next_it; } static node_pointer get_smaller_sibling(node_pointer p_nd) { inode_pointer p_parent = static_cast(p_nd->m_p_parent); inode_iterator it = p_parent->begin(); if (*it == p_nd) return 0; inode_iterator prev_it; do { prev_it = it; ++it; if (*it == p_nd) return *prev_it; } while (true); _GLIBCXX_DEBUG_ASSERT(false); return 0; } static leaf_pointer leftmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->leftmost_descendant(); } static leaf_pointer rightmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->rightmost_descendant(); } }; /// Iterator. template class _Iter : public _CIter { public: typedef _CIter base_type; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::type_traits type_traits; typedef typename type_traits::value_type value_type; typedef typename type_traits::pointer pointer; typedef typename type_traits::reference reference; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::leaf_pointer leaf_pointer; typedef typename base_type::leaf_const_pointer leaf_const_pointer; typedef typename base_type::head_pointer head_pointer; typedef typename base_type::inode_pointer inode_pointer; _Iter(node_pointer p_nd = 0) : base_type(p_nd) { } _Iter(const PB_DS_ODIR_IT_C_DEC& other) : base_type(other.m_p_nd) { } _Iter& operator=(const _Iter& other) { base_type::m_p_nd = other.m_p_nd; return *this; } _Iter& operator=(const PB_DS_ODIR_IT_C_DEC& other) { base_type::m_p_nd = other.m_p_nd; return *this; } pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node); return &static_cast(base_type::m_p_nd)->value(); } reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node); return static_cast(base_type::m_p_nd)->value(); } _Iter& operator++() { base_type::operator++(); return *this; } _Iter operator++(int) { _Iter ret(base_type::m_p_nd); operator++(); return ret; } _Iter& operator--() { base_type::operator--(); return *this; } _Iter operator--(int) { _Iter ret(base_type::m_p_nd); operator--(); return ret; } }; #undef PB_DS_CONST_ODIR_IT_C_DEC #undef PB_DS_ODIR_IT_C_DEC #define PB_DS_PAT_TRIE_NODE_CONST_ITERATOR_C_DEC \ _Node_citer #define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \ _Node_iter /// Node const iterator. template class _Node_citer { protected: typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind __rebind_l; typedef typename __rebind_l::other::pointer leaf_pointer; typedef typename __rebind_l::other::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind __rebind_in; typedef typename __rebind_in::other::pointer inode_pointer; typedef typename __rebind_in::other::const_pointer inode_const_pointer; typedef typename Node::a_const_pointer a_const_pointer; typedef typename Node::a_const_iterator a_const_iterator; private: a_const_iterator pref_begin() const { if (m_p_nd->m_type == leaf_node) { leaf_const_pointer lcp = static_cast(m_p_nd); return m_p_traits->begin(m_p_traits->extract_key(lcp->value())); } _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); return static_cast(m_p_nd)->pref_b_it(); } a_const_iterator pref_end() const { if (m_p_nd->m_type == leaf_node) { leaf_const_pointer lcp = static_cast(m_p_nd); return m_p_traits->end(m_p_traits->extract_key(lcp->value())); } _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); return static_cast(m_p_nd)->pref_e_it(); } public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::size_type size_type; typedef _CIterator value_type; typedef value_type reference; typedef value_type const_reference; /// Metadata type. typedef typename Node::metadata_type metadata_type; /// Const metadata reference type. typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename __rebind_ma::const_reference metadata_const_reference; inline _Node_citer(node_pointer p_nd = 0, a_const_pointer p_traits = 0) : m_p_nd(const_cast(p_nd)), m_p_traits(p_traits) { } /// Subtree valid prefix. std::pair valid_prefix() const { return std::make_pair(pref_begin(), pref_end()); } /// Const access; returns the __const iterator* associated with /// the current leaf. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(num_children() == 0); return _CIterator(m_p_nd); } /// Metadata access. metadata_const_reference get_metadata() const { return m_p_nd->get_metadata(); } /// Returns the number of children in the corresponding node. size_type num_children() const { if (m_p_nd->m_type == leaf_node) return 0; _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); inode_pointer inp = static_cast(m_p_nd); return std::distance(inp->begin(), inp->end()); } /// Returns a __const node __iterator to the corresponding node's /// i-th child. _Node_citer get_child(size_type i) const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); inode_pointer inp = static_cast(m_p_nd); typename Inode::iterator it = inp->begin(); std::advance(it, i); return _Node_citer(*it, m_p_traits); } /// Compares content to a different iterator object. bool operator==(const _Node_citer& other) const { return m_p_nd == other.m_p_nd; } /// Compares content (negatively) to a different iterator object. bool operator!=(const _Node_citer& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; a_const_pointer m_p_traits; }; /// Node iterator. template class _Node_iter : public _Node_citer { private: typedef _Node_citer base_type; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename base_type::inode_pointer inode_pointer; typedef typename base_type::a_const_pointer a_const_pointer; typedef Iterator iterator; public: typedef typename base_type::size_type size_type; typedef Iterator value_type; typedef value_type reference; typedef value_type const_reference; _Node_iter(node_pointer p_nd = 0, a_const_pointer p_traits = 0) : base_type(p_nd, p_traits) { } /// Access; returns the iterator* associated with the current leaf. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0); return iterator(base_type::m_p_nd); } /// Returns a node __iterator to the corresponding node's i-th child. _Node_iter get_child(size_type i) const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == i_node); typename Inode::iterator it = static_cast(base_type::m_p_nd)->begin(); std::advance(it, i); return _Node_iter(*it, base_type::m_p_traits); } }; }; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ pat_trie_base::_Inode<_ATraits, Metadata> PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::__rebind_l PB_DS_CLASS_C_DEC::s_leaf_alloc; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::__rebind_in PB_DS_CLASS_C_DEC::s_inode_alloc; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_pref_pos(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) const { if (static_cast(std::distance(b_it, e_it)) <= m_e_ind) return 0; std::advance(b_it, m_e_ind); return 1 + p_traits->e_pos(*b_it); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: _Inode(size_type len, const a_const_iterator it) : base_type(i_node), m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it) { std::advance(m_pref_e_it, m_e_ind); std::fill(m_a_p_children, m_a_p_children + arr_size, static_cast(0)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_prefixes(a_const_pointer p_traits) { node_pointer p_first = *begin(); if (p_first->m_type == leaf_node) { leaf_const_pointer p = static_cast(p_first); m_pref_b_it = p_traits->begin(access_traits::extract_key(p->value())); } else { inode_pointer p = static_cast(p_first); _GLIBCXX_DEBUG_ASSERT(p_first->m_type == i_node); m_pref_b_it = p->pref_b_it(); } m_pref_e_it = m_pref_b_it; std::advance(m_pref_e_it, m_e_ind); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { typedef node_pointer_pointer pointer_type; pointer_type p = const_cast(m_a_p_children); return const_iterator(p + get_begin_pos(), p + arr_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_a_p_children + get_begin_pos(), m_a_p_children + arr_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { typedef node_pointer_pointer pointer_type; pointer_type p = const_cast(m_a_p_children) + arr_size; return const_iterator(p, p); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_child_node(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); return m_a_p_children[i]; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: get_child_it(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != 0); return iterator(m_a_p_children + i, m_a_p_children + i); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: get_child_node(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) const { return const_cast(get_child_node(b_it, e_it, p_traits)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_lower_bound_child_node(a_const_iterator b_it, a_const_iterator e_it, size_type checked_ind, a_const_pointer p_traits) { if (!should_be_mine(b_it, e_it, checked_ind, p_traits)) { if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it, m_pref_e_it, true)) return leftmost_descendant(); return rightmost_descendant(); } size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); if (m_a_p_children[i] != 0) return m_a_p_children[i]; while (++i < arr_size) if (m_a_p_children[i] != 0) { const node_type& __nt = m_a_p_children[i]->m_type; node_pointer ret = m_a_p_children[i]; if (__nt == leaf_node) return ret; _GLIBCXX_DEBUG_ASSERT(__nt == i_node); inode_pointer inp = static_cast(ret); return inp->leftmost_descendant(); } return rightmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: add_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); if (m_a_p_children[i] == 0) { m_a_p_children[i] = p_nd; p_nd->m_p_parent = this; return p_nd; } return m_a_p_children[i]; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: get_join_child(node_const_pointer p_nd, a_const_pointer p_tr) const { node_pointer p = const_cast(p_nd); return const_cast(this)->get_join_child(p, p_tr); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_join_child(node_pointer p_nd, a_const_pointer p_traits) { size_type i; a_const_iterator b_it; a_const_iterator e_it; if (p_nd->m_type == leaf_node) { leaf_const_pointer p = static_cast(p_nd); typedef typename type_traits::key_const_reference kcr; kcr r_key = access_traits::extract_key(p->value()); b_it = p_traits->begin(r_key); e_it = p_traits->end(r_key); } else { b_it = static_cast(p_nd)->pref_b_it(); e_it = static_cast(p_nd)->pref_e_it(); } i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); return m_a_p_children[i]; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_child(node_pointer p_nd) { size_type i = 0; for (; i < arr_size; ++i) if (m_a_p_children[i] == p_nd) { m_a_p_children[i] = 0; return; } _GLIBCXX_DEBUG_ASSERT(i != arr_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_child(iterator it) { *it.m_p_p_cur = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: replace_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); m_a_p_children[i] = p_nd; p_nd->m_p_parent = this; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_b_it() const { return m_pref_b_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_e_it() const { return m_pref_e_it; } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: should_be_mine(a_const_iterator b_it, a_const_iterator e_it, size_type checked_ind, a_const_pointer p_traits) const { if (m_e_ind == 0) return true; const size_type num_es = std::distance(b_it, e_it); if (num_es < m_e_ind) return false; a_const_iterator key_b_it = b_it; std::advance(key_b_it, checked_ind); a_const_iterator key_e_it = b_it; std::advance(key_e_it, m_e_ind); a_const_iterator value_b_it = m_pref_b_it; std::advance(value_b_it, checked_ind); a_const_iterator value_e_it = m_pref_b_it; std::advance(value_e_it, m_e_ind); return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it, value_e_it); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant() { node_pointer p_pot = *begin(); if (p_pot->m_type == leaf_node) return (static_cast(p_pot)); _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node); return static_cast(p_pot)->leftmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant() const { return const_cast(this)->leftmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant() { const size_type num_children = std::distance(begin(), end()); _GLIBCXX_DEBUG_ASSERT(num_children >= 2); iterator it = begin(); std::advance(it, num_children - 1); node_pointer p_pot =* it; if (p_pot->m_type == leaf_node) return static_cast(p_pot); _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node); return static_cast(p_pot)->rightmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant() const { return const_cast(this)->rightmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_begin_pos() const { size_type i = 0; for (; i < arr_size && m_a_p_children[i] == 0; ++i) ; return i; } #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_debug_info PB_DS_CLASS_C_DEC:: assert_valid_imp(a_const_pointer p_traits, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_type == i_node); PB_DS_DEBUG_VERIFY(static_cast(std::distance(pref_b_it(), pref_e_it())) == m_e_ind); PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) >= 2); for (typename _Inode::const_iterator it = begin(); it != end(); ++it) { node_const_pointer p_nd = *it; PB_DS_DEBUG_VERIFY(p_nd->m_p_parent == this); node_debug_info child_ret = p_nd->assert_valid_imp(p_traits, __file, __line); PB_DS_DEBUG_VERIFY(static_cast(std::distance(child_ret.first, child_ret.second)) >= m_e_ind); PB_DS_DEBUG_VERIFY(should_be_mine(child_ret.first, child_ret.second, 0, p_traits)); PB_DS_DEBUG_VERIFY(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast(it.m_p_p_cur - m_a_p_children)); } return std::make_pair(pref_b_it(), pref_e_it()); } #endif #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]#ӌAA*8/ext/pb_ds/detail/pat_trie_/pat_trie_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/pat_trie_.hpp * Contains an implementation class for a patricia tree. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_PAT_TRIE_NAME pat_trie_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_PAT_TRIE_NAME pat_trie_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_PAT_TRIE_NAME #define PB_DS_PAT_TRIE_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base >, \ typename _Alloc::template rebind::other::const_reference> #endif /** * @brief PATRICIA trie. * @ingroup branch-detail * * This implementation loosely borrows ideas from: * 1) Fast Mergeable Integer Maps, Okasaki, Gill 1998 * 2) Ptset: Sets of integers implemented as Patricia trees, * Jean-Christophe Filliatr, 2000 */ template class PB_DS_PAT_TRIE_NAME : #ifdef _GLIBCXX_DEBUG public PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public Node_And_It_Traits::synth_access_traits, public Node_And_It_Traits::node_update, public PB_DS_PAT_TRIE_TRAITS_BASE, public pat_trie_base { private: typedef pat_trie_base base_type; typedef PB_DS_PAT_TRIE_TRAITS_BASE traits_base; typedef Node_And_It_Traits traits_type; typedef typename traits_type::synth_access_traits synth_access_traits; typedef typename synth_access_traits::const_iterator a_const_iterator; typedef typename traits_type::node node; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::const_pointer node_const_pointer; typedef typename __rebind_n::other::pointer node_pointer; typedef typename traits_type::head head; typedef typename _Alloc::template rebind __rebind_h; typedef typename __rebind_h::other head_allocator; typedef typename head_allocator::pointer head_pointer; typedef typename traits_type::leaf leaf; typedef typename _Alloc::template rebind __rebind_l; typedef typename __rebind_l::other leaf_allocator; typedef typename leaf_allocator::pointer leaf_pointer; typedef typename leaf_allocator::const_pointer leaf_const_pointer; typedef typename traits_type::inode inode; typedef typename inode::iterator inode_iterator; typedef typename _Alloc::template rebind __rebind_in; typedef typename __rebind_in::other __rebind_ina; typedef typename __rebind_in::other inode_allocator; typedef typename __rebind_ina::pointer inode_pointer; typedef typename __rebind_ina::const_pointer inode_const_pointer; /// Conditional deallocator. class cond_dealtor { protected: leaf_pointer m_p_nd; bool m_no_action_dtor; bool m_call_destructor; public: cond_dealtor(leaf_pointer p_nd) : m_p_nd(p_nd), m_no_action_dtor(false), m_call_destructor(false) { } void set_no_action_dtor() { m_no_action_dtor = true; } void set_call_destructor() { m_call_destructor = true; } ~cond_dealtor() { if (m_no_action_dtor) return; if (m_call_destructor) m_p_nd->~leaf(); s_leaf_allocator.deallocate(m_p_nd, 1); } }; /// Branch bag, for split-join. class branch_bag { private: typedef inode_pointer __inp; typedef typename _Alloc::template rebind<__inp>::other __rebind_inp; #ifdef _GLIBCXX_DEBUG typedef std::_GLIBCXX_STD_C::list<__inp, __rebind_inp> bag_type; #else typedef std::list<__inp, __rebind_inp> bag_type; #endif bag_type m_bag; public: void add_branch() { inode_pointer p_nd = s_inode_allocator.allocate(1); __try { m_bag.push_back(p_nd); } __catch(...) { s_inode_allocator.deallocate(p_nd, 1); __throw_exception_again; } } inode_pointer get_branch() { _GLIBCXX_DEBUG_ASSERT(!m_bag.empty()); inode_pointer p_nd = *m_bag.begin(); m_bag.pop_front(); return p_nd; } ~branch_bag() { while (!m_bag.empty()) { inode_pointer p_nd = *m_bag.begin(); s_inode_allocator.deallocate(p_nd, 1); m_bag.pop_front(); } } inline bool empty() const { return m_bag.empty(); } }; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef typename traits_type::null_node_update_pointer null_node_update_pointer; public: typedef pat_trie_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef typename traits_type::access_traits access_traits; typedef typename traits_type::const_iterator point_const_iterator; typedef typename traits_type::iterator point_iterator; typedef point_const_iterator const_iterator; typedef point_iterator iterator; typedef typename traits_type::reverse_iterator reverse_iterator; typedef typename traits_type::const_reverse_iterator const_reverse_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_update node_update; PB_DS_PAT_TRIE_NAME(); PB_DS_PAT_TRIE_NAME(const access_traits&); PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~PB_DS_PAT_TRIE_NAME(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; access_traits& get_access_traits(); const access_traits& get_access_traits() const; node_update& get_node_update(); const node_update& get_node_update() const; inline std::pair insert(const_reference); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return insert(std::make_pair(r_key, mapped_type())).first->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator lower_bound(key_const_reference); inline point_const_iterator lower_bound(key_const_reference) const; inline point_iterator upper_bound(key_const_reference); inline point_const_iterator upper_bound(key_const_reference) const; void clear(); inline bool erase(key_const_reference); inline const_iterator erase(const_iterator); #ifdef PB_DS_DATA_TRUE_INDICATOR inline iterator erase(iterator); #endif inline const_reverse_iterator erase(const_reverse_iterator); #ifdef PB_DS_DATA_TRUE_INDICATOR inline reverse_iterator erase(reverse_iterator); #endif template inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline reverse_iterator rbegin(); inline const_reverse_iterator rbegin() const; inline reverse_iterator rend(); inline const_reverse_iterator rend() const; /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); #ifdef PB_DS_PAT_TRIE_TRACE_ void trace() const; #endif protected: template void copy_from_range(It, It); void value_swap(PB_DS_CLASS_C_DEC&); node_pointer recursive_copy_node(node_const_pointer); private: void initialize(); inline void apply_update(node_pointer, null_node_update_pointer); template inline void apply_update(node_pointer, Node_Update_*); bool join_prep(PB_DS_CLASS_C_DEC&, branch_bag&); void rec_join_prep(node_const_pointer, node_const_pointer, branch_bag&); void rec_join_prep(leaf_const_pointer, leaf_const_pointer, branch_bag&); void rec_join_prep(leaf_const_pointer, inode_const_pointer, branch_bag&); void rec_join_prep(inode_const_pointer, leaf_const_pointer, branch_bag&); void rec_join_prep(inode_const_pointer, inode_const_pointer, branch_bag&); node_pointer rec_join(node_pointer, node_pointer, size_type, branch_bag&); node_pointer rec_join(leaf_pointer, leaf_pointer, branch_bag&); node_pointer rec_join(leaf_pointer, inode_pointer, size_type, branch_bag&); node_pointer rec_join(inode_pointer, leaf_pointer, size_type, branch_bag&); node_pointer rec_join(inode_pointer, inode_pointer, branch_bag&); size_type keys_diff_ind(typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator); inode_pointer insert_branch(node_pointer, node_pointer, branch_bag&); void update_min_max_for_inserted_leaf(leaf_pointer); void erase_leaf(leaf_pointer); inline void actual_erase_leaf(leaf_pointer); void clear_imp(node_pointer); void erase_fixup(inode_pointer); void update_min_max_for_erased_leaf(leaf_pointer); static inline a_const_iterator pref_begin(node_const_pointer); static inline a_const_iterator pref_end(node_const_pointer); inline node_pointer find_imp(key_const_reference); inline node_pointer lower_bound_imp(key_const_reference); inline node_pointer upper_bound_imp(key_const_reference); inline static leaf_const_pointer leftmost_descendant(node_const_pointer); inline static leaf_pointer leftmost_descendant(node_pointer); inline static leaf_const_pointer rightmost_descendant(node_const_pointer); inline static leaf_pointer rightmost_descendant(node_pointer); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_iterators(const char*, int) const; void assert_reverse_iterators(const char*, int) const; static size_type recursive_count_leafs(node_const_pointer, const char*, int); #endif #ifdef PB_DS_PAT_TRIE_TRACE_ static void trace_node(node_const_pointer, size_type); template static void trace_node_metadata(node_const_pointer, type_to_type); static void trace_node_metadata(node_const_pointer, type_to_type); #endif leaf_pointer split_prep(key_const_reference, PB_DS_CLASS_C_DEC&, branch_bag&); node_pointer rec_split(node_pointer, a_const_iterator, a_const_iterator, PB_DS_CLASS_C_DEC&, branch_bag&); void split_insert_branch(size_type, a_const_iterator, inode_iterator, size_type, branch_bag&); static head_allocator s_head_allocator; static inode_allocator s_inode_allocator; static leaf_allocator s_leaf_allocator; head_pointer m_p_head; size_type m_size; }; #define PB_DS_ASSERT_NODE_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X->assert_valid(this, __FILE__, __LINE__);) #define PB_DS_RECURSIVE_COUNT_LEAFS(X) \ recursive_count_leafs(X, __FILE__, __LINE__) #include #include #include #include #include #include #include #include #include #include #include #undef PB_DS_RECURSIVE_COUNT_LEAFS #undef PB_DS_ASSERT_NODE_VALID #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_PAT_TRIE_NAME #undef PB_DS_PAT_TRIE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC } // namespace detail } // namespace __gnu_pbds PKgd1],'+'8/ext/pb_ds/detail/pat_trie_/traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/traits.hpp * Contains an implementation class for pat_trie_. */ #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP #define PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP #include #include namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct trie_traits { private: typedef pat_trie_base base_type; typedef types_traits type_traits; public: typedef typename trie_node_metadata_dispatch::type metadata_type; typedef base_type::_Metadata metadata; typedef _ATraits access_traits; /// Type for synthesized traits. typedef __gnu_pbds::detail::synth_access_traits synth_access_traits; typedef base_type::_Node_base node; typedef base_type::_Head head; typedef base_type::_Leaf leaf; typedef base_type::_Inode inode; typedef base_type::_Iter iterator; typedef base_type::_CIter const_iterator; typedef base_type::_Iter reverse_iterator; typedef base_type::_CIter const_reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef base_type::_Node_citer node_const_iterator; typedef base_type::_Node_iter node_iterator; /// Type for node update. typedef Node_Update node_update; typedef null_node_update* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct trie_traits { private: typedef pat_trie_base base_type; typedef types_traits type_traits; public: typedef typename trie_node_metadata_dispatch::type metadata_type; typedef base_type::_Metadata metadata; typedef _ATraits access_traits; /// Type for synthesized traits. typedef __gnu_pbds::detail::synth_access_traits synth_access_traits; typedef base_type::_Node_base node; typedef base_type::_Head head; typedef base_type::_Leaf leaf; typedef base_type::_Inode inode; typedef base_type::_CIter const_iterator; typedef const_iterator iterator; typedef base_type::_CIter const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef base_type::_Node_citer node_const_iterator; typedef node_const_iterator node_iterator; /// Type for node update. typedef Node_Update node_update; typedef null_node_update* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP PKgd1]T+f]]78/ext/pb_ds/detail/trie_policy/order_statistics_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/order_statistics_imp.hpp * Contains forward declarations for order_statistics_key */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) { if (empty()) return end(); ++order; node_iterator nd_it = node_begin(); while (true) { if (order > nd_it.get_metadata()) return ++base_type::rightmost_it(nd_it); const size_type num_children = nd_it.num_children(); if (num_children == 0) return *nd_it; for (size_type i = 0; i < num_children; ++i) { node_iterator child_nd_it = nd_it.get_child(i); if (order <= child_nd_it.get_metadata()) { i = num_children; nd_it = child_nd_it; } else order -= child_nd_it.get_metadata(); } } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) const { return const_cast(this)->find_by_order(order); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_key(key_const_reference r_key) const { const _ATraits& r_traits = const_cast(this)->get_access_traits(); return order_of_prefix(r_traits.begin(r_key), r_traits.end(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_prefix(typename access_traits::const_iterator b, typename access_traits::const_iterator e) const { if (empty()) return 0; const _ATraits& r_traits = const_cast(this)->get_access_traits(); node_const_iterator nd_it = node_begin(); node_const_iterator end_nd_it = node_end(); size_type ord = 0; while (true) { const size_type num_children = nd_it.num_children(); if (num_children == 0) { key_const_reference r_key = base_type::extract_key(*(*nd_it)); typename access_traits::const_iterator key_b = r_traits.begin(r_key); typename access_traits::const_iterator key_e = r_traits.end(r_key); return (base_type::less(key_b, key_e, b, e, r_traits)) ? ord + 1 : ord; } node_const_iterator next_nd_it = end_nd_it; size_type i = num_children - 1; do { node_const_iterator child_nd_it = nd_it.get_child(i); if (next_nd_it != end_nd_it) ord += child_nd_it.get_metadata(); else if (!base_type::less(b, e, child_nd_it.valid_prefix().first, child_nd_it.valid_prefix().second, r_traits)) next_nd_it = child_nd_it; } while (i-- > 0); if (next_nd_it == end_nd_it) return ord; nd_it = next_nd_it; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator nd_it, node_const_iterator /*end_nd_it*/) const { const size_type num_children = nd_it.num_children(); size_type children_rank = 0; for (size_type i = 0; i < num_children; ++i) children_rank += nd_it.get_child(i).get_metadata(); const size_type res = (num_children == 0) ? 1 : children_rank; const_cast(nd_it.get_metadata()) = res; } PKgd1]Ja <8/ext/pb_ds/detail/trie_policy/sample_trie_access_traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/sample_trie_access_traits.hpp * Contains a sample probe policy. */ #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP #define PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP namespace __gnu_pbds { /// A sample trie element access traits. struct sample_trie_access_traits { typedef std::size_t size_type; typedef std::string key_type; typedef typename _Alloc::template rebind __rebind_k; typedef typename __rebind_k::other::const_reference key_const_reference; typedef std::string::const_iterator const_iterator; /// Element type. typedef char e_type; enum { max_size = 4 }; /// Returns a const_iterator to the first element of r_key. inline static const_iterator begin(key_const_reference); /// Returns a const_iterator to the after-last element of r_key. inline static const_iterator end(key_const_reference); /// Maps an element to a position. inline static size_type e_pos(e_type); }; } #endif // #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP PKgd1]&vC 98/ext/pb_ds/detail/trie_policy/node_metadata_selector.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/node_metadata_selector.hpp * Contains an implementation class for tries. */ #ifndef PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP #define PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP #include #include namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Trie metadata helper. template struct trie_metadata_helper; /// Specialization, false. template struct trie_metadata_helper { typedef typename Node_Update::metadata_type type; }; /// Specialization, true. template struct trie_metadata_helper { typedef null_type type; }; /// Trie node metadata dispatch. template class Node_Update, typename _Alloc> struct trie_node_metadata_dispatch { private: typedef dumnode_const_iterator __it_type; typedef Node_Update<__it_type, __it_type, Cmp_Fn, _Alloc> __node_u; typedef null_node_update<__it_type, __it_type, Cmp_Fn, _Alloc> __nnode_u; enum { null_update = is_same<__node_u, __nnode_u>::value }; public: typedef typename trie_metadata_helper<__node_u, null_update>::type type; }; //@} } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP PKgd1] {ɟ@8/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/prefix_search_node_update_imp.hpp * Contains an implementation of prefix_search_node_update. */ PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::const_iterator, typename PB_DS_CLASS_C_DEC::const_iterator> PB_DS_CLASS_C_DEC:: prefix_range(key_const_reference r_key) const { const access_traits& r_traits = get_access_traits(); return (prefix_range(r_traits.begin(r_key), r_traits.end(r_key))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::iterator, typename PB_DS_CLASS_C_DEC::iterator> PB_DS_CLASS_C_DEC:: prefix_range(key_const_reference r_key) { return (prefix_range(get_access_traits().begin(r_key), get_access_traits().end(r_key))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::const_iterator, typename PB_DS_CLASS_C_DEC::const_iterator> PB_DS_CLASS_C_DEC:: prefix_range(typename access_traits::const_iterator b, typename access_traits::const_iterator e) const { const std::pair non_const_ret = const_cast(this)->prefix_range(b, e); return (std::make_pair(const_iterator(non_const_ret.first), const_iterator(non_const_ret.second))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::iterator, typename PB_DS_CLASS_C_DEC::iterator> PB_DS_CLASS_C_DEC:: prefix_range(typename access_traits::const_iterator b, typename access_traits::const_iterator e) { Node_Itr nd_it = node_begin(); Node_Itr end_nd_it = node_end(); const access_traits& r_traits = get_access_traits(); const size_type given_range_length = std::distance(b, e); while (true) { if (nd_it == end_nd_it) return (std::make_pair(end(), end())); const size_type common_range_length = base_type::common_prefix_len(nd_it, b, e, r_traits); if (common_range_length >= given_range_length) { iterator ret_b = this->leftmost_it(nd_it); iterator ret_e = this->rightmost_it(nd_it); return (std::make_pair(ret_b, ++ret_e)); } nd_it = next_child(nd_it, b, e, end_nd_it, r_traits); } } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: next_child(node_iterator nd_it, typename access_traits::const_iterator b, typename access_traits::const_iterator e, node_iterator end_nd_it, const access_traits& r_traits) { const size_type num_children = nd_it.num_children(); node_iterator ret = end_nd_it; size_type max_length = 0; for (size_type i = 0; i < num_children; ++i) { node_iterator pot = nd_it.get_child(i); const size_type common_range_length = base_type::common_prefix_len(pot, b, e, r_traits); if (common_range_length > max_length) { ret = pot; max_length = common_range_length; } } return (ret); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator /*nd_it*/, node_const_iterator /*end_nd_it*/) const { } PKgd1]96 @8/ext/pb_ds/detail/trie_policy/trie_string_access_traits_imp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/trie_string_access_traits_imp.hpp * Contains a policy for extracting character positions from * a string for a vector-based PATRICIA tree */ PB_DS_CLASS_T_DEC detail::integral_constant PB_DS_CLASS_C_DEC::s_rev_ind; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: e_pos(e_type e) { return (static_cast(e - min_e_val)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin(key_const_reference r_key) { return (begin_imp(r_key, s_rev_ind)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end(key_const_reference r_key) { return (end_imp(r_key, s_rev_ind)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin_imp(key_const_reference r_key, detail::false_type) { return (r_key.begin()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin_imp(key_const_reference r_key, detail::true_type) { return (r_key.rbegin()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end_imp(key_const_reference r_key, detail::false_type) { return (r_key.end()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end_imp(key_const_reference r_key, detail::true_type) { return (r_key.rend()); } PKgd1], , :8/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/sample_trie_node_update.hpp * Contains a samle node update functor. */ #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP #define PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP namespace __gnu_pbds { /// A sample node updator. template class sample_trie_node_update { public: typedef std::size_t metadata_type; protected: /// Default constructor. sample_trie_node_update(); /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; }; } #endif // #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP PKgd1]538/ext/pb_ds/detail/trie_policy/trie_policy_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/trie_policy_base.hpp * Contains an implementation of trie_policy_base. */ #ifndef PB_DS_TRIE_POLICY_BASE_HPP #define PB_DS_TRIE_POLICY_BASE_HPP #include namespace __gnu_pbds { namespace detail { /// Base class for trie policies. template class trie_policy_base : public branch_policy { typedef branch_policy base_type; public: typedef _ATraits access_traits; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef null_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; protected: virtual const_iterator end() const = 0; virtual iterator end() = 0; virtual node_const_iterator node_begin() const = 0; virtual node_iterator node_begin() = 0; virtual node_const_iterator node_end() const = 0; virtual node_iterator node_end() = 0; virtual const access_traits& get_access_traits() const = 0; private: typedef typename access_traits::const_iterator e_const_iterator; typedef std::pair prefix_range_t; protected: static size_type common_prefix_len(node_iterator, e_const_iterator, e_const_iterator, const access_traits&); static iterator leftmost_it(node_iterator); static iterator rightmost_it(node_iterator); static bool less(e_const_iterator, e_const_iterator, e_const_iterator, e_const_iterator, const access_traits&); }; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ trie_policy_base PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: common_prefix_len(node_iterator nd_it, e_const_iterator b_r, e_const_iterator e_r, const access_traits& r_traits) { prefix_range_t pref_range = nd_it.valid_prefix(); e_const_iterator b_l = pref_range.first; e_const_iterator e_l = pref_range.second; const size_type range_length_l = std::distance(b_l, e_l); const size_type range_length_r = std::distance(b_r, e_r); if (range_length_r < range_length_l) { std::swap(b_l, b_r); std::swap(e_l, e_r); } size_type ret = 0; while (b_l != e_l) { if (r_traits.e_pos(*b_l) != r_traits.e_pos(*b_r)) return ret; ++ret; ++b_l; ++b_r; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: leftmost_it(node_iterator nd_it) { if (nd_it.num_children() == 0) return *nd_it; return leftmost_it(nd_it.get_child(0)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: rightmost_it(node_iterator nd_it) { const size_type num_children = nd_it.num_children(); if (num_children == 0) return *nd_it; return rightmost_it(nd_it.get_child(num_children - 1)); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: less(e_const_iterator b_l, e_const_iterator e_l, e_const_iterator b_r, e_const_iterator e_r, const access_traits& r_traits) { while (b_l != e_l) { if (b_r == e_r) return false; size_type l_pos = r_traits.e_pos(*b_l); size_type r_pos = r_traits.e_pos(*b_r); if (l_pos != r_pos) return (l_pos < r_pos); ++b_l; ++b_r; } return b_r != e_r; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TRIE_POLICY_BASE_HPP PKgd1]%yB/8/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/trace_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef PB_DS_THIN_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; std::cerr << "m_p_max " << m_p_max << std::endl; base_type::trace(); } #endif // #ifdef PB_DS_THIN_HEAP_TRACE_ PKgd1]3^ A8/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap() : m_p_max(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn), m_p_max(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); m_p_max = base_type::m_p_root; for (node_pointer p_nd = base_type::m_p_root; p_nd != 0; p_nd = p_nd->m_p_next_sibling) if (Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) m_p_max = p_nd; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); std::swap(m_p_max, other.m_p_max); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~thin_heap() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { std::fill(m_a_aux, m_a_aux + max_rank, static_cast(0)); } PKgd1]3.8/ext/pb_ds/detail/thin_heap_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/find_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); return m_p_max->m_value; } PKgd1] /8/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/debug_fn_imps.hpp * Contains an implementation for thin_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); assert_node_consistent(base_type::m_p_root, true, __file, __line); assert_max(__file, __line); assert_aux_null(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_aux_null(const char* __file, int __line) const { for (size_type i = 0; i < max_rank; ++i) PB_DS_DEBUG_VERIFY(m_a_aux[i] == 0); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { if (m_p_max == 0) { PB_DS_DEBUG_VERIFY(base_type::empty()); return; } PB_DS_DEBUG_VERIFY(!base_type::empty()); PB_DS_DEBUG_VERIFY(base_type::parent(m_p_max) == 0); PB_DS_DEBUG_VERIFY(m_p_max->m_p_prev_or_parent == 0); for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool root, const char* __file, int __line) const { base_type::assert_node_consistent(p_nd, root, __file, __line); if (p_nd == 0) return; assert_node_consistent(p_nd->m_p_next_sibling, root, __file, __line); assert_node_consistent(p_nd->m_p_l_child, false, __file, __line); if (!root) { if (p_nd->m_metadata == 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_next_sibling == 0); else PB_DS_DEBUG_VERIFY(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata + 1); } if (p_nd->m_p_l_child != 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_l_child->m_metadata + 1 == base_type::degree(p_nd)); const bool unmarked_valid = (p_nd->m_p_l_child == 0 && p_nd->m_metadata == 0) || (p_nd->m_p_l_child != 0 && p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 1); const bool marked_valid = (p_nd->m_p_l_child == 0 && p_nd->m_metadata == 1) || (p_nd->m_p_l_child != 0 && p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 2); PB_DS_DEBUG_VERIFY(unmarked_valid || marked_valid); if (root) PB_DS_DEBUG_VERIFY(unmarked_valid); } #endif PKgd1]6;;08/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/insert_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); p_nd->m_metadata = 0; p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = 0; if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = 0; m_p_max = base_type::m_p_root = p_nd; PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } p_nd->m_p_next_sibling = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; update_max(p_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_root(node_pointer p_nd) { p_nd->m_metadata = p_nd->m_p_l_child == 0 ? 0 : 1 + p_nd->m_p_l_child->m_metadata; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_root_and_link(node_pointer p_nd) { make_root(p_nd); p_nd->m_p_prev_or_parent = 0; p_nd->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; update_max(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix(node_pointer p_y) { while (true) { if (p_y->m_p_prev_or_parent == 0) { fix_root(p_y); return; } else if (p_y->m_metadata == 1&& p_y->m_p_next_sibling == 0) { if (p_y->m_p_l_child != 0) { fix_sibling_rank_1_unmarked(p_y); return; } fix_sibling_rank_1_marked(p_y); p_y = p_y->m_p_prev_or_parent; } else if (p_y->m_metadata > p_y->m_p_next_sibling->m_metadata + 1) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child != 0); if (p_y->m_metadata != p_y->m_p_l_child->m_metadata + 2) { fix_sibling_general_unmarked(p_y); return; } fix_sibling_general_marked(p_y); p_y = p_y->m_p_prev_or_parent; } else if ((p_y->m_p_l_child == 0&& p_y->m_metadata == 2) ||(p_y->m_p_l_child != 0&& p_y->m_metadata == p_y->m_p_l_child->m_metadata + 3)) { node_pointer p_z = p_y->m_p_prev_or_parent; fix_child(p_y); p_y = p_z; } else return; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_root(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent == 0); make_root(p_y); PB_DS_ASSERT_NODE_CONSISTENT(p_y, true) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_rank_1_unmarked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); _GLIBCXX_DEBUG_ONLY(node_pointer p_w = p_y->m_p_l_child;) _GLIBCXX_DEBUG_ASSERT(p_w != 0); _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling == 0); _GLIBCXX_DEBUG_ASSERT(p_y->m_p_next_sibling == 0); p_y->m_p_next_sibling = p_y->m_p_l_child; p_y->m_p_next_sibling->m_p_prev_or_parent = p_y; p_y->m_p_l_child = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_rank_1_marked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child == 0); p_y->m_metadata = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_general_unmarked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); node_pointer p_w = p_y->m_p_l_child; _GLIBCXX_DEBUG_ASSERT(p_w != 0); _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != 0); p_y->m_p_l_child = p_w->m_p_next_sibling; p_w->m_p_next_sibling->m_p_prev_or_parent = p_y; p_w->m_p_next_sibling = p_y->m_p_next_sibling; _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != 0); p_w->m_p_next_sibling->m_p_prev_or_parent = p_w; p_y->m_p_next_sibling = p_w; p_w->m_p_prev_or_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_general_marked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); --p_y->m_metadata; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_child(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); if (p_y->m_p_next_sibling != 0) p_y->m_p_next_sibling->m_p_prev_or_parent = p_y->m_p_prev_or_parent; if (p_y->m_p_prev_or_parent->m_p_l_child == p_y) p_y->m_p_prev_or_parent->m_p_l_child = p_y->m_p_next_sibling; else p_y->m_p_prev_or_parent->m_p_next_sibling = p_y->m_p_next_sibling; make_root_and_link(p_y); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); const bool smaller = Cmp_Fn::operator()(r_new_val, p_nd->m_value); p_nd->m_value = r_new_val; if (smaller) { remove_node(p_nd); p_nd->m_p_l_child = 0; make_root_and_link(p_nd); PB_DS_ASSERT_VALID((*this)) return; } if (p_nd->m_p_prev_or_parent == 0) { update_max(p_nd); PB_DS_ASSERT_VALID((*this)) return; } node_pointer p_y = p_nd->m_p_prev_or_parent; _GLIBCXX_DEBUG_ASSERT(p_y != 0); if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_y; if (p_y->m_p_l_child == p_nd) p_y->m_p_l_child = p_nd->m_p_next_sibling; else p_y->m_p_next_sibling = p_nd->m_p_next_sibling; fix(p_y); make_root_and_link(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_max(node_pointer p_nd) { if (m_p_max == 0 || Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) m_p_max = p_nd; } PKgd1]. ,8/ext/pb_ds/detail/thin_heap_/thin_heap_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/thin_heap_.hpp * Contains an implementation class for a thin heap. */ #ifndef PB_DS_THIN_HEAP_HPP #define PB_DS_THIN_HEAP_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ thin_heap #ifdef _GLIBCXX_DEBUG #define PB_DS_BASE_T_P \ #else #define PB_DS_BASE_T_P \ #endif /** * Thin heap. * * @ingroup heap-detail * * See Tarjan and Kaplan. */ template class thin_heap : public left_child_next_sibling_heap PB_DS_BASE_T_P { private: typedef typename _Alloc::template rebind::other __rebind_a; typedef left_child_next_sibling_heap PB_DS_BASE_T_P base_type; protected: typedef typename base_type::node node; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_a::pointer pointer; typedef typename __rebind_a::const_pointer const_pointer; typedef typename __rebind_a::reference reference; typedef typename __rebind_a::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); inline void clear(); template size_type erase_if(Pred); template void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); protected: thin_heap(); thin_heap(const Cmp_Fn&); thin_heap(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~thin_heap(); template void copy_from_range(It, It); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_max(const char*, int) const; #endif #ifdef PB_DS_THIN_HEAP_TRACE_ void trace() const; #endif private: enum { max_rank = (sizeof(size_type) << 4) + 2 }; void initialize(); inline void update_max(node_pointer); inline void fix(node_pointer); inline void fix_root(node_pointer); inline void fix_sibling_rank_1_unmarked(node_pointer); inline void fix_sibling_rank_1_marked(node_pointer); inline void fix_sibling_general_unmarked(node_pointer); inline void fix_sibling_general_marked(node_pointer); inline void fix_child(node_pointer); inline static void make_root(node_pointer); inline void make_root_and_link(node_pointer); inline void remove_max_node(); void to_aux_except_max(); inline void add_to_aux(node_pointer); inline void make_from_aux(); inline size_type rank_bound(); inline void make_child_of(node_pointer, node_pointer); inline void remove_node(node_pointer); inline node_pointer join(node_pointer, node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_node_consistent(node_const_pointer, bool, const char*, int) const; void assert_aux_null(const char*, int) const; #endif node_pointer m_p_max; node_pointer m_a_aux[max_rank]; }; enum { num_distinct_rank_bounds = 48 }; // Taken from the SGI implementation; acknowledged in the docs. static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] = { /* Dealing cards... */ /* 0 */ 0ul, /* 1 */ 1ul, /* 2 */ 1ul, /* 3 */ 2ul, /* 4 */ 4ul, /* 5 */ 6ul, /* 6 */ 11ul, /* 7 */ 17ul, /* 8 */ 29ul, /* 9 */ 46ul, /* 10 */ 76ul, /* 11 */ 122ul, /* 12 */ 199ul, /* 13 */ 321ul, /* 14 */ 521ul, /* 15 */ 842ul, /* 16 */ 1364ul, /* 17 */ 2206ul, /* 18 */ 3571ul, /* 19 */ 5777ul, /* 20 */ 9349ul, /* 21 */ 15126ul, /* 22 */ 24476ul, /* 23 */ 39602ul, /* 24 */ 64079ul #if __SIZE_MAX__ > 0xfffful , /* 25 */ 103681ul, /* 26 */ 167761ul, /* 27 */ 271442ul, /* 28 */ 439204ul, /* 29 */ 710646ul #if __SIZE_MAX__ > 0xffffful , /* 30 */ 1149851ul, /* 31 */ 1860497ul, /* 32 */ 3010349ul, /* 33 */ 4870846ul, /* 34 */ 7881196ul, /* 35 */ 12752042ul #if __SIZE_MAX__ > 0xfffffful , /* 36 */ 20633239ul, /* 37 */ 33385282ul, /* 38 */ 54018521ul, /* 39 */ 87403803ul, /* 40 */ 141422324ul, /* 41 */ 228826127ul, /* 42 */ 370248451ul, /* 43 */ 599074578ul, /* 44 */ 969323029ul, /* 45 */ 1568397607ul, /* 46 */ 2537720636ul, /* 47 */ 4106118243ul #endif #endif #endif /* Pot's good, let's play */ }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #define PB_DS_ASSERT_AUX_NULL(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_aux_null(__FILE__, __LINE__);) #include #include #include #include #include #include #include #undef PB_DS_ASSERT_AUX_NULL #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_BASE_T_P } // namespace detail } // namespace __gnu_pbds #endif PKgd1]@d /8/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/erase_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); node_pointer p_nd = m_p_max; remove_max_node(); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: remove_max_node() { to_aux_except_max(); make_from_aux(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: to_aux_except_max() { node_pointer p_add = base_type::m_p_root; while (p_add != m_p_max) { node_pointer p_next_add = p_add->m_p_next_sibling; add_to_aux(p_add); p_add = p_next_add; } p_add = m_p_max->m_p_l_child; while (p_add != 0) { node_pointer p_next_add = p_add->m_p_next_sibling; p_add->m_metadata = p_add->m_p_l_child == 0 ? 0 : p_add->m_p_l_child->m_metadata + 1; add_to_aux(p_add); p_add = p_next_add; } p_add = m_p_max->m_p_next_sibling; while (p_add != 0) { node_pointer p_next_add = p_add->m_p_next_sibling; add_to_aux(p_add); p_add = p_next_add; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: add_to_aux(node_pointer p_nd) { size_type r = p_nd->m_metadata; while (m_a_aux[r] != 0) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value)) make_child_of(m_a_aux[r], p_nd); else { make_child_of(p_nd, m_a_aux[r]); p_nd = m_a_aux[r]; } m_a_aux[r] = 0; ++r; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); m_a_aux[r] = p_nd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_child_of(node_pointer p_nd, node_pointer p_new_parent) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata); _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd || m_a_aux[p_nd->m_metadata] == p_new_parent); ++p_new_parent->m_metadata; base_type::make_child_of(p_nd, p_new_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_from_aux() { base_type::m_p_root = m_p_max = 0; const size_type rnk_bnd = rank_bound(); size_type i = 0; while (i < rnk_bnd) { if (m_a_aux[i] != 0) { make_root_and_link(m_a_aux[i]); m_a_aux[i] = 0; } ++i; } PB_DS_ASSERT_AUX_NULL((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_nd) { node_pointer p_parent = p_nd; while (base_type::parent(p_parent) != 0) p_parent = base_type::parent(p_parent); base_type::bubble_to_top(p_nd); m_p_max = p_nd; node_pointer p_fix = base_type::m_p_root; while (p_fix != 0&& p_fix->m_p_next_sibling != p_parent) p_fix = p_fix->m_p_next_sibling; if (p_fix != 0) p_fix->m_p_next_sibling = p_nd; remove_max_node(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_p_max = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_nd = it.m_p_nd; remove_node(p_nd); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; m_p_max = base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; make_root_and_link(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: rank_bound() { using namespace std; const size_t* const p_upper = std::upper_bound(g_a_rank_bounds, g_a_rank_bounds + num_distinct_rank_bounds, base_type::m_size); if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds) return max_rank; return (p_upper - g_a_rank_bounds); } PKgd1]tS S 48/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/split_join_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; other.make_root_and_link(p_out); p_out = p_next; } PB_DS_ASSERT_VALID(other) node_pointer p_cur = base_type::m_p_root; m_p_max = 0; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; make_root_and_link(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) node_pointer p_other = other.m_p_root; while (p_other != 0) { node_pointer p_next = p_other->m_p_next_sibling; make_root_and_link(p_other); p_other = p_next; } base_type::m_size += other.m_size; other.m_p_root = 0; other.m_size = 0; other.m_p_max = 0; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1]px::>8/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/binomial_heap_base_.hpp * Contains an implementation class for a base of binomial heaps. */ #ifndef PB_DS_BINOMIAL_HEAP_BASE_HPP #define PB_DS_BINOMIAL_HEAP_BASE_HPP /* * Binomial heap base. * Vuillemin J is the mastah. * Modified from CLRS. */ #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ binomial_heap_base #ifdef _GLIBCXX_DEBUG #define PB_DS_B_HEAP_BASE \ left_child_next_sibling_heap #else #define PB_DS_B_HEAP_BASE \ left_child_next_sibling_heap #endif /// Base class for binomial heap. template class binomial_heap_base : public PB_DS_B_HEAP_BASE { private: typedef typename _Alloc::template rebind::other __rebind_v; typedef PB_DS_B_HEAP_BASE base_type; protected: typedef typename base_type::node node; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_v::pointer pointer; typedef typename __rebind_v::const_pointer const_pointer; typedef typename __rebind_v::reference reference; typedef typename __rebind_v::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; public: inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); inline void clear(); template size_type erase_if(Pred); template void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); protected: binomial_heap_base(); binomial_heap_base(const Cmp_Fn&); binomial_heap_base(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~binomial_heap_base(); template void copy_from_range(It, It); inline void find_max(); #ifdef _GLIBCXX_DEBUG void assert_valid(bool, const char*, int) const; void assert_max(const char*, int) const; #endif private: inline node_pointer fix(node_pointer) const; inline void insert_node(node_pointer); inline void remove_parentless_node(node_pointer); inline node_pointer join(node_pointer, node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_node_consistent(node_const_pointer, bool, bool, const char*, int) const; #endif protected: node_pointer m_p_max; }; #define PB_DS_ASSERT_VALID_COND(X, _StrictlyBinomial) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(_StrictlyBinomial,__FILE__, __LINE__);) #define PB_DS_ASSERT_BASE_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #include #include #include #include #include #include #undef PB_DS_ASSERT_BASE_NODE_CONSISTENT #undef PB_DS_ASSERT_VALID_COND #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_B_HEAP_BASE } // namespace detail } // namespace __gnu_pbds #endif PKgd1]ܮY J8/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/constructors_destructor_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base() : m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn), m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base(const PB_DS_CLASS_C_DEC& other) : base_type(other), m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),false) base_type::swap(other); std::swap(m_p_max, other.m_p_max); PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binomial_heap_base() { } PKgd1]; m-) ) 78/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/find_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID_COND((*this),false) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) const_cast(this)->find_max(); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); return m_p_max->m_value; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: find_max() { node_pointer p_cur = base_type::m_p_root; m_p_max = p_cur; while (p_cur != 0) { if (Cmp_Fn::operator()(m_p_max->m_value, p_cur->m_value)) m_p_max = p_cur; p_cur = p_cur->m_p_next_sibling; } } PKgd1]I 88/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/debug_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(bool strictly_binomial, const char* __file, int __line) const { base_type::assert_valid(__file, __line); assert_node_consistent(base_type::m_p_root, strictly_binomial, true, __file, __line); assert_max(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { if (m_p_max == 0) return; PB_DS_DEBUG_VERIFY(base_type::parent(m_p_max) == 0); for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool strictly_binomial, bool increasing, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(increasing || strictly_binomial); base_type::assert_node_consistent(p_nd, false, __file, __line); if (p_nd == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_metadata == base_type::degree(p_nd)); PB_DS_DEBUG_VERIFY(base_type::size_under_node(p_nd) == static_cast(1 << p_nd->m_metadata)); assert_node_consistent(p_nd->m_p_next_sibling, strictly_binomial, increasing, __file, __line); assert_node_consistent(p_nd->m_p_l_child, true, false, __file, __line); if (p_nd->m_p_next_sibling != 0) { if (increasing) { if (strictly_binomial) PB_DS_DEBUG_VERIFY(p_nd->m_metadata < p_nd->m_p_next_sibling->m_metadata); else PB_DS_DEBUG_VERIFY(p_nd->m_metadata <= p_nd->m_p_next_sibling->m_metadata); } else PB_DS_DEBUG_VERIFY(p_nd->m_metadata > p_nd->m_p_next_sibling->m_metadata); } } #endif PKgd1]Ca98/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/insert_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID_COND((*this),true) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); insert_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_node(node_pointer p_nd) { if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = 0; p_nd->m_p_prev_or_parent = 0; p_nd->m_p_l_child = 0; p_nd->m_metadata = 0; base_type::m_p_root = p_nd; return; } if (base_type::m_p_root->m_metadata > 0) { p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = 0; p_nd->m_p_next_sibling = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root = p_nd; p_nd->m_metadata = 0; return; } if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) { p_nd->m_p_next_sibling = base_type::m_p_root->m_p_next_sibling; p_nd->m_p_prev_or_parent = 0; p_nd->m_metadata = 1; p_nd->m_p_l_child = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root->m_p_next_sibling = 0; base_type::m_p_root = p_nd; } else { p_nd->m_p_next_sibling = 0; p_nd->m_p_l_child = 0; p_nd->m_p_prev_or_parent = base_type::m_p_root; p_nd->m_metadata = 0; _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root->m_p_l_child == 0); base_type::m_p_root->m_p_l_child = p_nd; base_type::m_p_root->m_metadata = 1; } base_type::m_p_root = fix(base_type::m_p_root); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: fix(node_pointer p_nd) const { while (p_nd->m_p_next_sibling != 0 && p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata) { node_pointer p_next = p_nd->m_p_next_sibling; if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; if (p_nd->m_p_prev_or_parent != 0) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_next; base_type::make_child_of(p_nd, p_next); ++p_next->m_metadata; p_nd = p_next; } else { p_nd->m_p_next_sibling = p_next->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_next->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); ++p_nd->m_metadata; } } if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; return p_nd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID_COND((*this),true) node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd, false) const bool bubble_up = Cmp_Fn::operator()(p_nd->m_value, r_new_val); p_nd->m_value = r_new_val; if (bubble_up) { node_pointer p_parent = base_type::parent(p_nd); while (p_parent != 0 && Cmp_Fn::operator()(p_parent->m_value, p_nd->m_value)) { base_type::swap_with_parent(p_nd, p_parent); p_parent = base_type::parent(p_nd); } if (p_nd->m_p_prev_or_parent == 0) base_type::m_p_root = p_nd; m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return; } base_type::bubble_to_top(p_nd); remove_parentless_node(p_nd); insert_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PKgd1]Dd88/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/erase_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) find_max(); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); node_pointer p_nd = m_p_max; remove_parentless_node(m_p_max); base_type::actual_erase_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_parentless_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(base_type::parent(p_nd) == 0); node_pointer p_cur_root = p_nd == base_type::m_p_root? p_nd->m_p_next_sibling : base_type::m_p_root; if (p_cur_root != 0) p_cur_root->m_p_prev_or_parent = 0; if (p_nd->m_p_prev_or_parent != 0) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; node_pointer p_child = p_nd->m_p_l_child; if (p_child != 0) { p_child->m_p_prev_or_parent = 0; while (p_child->m_p_next_sibling != 0) p_child = p_child->m_p_next_sibling; } m_p_max = 0; base_type::m_p_root = join(p_cur_root, p_child); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_p_max = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::bubble_to_top(it.m_p_nd); remove_parentless_node(it.m_p_nd); base_type::actual_erase_node(it.m_p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID_COND((*this),true) if (base_type::empty()) { PB_DS_ASSERT_VALID_COND((*this),true) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0; p_cur->m_metadata = 0; p_cur->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_cur; base_type::m_p_root = p_cur; base_type::m_p_root = fix(base_type::m_p_root); p_cur = p_next; } m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return ersd; } PKgd1]V =8/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/split_join_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; p_out->m_p_l_child = p_out->m_p_prev_or_parent = 0; p_out->m_metadata = 0; p_out->m_p_next_sibling = other.m_p_root; if (other.m_p_root != 0) other.m_p_root->m_p_prev_or_parent = p_out; other.m_p_root = p_out; other.m_p_root = other.fix(other.m_p_root); p_out = p_next; } PB_DS_ASSERT_VALID_COND(other,true) node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0; p_cur->m_metadata = 0; p_cur->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_cur; base_type::m_p_root = p_cur; base_type::m_p_root = fix(base_type::m_p_root); p_cur = p_next; } m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) node_pointer p_other = other.m_p_root; if (p_other != 0) do { node_pointer p_next = p_other->m_p_next_sibling; std::swap(p_other->m_p_next_sibling, p_other->m_p_prev_or_parent); p_other = p_next; } while (p_other != 0); base_type::m_p_root = join(base_type::m_p_root, other.m_p_root); base_type::m_size += other.m_size; m_p_max = 0; other.m_p_root = 0; other.m_size = 0; other.m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: join(node_pointer p_lhs, node_pointer p_rhs) const { node_pointer p_ret = 0; node_pointer p_cur = 0; while (p_lhs != 0 || p_rhs != 0) { if (p_rhs == 0) { if (p_cur == 0) p_ret = p_cur = p_lhs; else { p_cur->m_p_next_sibling = p_lhs; p_lhs->m_p_prev_or_parent = p_cur; } p_cur = p_lhs = 0; } else if (p_lhs == 0 || p_rhs->m_metadata < p_lhs->m_metadata) { if (p_cur == 0) { p_ret = p_cur = p_rhs; p_rhs = p_rhs->m_p_prev_or_parent; } else { p_cur->m_p_next_sibling = p_rhs; p_rhs = p_rhs->m_p_prev_or_parent; p_cur->m_p_next_sibling->m_p_prev_or_parent = p_cur; p_cur = p_cur->m_p_next_sibling; } } else if (p_lhs->m_metadata < p_rhs->m_metadata) { if (p_cur == 0) p_ret = p_cur = p_lhs; else { p_cur->m_p_next_sibling = p_lhs; p_lhs->m_p_prev_or_parent = p_cur; p_cur = p_cur->m_p_next_sibling; } p_lhs = p_cur->m_p_next_sibling; } else { node_pointer p_next_rhs = p_rhs->m_p_prev_or_parent; p_rhs->m_p_next_sibling = p_lhs; p_lhs = fix(p_rhs); p_rhs = p_next_rhs; } } if (p_cur != 0) p_cur->m_p_next_sibling = 0; if (p_ret != 0) p_ret->m_p_prev_or_parent = 0; return p_ret; } PKgd1]Uc,,38/ext/pb_ds/detail/priority_queue_base_dispatch.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/priority_queue_base_dispatch.hpp * Contains an pqiative container dispatching base. */ #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP #define PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #include #include #include #include #include #undef PB_DS_DEBUG_VERIFY #undef PB_DS_ASSERT_VALID namespace __gnu_pbds { namespace detail { /// Specialization for pairing_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, pairing_heap_tag, null_type> { /// Dispatched type. typedef pairing_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for binomial_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, binomial_heap_tag, null_type> { /// Dispatched type. typedef binomial_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for rc_binary_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, rc_binomial_heap_tag, null_type> { /// Dispatched type. typedef rc_binomial_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for binary_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, binary_heap_tag, null_type> { /// Dispatched type. typedef binary_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for thin_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, thin_heap_tag, null_type> { /// Dispatched type. typedef thin_heap<_VTp, Cmp_Fn, _Alloc> type; }; //@} group pbds } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP PKgd1]%!!%8/ext/pb_ds/detail/debug_map_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/debug_map_base.hpp * Contains a debug-mode base for all maps. */ #ifndef PB_DS_DEBUG_MAP_BASE_HPP #define PB_DS_DEBUG_MAP_BASE_HPP #ifdef _GLIBCXX_DEBUG #include #include #include #include #include #include namespace __gnu_pbds { namespace detail { // Need std::pair ostream extractor. template inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __out, const std::pair<_Tp1, _Tp2>& p) { return (__out << '(' << p.first << ',' << p.second << ')'); } #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ debug_map_base /// Debug base class. template class debug_map_base { private: typedef Const_Key_Reference key_const_reference; typedef std::_GLIBCXX_STD_C::list key_repository; typedef typename key_repository::size_type size_type; typedef typename key_repository::iterator iterator; typedef typename key_repository::const_iterator const_iterator; protected: debug_map_base(); debug_map_base(const PB_DS_CLASS_C_DEC&); ~debug_map_base(); inline void insert_new(key_const_reference); inline void erase_existing(key_const_reference); void clear(); inline void check_key_exists(key_const_reference, const char*, int) const; inline void check_key_does_not_exist(key_const_reference, const char*, int) const; inline void check_size(size_type, const char*, int) const; void swap(PB_DS_CLASS_C_DEC&); template void split(key_const_reference, Cmp_Fn, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&, bool with_cleanup = true); private: void assert_valid(const char*, int) const; const_iterator find(key_const_reference) const; iterator find(key_const_reference); key_repository m_keys; Eq_Fn m_eq; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: debug_map_base() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: debug_map_base(const PB_DS_CLASS_C_DEC& other) : m_keys(other.m_keys), m_eq(other.m_eq) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~debug_map_base() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_new(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) if (find(r_key) != m_keys.end()) { std::cerr << "insert_new key already present " << r_key << std::endl; std::abort(); } __try { m_keys.push_back(r_key); } __catch(...) { std::cerr << "insert_new " << r_key << std::endl; std::abort(); } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_existing(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator it = find(r_key); if (it == m_keys.end()) { std::cerr << "erase_existing" << r_key << std::endl; std::abort(); } m_keys.erase(it); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_ASSERT_VALID((*this)) m_keys.clear(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_key_exists(key_const_reference r_key, const char* __file, int __line) const { assert_valid(__file, __line); if (find(r_key) == m_keys.end()) { std::cerr << __file << ':' << __line << ": check_key_exists " << r_key << std::endl; std::abort(); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_key_does_not_exist(key_const_reference r_key, const char* __file, int __line) const { assert_valid(__file, __line); if (find(r_key) != m_keys.end()) { using std::cerr; using std::endl; cerr << __file << ':' << __line << ": check_key_does_not_exist " << r_key << endl; std::abort(); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_size(size_type size, const char* __file, int __line) const { assert_valid(__file, __line); const size_type keys_size = m_keys.size(); if (size != keys_size) { std::cerr << __file << ':' << __line << ": check_size " << size << " != " << keys_size << std::endl; std::abort(); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) m_keys.swap(other.m_keys); std::swap(m_eq, other.m_eq); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) typedef const_iterator iterator_type; for (iterator_type it = m_keys.begin(); it != m_keys.end(); ++it) if (m_eq(*it, r_key)) return it; return m_keys.end(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator it = m_keys.begin(); while (it != m_keys.end()) { if (m_eq(*it, r_key)) return it; ++it; } return it; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { const_iterator prime_it = m_keys.begin(); while (prime_it != m_keys.end()) { const_iterator sec_it = prime_it; ++sec_it; while (sec_it != m_keys.end()) { PB_DS_DEBUG_VERIFY(!m_eq(*sec_it, *prime_it)); PB_DS_DEBUG_VERIFY(!m_eq(*prime_it, *sec_it)); ++sec_it; } ++prime_it; } } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, Cmp_Fn cmp_fn, PB_DS_CLASS_C_DEC& other) { other.clear(); iterator it = m_keys.begin(); while (it != m_keys.end()) if (cmp_fn(r_key, *it)) { other.insert_new(*it); it = m_keys.erase(it); } else ++it; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other, bool with_cleanup) { iterator it = other.m_keys.begin(); while (it != other.m_keys.end()) { insert_new(*it); if (with_cleanup) it = other.m_keys.erase(it); else ++it; } _GLIBCXX_DEBUG_ASSERT(!with_cleanup || other.m_keys.empty()); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif #endif PKgd1]C~==88/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: do_resize_if_needed() { if (!resize_base::is_resize_needed()) return false; resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type n) { resize_imp(resize_base::get_nearest_larger_size(n)); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: do_resize_if_needed_no_throw() { if (!resize_base::is_resize_needed()) return; __try { resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); } __catch(...) { } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(size_type new_size) { #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_num_e); #endif if (new_size == m_num_e) return; PB_DS_ASSERT_VALID((*this)) const size_type old_size = m_num_e; entry_array a_entries_resized = 0; // Following line might throw an exception. a_entries_resized = s_entry_allocator.allocate(new_size); ranged_probe_fn_base::notify_resized(new_size); m_num_e = new_size; for (size_type i = 0; i < m_num_e; ++i) a_entries_resized[i].m_stat = empty_entry_status; __try { resize_imp(a_entries_resized, old_size); } __catch(...) { erase_all_valid_entries(a_entries_resized, new_size); m_num_e = old_size; s_entry_allocator.deallocate(a_entries_resized, new_size); ranged_probe_fn_base::notify_resized(old_size); __throw_exception_again; } // At this point no exceptions can be thrown. _GLIBCXX_DEBUG_ONLY(assert_entry_array_valid(a_entries_resized, traits_base::m_store_extra_indicator, __FILE__, __LINE__);) Resize_Policy::notify_resized(new_size); erase_all_valid_entries(m_entries, old_size); s_entry_allocator.deallocate(m_entries, old_size); m_entries = a_entries_resized; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(entry_array a_entries_resized, size_type old_size) { for (size_type pos = 0; pos < old_size; ++pos) if (m_entries[pos].m_stat == valid_entry_status) resize_imp_reassign(m_entries + pos, a_entries_resized, traits_base::m_store_extra_indicator); } #include #include PKgd1]A^: : F8/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions, when the * hash value is not stored. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, false_type) { key_const_reference r_key = PB_DS_V2F(p_e->m_value); size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry_pointer p_new_e = a_entries_resized + pos; switch(p_new_e->m_stat) { case empty_entry_status: new (&p_new_e->m_value) value_type(p_e->m_value); p_new_e->m_stat = valid_entry_status; return; case erased_entry_status: _GLIBCXX_DEBUG_ASSERT(0); break; case valid_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; } __throw_insert_error(); } PKgd1]E E E8/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_imp(key_const_reference r_key, false_type) { PB_DS_ASSERT_VALID((*this)) size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; resize_base::notify_erase_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_erase_search_end(); erase_entry(p_e); do_resize_if_needed_no_throw(); return true; } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_erase_search_collision(); } resize_base::notify_erase_search_end(); return false; } PKgd1]!F8/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: find_ins_pos(key_const_reference r_key, false_type) { size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; /* The insertion position is initted to a non-legal value to indicate * that it has not been initted yet. */ size_type ins_pos = m_num_e; resize_base::notify_insert_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); _GLIBCXX_DEBUG_ASSERT(pos < m_num_e); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return (ins_pos == m_num_e) ? pos : ins_pos; } break; case erased_entry_status: if (ins_pos == m_num_e) ins_pos = pos; break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) return pos; } break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_insert_search_collision(); } resize_base::notify_insert_search_end(); if (ins_pos == m_num_e) __throw_insert_error(); return ins_pos; } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, false_type) { key_const_reference r_key = PB_DS_V2F(r_val); const size_type pos = find_ins_pos(r_key, traits_base::m_store_extra_indicator); if (m_entries[pos].m_stat == valid_entry_status) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&(m_entries + pos)->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos), true); } PKgd1](x x 78/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/trace_fn_imps.hpp * Contains implementations of gp_ht_map_'s trace-mode functions. */ #ifdef PB_DS_HT_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << static_cast(m_num_e) << " " << static_cast(m_num_used_e) << std::endl; for (size_type i = 0; i < m_num_e; ++i) { std::cerr << static_cast(i) << " "; switch(m_entries[i].m_stat) { case empty_entry_status: std::cerr << ""; break; case erased_entry_status: std::cerr << ""; break; case valid_entry_status: std::cerr << PB_DS_V2F(m_entries[i].m_value); break; default: _GLIBCXX_DEBUG_ASSERT(0); }; std::cerr << std::endl; } } #endif // #ifdef PB_DS_HT_MAP_TRACE_ PKgd1]57H8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME() : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1)), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn) : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& r_comb_hash_fn) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, comb_hash_fn, prober), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober, const Resize_Policy& r_resize_policy) : hash_eq_fn_base(r_eq_fn), resize_base(r_resize_policy), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, comb_hash_fn, prober), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif hash_eq_fn_base(other), resize_base(other), ranged_probe_fn_base(other), m_num_e(other.m_num_e), m_num_used_e(other.m_num_used_e), m_entries(s_entry_allocator.allocate(m_num_e)) { for (size_type i = 0; i < m_num_e; ++i) m_entries[i].m_stat = (entry_status)empty_entry_status; __try { for (size_type i = 0; i < m_num_e; ++i) { m_entries[i].m_stat = other.m_entries[i].m_stat; if (m_entries[i].m_stat == valid_entry_status) new (m_entries + i) entry(other.m_entries[i]); } } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_GP_HASH_NAME() { deallocate_all(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) std::swap(m_num_e, other.m_num_e); std::swap(m_num_used_e, other.m_num_used_e); std::swap(m_entries, other.m_entries); ranged_probe_fn_base::swap(other); hash_eq_fn_base::swap(other); resize_base::swap(other); _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { clear(); erase_all_valid_entries(m_entries, m_num_e); s_entry_allocator.deallocate(m_entries, m_num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_all_valid_entries(entry_array a_entries_resized, size_type len) { for (size_type pos = 0; pos < len; ++pos) { entry_pointer p_e = &a_entries_resized[pos]; if (p_e->m_stat == valid_entry_status) p_e->m_value.~value_type(); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { Resize_Policy::notify_resized(m_num_e); Resize_Policy::notify_cleared(); ranged_probe_fn_base::notify_resized(m_num_e); for (size_type i = 0; i < m_num_e; ++i) m_entries[i].m_stat = empty_entry_status; } PKgd1]Od d ?8/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/policy_access_fn_imps.hpp * Contains implementations of gp_ht_map_'s policy agpess * functions. */ PB_DS_CLASS_T_DEC Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() { return *this; } PB_DS_CLASS_T_DEC const Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() const { return *this; } PB_DS_CLASS_T_DEC Probe_Fn& PB_DS_CLASS_C_DEC:: get_probe_fn() { return *this; } PB_DS_CLASS_T_DEC const Probe_Fn& PB_DS_CLASS_C_DEC:: get_probe_fn() const { return *this; } PB_DS_CLASS_T_DEC Comb_Probe_Fn& PB_DS_CLASS_C_DEC:: get_comb_probe_fn() { return *this; } PB_DS_CLASS_T_DEC const Comb_Probe_Fn& PB_DS_CLASS_C_DEC:: get_comb_probe_fn() const { return *this; } PB_DS_CLASS_T_DEC Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() { return *this; } PB_DS_CLASS_T_DEC const Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() const { return *this; } PKgd1]$A8/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions, * when the hash value is stored. */ PKgd1]:<<68/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/info_fn_imps.hpp * Contains implementations of gp_ht_map_'s entire container info related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PKgd1]H09 68/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) return const_cast(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find_end() { return 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find_end() const { return 0; } PKgd1] ńD8/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::pointer PB_DS_CLASS_C_DEC:: find_key_pointer(key_const_reference r_key, false_type) PKgd1]ä; ; :8/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/iterator_fn_imps.hpp * Contains implementations of gp_ht_map_'s iterators related functions, e.g., * begin(). */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC::s_end_it; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC::s_const_end_it; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { pointer_ p_value; size_type pos; get_start_it_state(p_value, pos); return iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return s_end_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { const_pointer_ p_value; size_type pos; get_start_it_state(p_value, pos); return const_iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return s_const_end_it; } PKgd1]!S8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, true_type) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); entry* const p_e = m_entries + pos; new (&p_e->m_value) mapped_value_type(r_val); p_e->m_hash = ranged_probe_fn_base::operator()(PB_DS_V2F(r_val)).second; p_e->m_stat = valid_entry_status; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(p_e->m_value.first);) } PKgd1]P߂~~78/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { debug_base::check_size(m_num_used_e, __file, __line); assert_entry_array_valid(m_entries, traits_base::m_store_extra_indicator, __file, __line); } #include #include #endif PKgd1]Fhh88/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions. */ #include #include PKgd1]vjEOO48/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/gp_ht_map_.hpp * Contains an implementation class for general probing hash. */ #include #include #include #include #include #include #ifdef PB_DS_HT_MAP_TRACE_ #include #endif #ifdef _GLIBCXX_DEBUG #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_GP_HASH_NAME gp_ht_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_GP_HASH_NAME gp_ht_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_GP_HASH_NAME #define PB_DS_HASH_EQ_FN_C_DEC \ hash_eq_fn #define PB_DS_RANGED_PROBE_FN_C_DEC \ ranged_probe_fn #define PB_DS_GP_HASH_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base::other::const_reference> #endif /** * A general-probing hash-based container. * * * @ingroup hash-detail * * @tparam Key Key type. * * @tparam Mapped Map type. * * @tparam Hash_Fn Hashing functor. * Default is __gnu_cxx::hash. * * @tparam Eq_Fn Equal functor. * Default std::equal_to * * @tparam _Alloc Allocator type. * * @tparam Store_Hash If key type stores extra metadata. * Defaults to false. * * @tparam Comb_Probe_Fn Combining probe functor. * If Hash_Fn is not null_type, then this * is the ranged-probe functor; otherwise, * this is the range-hashing functor. * XXX See Design::Hash-Based Containers::Hash Policies. * Default direct_mask_range_hashing. * * @tparam Probe_Fn Probe functor. * Defaults to linear_probe_fn, * also quadratic_probe_fn. * * @tparam Resize_Policy Resizes hash. * Defaults to hash_standard_resize_policy, * using hash_exponential_size_policy and * hash_load_check_resize_trigger. * * * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_probe_fn, * detail::types_traits. (Optional: detail::debug_map_base.) */ template class PB_DS_GP_HASH_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_HASH_EQ_FN_C_DEC, public Resize_Policy, public PB_DS_RANGED_PROBE_FN_C_DEC, public PB_DS_GP_HASH_TRAITS_BASE { private: typedef PB_DS_GP_HASH_TRAITS_BASE traits_base; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; typedef typename traits_base::comp_hash comp_hash; enum entry_status { empty_entry_status, valid_entry_status, erased_entry_status } __attribute__ ((__packed__)); struct entry : public traits_base::stored_data_type { entry_status m_stat; }; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename entry_allocator::pointer entry_array; typedef PB_DS_RANGED_PROBE_FN_C_DEC ranged_probe_fn_base; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; typedef Resize_Policy resize_base; #define PB_DS_GEN_POS typename _Alloc::size_type #include #include #include #include #undef PB_DS_GEN_POS public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Probe_Fn probe_fn; typedef Comb_Probe_Fn comb_probe_fn; typedef Resize_Policy resize_policy; /// Value stores hash, true or false. enum { store_hash = Store_Hash }; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; PB_DS_GP_HASH_NAME(); PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC&); PB_DS_GP_HASH_NAME(const Hash_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, const Probe_Fn&, const Resize_Policy&); template void copy_from_range(It, It); virtual ~PB_DS_GP_HASH_NAME(); void swap(PB_DS_CLASS_C_DEC&); inline size_type size() const; inline size_type max_size() const; /// True if size() == 0. inline bool empty() const; /// Return current hash_fn. Hash_Fn& get_hash_fn(); /// Return current const hash_fn. const Hash_Fn& get_hash_fn() const; /// Return current eq_fn. Eq_Fn& get_eq_fn(); /// Return current const eq_fn. const Eq_Fn& get_eq_fn() const; /// Return current probe_fn. Probe_Fn& get_probe_fn(); /// Return current const probe_fn. const Probe_Fn& get_probe_fn() const; /// Return current comb_probe_fn. Comb_Probe_Fn& get_comb_probe_fn(); /// Return current const comb_probe_fn. const Comb_Probe_Fn& get_comb_probe_fn() const; /// Return current resize_policy. Resize_Policy& get_resize_policy(); /// Return current const resize_policy. const Resize_Policy& get_resize_policy() const; inline std::pair insert(const_reference r_val) { _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid(__FILE__, __LINE__);) return insert_imp(r_val, traits_base::m_store_extra_indicator); } inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return subscript_imp(r_key, traits_base::m_store_extra_indicator); #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator find_end(); inline point_const_iterator find_end() const; inline bool erase(key_const_reference); template inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace() const; #endif private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; void deallocate_all(); void initialize(); void erase_all_valid_entries(entry_array, size_type); inline bool do_resize_if_needed(); inline void do_resize_if_needed_no_throw(); void resize_imp(size_type); virtual void do_resize(size_type); void resize_imp(entry_array, size_type); inline void resize_imp_reassign(entry_pointer, entry_array, false_type); inline void resize_imp_reassign(entry_pointer, entry_array, true_type); inline size_type find_ins_pos(key_const_reference, false_type); inline comp_hash find_ins_pos(key_const_reference, true_type); inline std::pair insert_imp(const_reference, false_type); inline std::pair insert_imp(const_reference, true_type); inline pointer insert_new_imp(const_reference r_val, size_type pos) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); if (do_resize_if_needed()) pos = find_ins_pos(PB_DS_V2F(r_val), traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); entry* const p_e = m_entries + pos; new (&p_e->m_value) value_type(r_val); p_e->m_stat = valid_entry_status; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) { _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != valid_entry_status); if (do_resize_if_needed()) r_pos_hash_pair = find_ins_pos(PB_DS_V2F(r_val), traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != valid_entry_status); entry* const p_e = m_entries + r_pos_hash_pair.first; new (&p_e->m_value) value_type(r_val); p_e->m_hash = r_pos_hash_pair.second; p_e->m_stat = valid_entry_status; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } #ifdef PB_DS_DATA_TRUE_INDICATOR inline mapped_reference subscript_imp(key_const_reference key, false_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) const size_type pos = find_ins_pos(key, traits_base::m_store_extra_indicator); entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat != valid_entry_status) return insert_new_imp(value_type(key, mapped_type()), pos)->second; PB_DS_CHECK_KEY_EXISTS(key) return p_e->m_value.second; } inline mapped_reference subscript_imp(key_const_reference key, true_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) comp_hash pos_hash_pair = find_ins_pos(key, traits_base::m_store_extra_indicator); if (m_entries[pos_hash_pair.first].m_stat != valid_entry_status) return insert_new_imp(value_type(key, mapped_type()), pos_hash_pair)->second; PB_DS_CHECK_KEY_EXISTS(key) return (m_entries + pos_hash_pair.first)->m_value.second; } #endif inline pointer find_key_pointer(key_const_reference key, false_type) { const size_type hash = ranged_probe_fn_base::operator()(key); resize_base::notify_find_search_start(); // Loop until entry is found or until all possible entries accessed. for (size_type i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(key, hash, i); entry* const p_e = m_entries + pos; switch (p_e->m_stat) { case empty_entry_status: { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return 0; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), key)) { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_EXISTS(key) return pointer(&p_e->m_value); } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_find_search_collision(); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) resize_base::notify_find_search_end(); return 0; } inline pointer find_key_pointer(key_const_reference key, true_type) { comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(key); resize_base::notify_find_search_start(); // Loop until entry is found or until all possible entries accessed. for (size_type i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return 0; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, key, pos_hash_pair.second)) { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_EXISTS(key) return pointer(&p_e->m_value); } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_find_search_collision(); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) resize_base::notify_find_search_end(); return 0; } inline bool erase_imp(key_const_reference, true_type); inline bool erase_imp(key_const_reference, false_type); inline void erase_entry(entry_pointer); #ifdef PB_DS_DATA_TRUE_INDICATOR void inc_it_state(pointer& r_p_value, size_type& r_pos) const { inc_it_state((mapped_const_pointer& )r_p_value, r_pos); } #endif void inc_it_state(const_pointer& r_p_value, size_type& r_pos) const { _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); for (++r_pos; r_pos < m_num_e; ++r_pos) { const_entry_pointer p_e =& m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value =& p_e->m_value; return; } } r_p_value = 0; } void get_start_it_state(const_pointer& r_p_value, size_type& r_pos) const { for (r_pos = 0; r_pos < m_num_e; ++r_pos) { const_entry_pointer p_e = &m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value = &p_e->m_value; return; } } r_p_value = 0; } void get_start_it_state(pointer& r_p_value, size_type& r_pos) { for (r_pos = 0; r_pos < m_num_e; ++r_pos) { entry_pointer p_e = &m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value = &p_e->m_value; return; } } r_p_value = 0; } #ifdef _GLIBCXX_DEBUG void assert_entry_array_valid(const entry_array, false_type, const char*, int) const; void assert_entry_array_valid(const entry_array, true_type, const char*, int) const; #endif static entry_allocator s_entry_allocator; static iterator s_end_it; static const_iterator s_const_end_it; size_type m_num_e; size_type m_num_used_e; entry_pointer m_entries; enum { store_hash_ok = !Store_Hash || !is_same::value }; PB_DS_STATIC_ASSERT(sth, store_hash_ok); }; #include #include #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_HASH_EQ_FN_C_DEC #undef PB_DS_RANGED_PROBE_FN_C_DEC #undef PB_DS_GP_HASH_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_GP_HASH_NAME } // namespace detail } // namespace __gnu_pbds PKgd1][ 78/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_entry(entry_pointer p_e) { _GLIBCXX_DEBUG_ASSERT(p_e->m_stat = valid_entry_status); _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_e->m_value));) p_e->m_value.~value_type(); p_e->m_stat = erased_entry_status; _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); resize_base::notify_erased(--m_num_used_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat == valid_entry_status) erase_entry(p_e); } do_resize_if_needed_no_throw(); resize_base::notify_cleared(); } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat == valid_entry_status) if (pred(p_e->m_value)) { ++num_ersd; erase_entry(p_e); } } do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { return erase_imp(r_key, traits_base::m_store_extra_indicator); } #include #include PKgd1]m E8/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_array_valid(const entry_array a_entries, false_type, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { const_entry_pointer p_e = &a_entries[pos]; switch(p_e->m_stat) { case empty_entry_status: case erased_entry_status: break; case valid_entry_status: { key_const_reference r_key = PB_DS_V2F(p_e->m_value); debug_base::check_key_exists(r_key, __file, __line); ++iterated_num_used_e; break; } default: PB_DS_DEBUG_VERIFY(0); }; } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #endif PKgd1]6'[ [ C8/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions, when the * hash value is stored. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, true_type) { key_const_reference r_key = PB_DS_V2F(p_e->m_value); size_type hash = ranged_probe_fn_base::operator()(r_key, p_e->m_hash); size_type i; for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry_pointer p_new_e = a_entries_resized + pos; switch(p_new_e->m_stat) { case empty_entry_status: new (&p_new_e->m_value) value_type(p_e->m_value); p_new_e->m_hash = hash; p_new_e->m_stat = valid_entry_status; return; case erased_entry_status: _GLIBCXX_DEBUG_ASSERT(0); break; case valid_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; } __throw_insert_error(); } PKgd1]pC8/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: find_ins_pos(key_const_reference r_key, true_type) { PB_DS_ASSERT_VALID((*this)) comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); size_type i; /* The insertion position is initted to a non-legal value to indicate * that it has not been initted yet. */ size_type ins_pos = m_num_e; resize_base::notify_insert_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return ((ins_pos == m_num_e) ? std::make_pair(pos, pos_hash_pair.second) : std::make_pair(ins_pos, pos_hash_pair.second)); } break; case erased_entry_status: if (ins_pos == m_num_e) ins_pos = pos; break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(pos, pos_hash_pair.second); } break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_insert_search_collision(); } resize_base::notify_insert_search_end(); if (ins_pos == m_num_e) __throw_insert_error(); return std::make_pair(ins_pos, pos_hash_pair.second); } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, true_type) { key_const_reference r_key = PB_DS_V2F(r_val); comp_hash pos_hash_pair = find_ins_pos(r_key, traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(pos_hash_pair.first < m_num_e); entry_pointer p_e =& m_entries[pos_hash_pair.first]; if (p_e->m_stat == valid_entry_status) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); } PKgd1]ޝU U B8/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_array_valid(const entry_array a_entries, true_type, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { const_entry_pointer p_e =& a_entries[pos]; switch(p_e->m_stat) { case empty_entry_status: case erased_entry_status: break; case valid_entry_status: { key_const_reference r_key = PB_DS_V2F(p_e->m_value); debug_base::check_key_exists(r_key, __file, __line); const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); PB_DS_DEBUG_VERIFY(p_e->m_hash == pos_hash_pair.second); ++iterated_num_used_e; break; } default: PB_DS_DEBUG_VERIFY(0); }; } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #endif PKgd1]CV8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, false_type) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status)k; entry* const p_e = m_entries + pos; new (&p_e->m_value) mapped_value_type(r_val); p_e->m_stat = valid_entry_status; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(p_e->m_value.first);) } PKgd1];|g g B8/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_imp(key_const_reference r_key, true_type) { const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); size_type i; resize_base::notify_erase_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_erase_search_end(); erase_entry(p_e); do_resize_if_needed_no_throw(); return true; } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_erase_search_collision(); } resize_base::notify_erase_search_end(); return false; } PKgd1]eTpp68/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/trace_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { base_type::trace(); m_rc.trace(); } #endif // #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ PKgd1]e H8/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { make_binomial_heap(); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~rc_binomial_heap() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) base_type::swap(other); m_rc.swap(other.m_rc); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1] 68/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/debug_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(false, __file, __line); if (!base_type::empty()) { PB_DS_DEBUG_VERIFY(base_type::m_p_max != 0); base_type::assert_max(__file, __line); } m_rc.assert_valid(__file, __line); if (m_rc.empty()) { base_type::assert_valid(true, __file, __line); PB_DS_DEBUG_VERIFY(next_2_pointer(base_type::m_p_root) == 0); return; } node_const_pointer p_nd = next_2_pointer(base_type::m_p_root); typename rc_t::const_iterator it = m_rc.end(); --it; while (p_nd != 0) { PB_DS_DEBUG_VERIFY(*it == p_nd); node_const_pointer p_next = p_nd->m_p_next_sibling; PB_DS_DEBUG_VERIFY(p_next != 0); PB_DS_DEBUG_VERIFY(p_nd->m_metadata == p_next->m_metadata); PB_DS_DEBUG_VERIFY(p_next->m_p_next_sibling == 0 || p_next->m_metadata < p_next->m_p_next_sibling->m_metadata); --it; p_nd = next_2_pointer(next_after_0_pointer(p_nd)); } PB_DS_DEBUG_VERIFY(it + 1 == m_rc.begin()); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: next_2_pointer(node_const_pointer p_nd) { if (p_nd == 0) return 0; node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) return 0; if (p_nd->m_metadata == p_next->m_metadata) return p_nd; return next_2_pointer(p_next); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: next_after_0_pointer(node_const_pointer p_nd) { if (p_nd == 0) return 0; node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) return 0; if (p_nd->m_metadata < p_next->m_metadata) return p_next; return next_after_0_pointer(p_next); } #endif PKgd1]Ep78/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/insert_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) make_0_exposed(); PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); p_nd->m_p_l_child = p_nd->m_p_prev_or_parent = 0; p_nd->m_metadata = 0; if (base_type::m_p_max == 0 || Cmp_Fn::operator()(base_type::m_p_max->m_value, r_val)) base_type::m_p_max = p_nd; p_nd->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root = p_nd; if (p_nd->m_p_next_sibling != 0&& p_nd->m_p_next_sibling->m_metadata == 0) m_rc.push(p_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) make_binomial_heap(); base_type::modify(it, r_new_val); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: link_with_next_sibling(node_pointer p_nd) { node_pointer p_next = p_nd->m_p_next_sibling; _GLIBCXX_DEBUG_ASSERT(p_next != 0); _GLIBCXX_DEBUG_ASSERT(p_next->m_p_prev_or_parent == p_nd); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; if (p_next->m_p_prev_or_parent == 0) base_type::m_p_root = p_next; else p_next->m_p_prev_or_parent->m_p_next_sibling = p_next; if (base_type::m_p_max == p_nd) base_type::m_p_max = p_next; base_type::make_child_of(p_nd, p_next); ++p_next->m_metadata; return p_next; } p_nd->m_p_next_sibling = p_next->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; if (base_type::m_p_max == p_next) base_type::m_p_max = p_nd; base_type::make_child_of(p_next, p_nd); ++p_nd->m_metadata; return p_nd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: make_0_exposed() { if (m_rc.empty()) return; node_pointer p_nd = m_rc.top(); m_rc.pop(); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling != 0); _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata); node_pointer p_res = link_with_next_sibling(p_nd); if (p_res->m_p_next_sibling != 0&& p_res->m_metadata == p_res->m_p_next_sibling->m_metadata) m_rc.push(p_res); } PKgd1]OqI I 68/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/erase_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: pop() { make_binomial_heap(); _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::pop(); base_type::find_max(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_rc.clear(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: make_binomial_heap() { node_pointer p_nd = base_type::m_p_root; while (p_nd != 0) { node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) p_nd = p_next; else if (p_nd->m_metadata == p_next->m_metadata) p_nd = link_with_next_sibling(p_nd); else if (p_nd->m_metadata < p_next->m_metadata) p_nd = p_next; #ifdef _GLIBCXX_DEBUG else _GLIBCXX_DEBUG_ASSERT(0); #endif } m_rc.clear(); } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { make_binomial_heap(); const size_type ersd = base_type::erase_if(pred); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { make_binomial_heap(); base_type::erase(it); base_type::find_max(); } PKgd1]eO~:8/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/rc_binomial_heap_.hpp * Contains an implementation for redundant-counter binomial heap. */ #include #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ rc_binomial_heap #define PB_DS_RC_C_DEC \ rc::node, _Alloc> /** * Redundant-counter binomial heap. * * @ingroup heap-detail */ template class rc_binomial_heap : public binomial_heap_base { private: typedef binomial_heap_base base_type; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; typedef PB_DS_RC_C_DEC rc_t; public: typedef Value_Type value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::cmp_fn cmp_fn; typedef typename base_type::allocator_type allocator_type; rc_binomial_heap(); rc_binomial_heap(const Cmp_Fn&); rc_binomial_heap(const PB_DS_CLASS_C_DEC&); ~rc_binomial_heap(); void swap(PB_DS_CLASS_C_DEC&); inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline void pop(); void erase(point_iterator); inline void clear(); template size_type erase_if(Pred); template void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ void trace() const; #endif private: inline node_pointer link_with_next_sibling(node_pointer); void make_0_exposed(); void make_binomial_heap(); #ifdef _GLIBCXX_DEBUG static node_const_pointer next_2_pointer(node_const_pointer); static node_const_pointer next_after_0_pointer(node_const_pointer); #endif rc_t m_rc; }; #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_RC_C_DEC } // namespace detail } // namespace __gnu_pbds PKgd1]갓yy+8/ext/pb_ds/detail/rc_binomial_heap_/rc.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/rc.hpp * Contains a redundant (binary counter). */ #ifndef PB_DS_RC_HPP #define PB_DS_RC_HPP namespace __gnu_pbds { namespace detail { /// Redundant binary counter. template class rc { private: typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef _Node node; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind __rebind_np; typedef typename __rebind_np::other::pointer entry_pointer; typedef typename __rebind_np::other::const_pointer entry_const_pointer; enum { max_entries = sizeof(size_type) << 3 }; public: typedef node_pointer entry; typedef entry_const_pointer const_iterator; rc(); rc(const rc&); inline void swap(rc&); inline void push(entry); inline node_pointer top() const; inline void pop(); inline bool empty() const; inline size_type size() const; void clear(); const const_iterator begin() const; const const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ void trace() const; #endif private: node_pointer m_a_entries[max_entries]; size_type m_over_top; }; template rc<_Node, _Alloc>:: rc() : m_over_top(0) { PB_DS_ASSERT_VALID((*this)) } template rc<_Node, _Alloc>:: rc(const rc<_Node, _Alloc>& other) : m_over_top(0) { PB_DS_ASSERT_VALID((*this)) } template inline void rc<_Node, _Alloc>:: swap(rc<_Node, _Alloc>& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) const size_type over_top = std::max(m_over_top, other.m_over_top); for (size_type i = 0; i < over_top; ++i) std::swap(m_a_entries[i], other.m_a_entries[i]); std::swap(m_over_top, other.m_over_top); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } template inline void rc<_Node, _Alloc>:: push(entry p_nd) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); m_a_entries[m_over_top++] = p_nd; PB_DS_ASSERT_VALID((*this)) } template inline void rc<_Node, _Alloc>:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); --m_over_top; PB_DS_ASSERT_VALID((*this)) } template inline typename rc<_Node, _Alloc>::node_pointer rc<_Node, _Alloc>:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); return *(m_a_entries + m_over_top - 1); } template inline bool rc<_Node, _Alloc>:: empty() const { PB_DS_ASSERT_VALID((*this)) return m_over_top == 0; } template inline typename rc<_Node, _Alloc>::size_type rc<_Node, _Alloc>:: size() const { return m_over_top; } template void rc<_Node, _Alloc>:: clear() { PB_DS_ASSERT_VALID((*this)) m_over_top = 0; PB_DS_ASSERT_VALID((*this)) } template const typename rc<_Node, _Alloc>::const_iterator rc<_Node, _Alloc>:: begin() const { return& m_a_entries[0]; } template const typename rc<_Node, _Alloc>::const_iterator rc<_Node, _Alloc>:: end() const { return& m_a_entries[m_over_top]; } #ifdef _GLIBCXX_DEBUG template void rc<_Node, _Alloc>:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_over_top < max_entries); } #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ template void rc<_Node, _Alloc>:: trace() const { std::cout << "rc" << std::endl; for (size_type i = 0; i < m_over_top; ++i) std::cerr << m_a_entries[i] << std::endl; std::cout << std::endl; } #endif } // namespace detail } // namespace __gnu_pbds #endif PKgd1]>r r ;8/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/split_join_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) make_binomial_heap(); other.make_binomial_heap(); base_type::split(pred, other); base_type::find_max(); other.find_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) make_binomial_heap(); other.make_binomial_heap(); base_type::join(other); base_type::find_max(); other.find_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1]Vz*<''#8/ext/pb_ds/detail/types_traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/types_traits.hpp * Contains a traits class of types used by containers. */ #ifndef PB_DS_TYPES_TRAITS_HPP #define PB_DS_TYPES_TRAITS_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Primary template. template struct no_throw_copies { static const bool __simple = is_simple::value && is_simple::value; typedef integral_constant indicator; }; /// Specialization. template struct no_throw_copies { typedef integral_constant::value> indicator; }; /// Stored value. template struct stored_value { typedef _Tv value_type; value_type m_value; }; /// Stored hash. template struct stored_hash { typedef _Th hash_type; hash_type m_hash; }; /// Primary template for representation of stored data. /// Two types of data can be stored: value and hash. template struct stored_data : public stored_value<_Tv>, public stored_hash<_Th> { }; /// Specialization for representation of stored data of just value type. template struct stored_data<_Tv, null_type> : public stored_value<_Tv> { }; /// Primary template. template struct type_base; /** * Specialization of type_base for the case where the hash value * is not stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef std::pair __value_type; typedef typename _Alloc::template rebind<__value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::value_type value_type; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; }; /** * Specialization of type_base for the case where the hash value * is stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef std::pair __value_type; typedef typename _Alloc::template rebind<__value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::value_type value_type; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; }; /** * Specialization of type_base for the case where the hash value * is not stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; typedef Key value_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename _Alloc::template rebind __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; static null_type s_null_type; }; template null_type type_base::s_null_type; /** * Specialization of type_base for the case where the hash value * is stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; typedef Key value_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename _Alloc::template rebind __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; static null_type s_null_type; }; template null_type type_base::s_null_type; /// Type base dispatch. template struct type_dispatch { typedef type_base type; }; /// Traits for abstract types. template struct types_traits : public type_dispatch::type { private: typedef no_throw_copies __nothrowcopy; typedef typename _Alloc::template rebind::other __rebind_a; public: typedef typename _Alloc::size_type size_type; typedef typename __rebind_a::value_type key_type; typedef typename __rebind_a::pointer key_pointer; typedef typename __rebind_a::const_pointer key_const_pointer; typedef typename __rebind_a::reference key_reference; typedef typename __rebind_a::const_reference key_const_reference; typedef std::pair comp_hash; typedef integral_constant store_extra; typedef typename __nothrowcopy::indicator no_throw_indicator; store_extra m_store_extra_indicator; no_throw_indicator m_no_throw_copies_indicator; }; //@} } // namespace detail } // namespace __gnu_pbds #endif PKgd1]{&8/ext/pb_ds/detail/tree_trace_base.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/tree_trace_base.hpp * Contains tree-related policies. */ #ifndef PB_DS_TREE_TRACE_BASE_HPP #define PB_DS_TREE_TRACE_BASE_HPP #ifdef PB_DS_TREE_TRACE #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_TREE_TRACE #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ tree_trace_base #define PB_DS_TRACE_BASE \ branch_policy /// Tracing base class. template class tree_trace_base : private PB_DS_TRACE_BASE { public: void trace() const; private: typedef PB_DS_TRACE_BASE base_type; typedef Node_CItr node_const_iterator; typedef typename _Alloc::size_type size_type; void trace_node(node_const_iterator, size_type) const; virtual bool empty() const = 0; virtual node_const_iterator node_begin() const = 0; virtual node_const_iterator node_end() const = 0; static void print_node_pointer(Node_CItr, integral_constant); static void print_node_pointer(Node_CItr, integral_constant); template static void trace_it_metadata(Node_CItr, type_to_type); static void trace_it_metadata(Node_CItr, type_to_type); }; PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { if (empty()) return; trace_node(node_begin(), 0); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_iterator nd_it, size_type level) const { if (nd_it.get_r_child() != node_end()) trace_node(nd_it.get_r_child(), level + 1); for (size_type i = 0; i < level; ++i) std::cerr << ' '; print_node_pointer(nd_it, integral_constant()); std::cerr << base_type::extract_key(*(*nd_it)); typedef type_to_type m_type_ind_t; trace_it_metadata(nd_it, m_type_ind_t()); std::cerr << std::endl; if (nd_it.get_l_child() != node_end()) trace_node(nd_it.get_l_child(), level + 1); } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: trace_it_metadata(Node_CItr nd_it, type_to_type) { const unsigned long ul = static_cast(nd_it.get_metadata()); std::cerr << " (" << ul << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_it_metadata(Node_CItr, type_to_type) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: print_node_pointer(Node_CItr nd_it, integral_constant) { std::cerr << nd_it.m_p_nd << " "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: print_node_pointer(Node_CItr nd_it, integral_constant) { std::cerr << *nd_it << " "; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_TRACE_BASE #endif // #ifdef PB_DS_TREE_TRACE } // namespace detail } // namespace __gnu_pbds #endif // #ifdef PB_DS_TREE_TRACE #endif // #ifndef PB_DS_TREE_TRACE_BASE_HPP PKgd1]b1(8/ext/pb_ds/detail/standard_policies.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/standard_policies.hpp * Contains standard policies for containers. */ #ifndef PB_DS_STANDARD_POLICIES_HPP #define PB_DS_STANDARD_POLICIES_HPP #include #include #include #include #include #include #include #include namespace __gnu_pbds { namespace detail { /// Primary template, default_hash_fn. template struct default_hash_fn { /// Dispatched type. typedef std::tr1::hash type; }; /// Primary template, default_eq_fn. template struct default_eq_fn { /// Dispatched type. typedef std::equal_to type; }; /// Enumeration for default behavior of stored hash data. enum { default_store_hash = false }; /// Primary template, default_comb_hash_fn. struct default_comb_hash_fn { /// Dispatched type. typedef direct_mask_range_hashing<> type; }; /// Primary template, default_resize_policy. template struct default_resize_policy { private: typedef typename Comb_Hash_Fn::size_type size_type; typedef direct_mask_range_hashing default_fn; typedef is_same same_type; typedef hash_exponential_size_policy iftrue; typedef hash_prime_size_policy iffalse; typedef __conditional_type cond_type; typedef typename cond_type::__type size_policy_type; typedef hash_load_check_resize_trigger trigger; public: /// Dispatched type. typedef hash_standard_resize_policy type; }; /// Default update policy. struct default_update_policy { /// Dispatched type. typedef lu_move_to_front_policy<> type; }; /// Primary template, default_probe_fn. template struct default_probe_fn { private: typedef typename Comb_Probe_Fn::size_type size_type; typedef direct_mask_range_hashing default_fn; typedef is_same same_type; typedef linear_probe_fn iftrue; typedef quadratic_probe_fn iffalse; typedef __conditional_type cond_type; public: /// Dispatched type. typedef typename cond_type::__type type; }; /// Primary template, default_trie_access_traits. template struct default_trie_access_traits; #define __dtrie_alloc std::allocator #define __dtrie_string std::basic_string /// Partial specialization, default_trie_access_traits. template struct default_trie_access_traits<__dtrie_string> { private: typedef __dtrie_string string_type; public: /// Dispatched type. typedef trie_string_access_traits type; }; #undef __dtrie_alloc #undef __dtrie_string } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_STANDARD_POLICIES_HPP PKgd1]h(8/ext/pb_ds/detail/rb_tree_map_/node.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/node.hpp * Contains an implementation for rb_tree_. */ #ifndef PB_DS_RB_TREE_NODE_HPP #define PB_DS_RB_TREE_NODE_HPP #include namespace __gnu_pbds { namespace detail { /// Node for Red-Black trees. template struct rb_tree_node_ { public: typedef Value_Type value_type; typedef Metadata metadata_type; typedef typename _Alloc::template rebind< rb_tree_node_< Value_Type, Metadata, _Alloc> >::other::pointer node_pointer; typedef typename _Alloc::template rebind< metadata_type>::other::reference metadata_reference; typedef typename _Alloc::template rebind< metadata_type>::other::const_reference metadata_const_reference; bool special() const { return m_red; } metadata_const_reference get_metadata() const { return m_metadata; } metadata_reference get_metadata() { return m_metadata; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) <<(m_red? " " : " ") << "(" << m_metadata << ")"; } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_red; metadata_type m_metadata; }; template struct rb_tree_node_ { public: typedef Value_Type value_type; typedef null_type metadata_type; typedef typename _Alloc::template rebind< rb_tree_node_< Value_Type, null_type, _Alloc> >::other::pointer node_pointer; bool special() const { return m_red; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) <<(m_red? " " : " "); } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_red; }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1] C8/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/constructors_destructor_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME() { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : base_type(r_cmp_fn, r_node_update) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { base_type::m_p_head->m_red = true; } PKgd1]d1108/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/info_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_effectively_black(const node_pointer p_nd) { return (p_nd == 0 || !p_nd->m_red); } PKgd1]ק08/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/find_fn_imps.hpp * Contains an implementation for rb_tree_. */ PKgd1]A 18/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/debug_fn_imps.hpp * Contains an implementation for rb_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: assert_node_consistent(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return 1; const size_type l_height = assert_node_consistent(p_nd->m_p_left, __file, __line); const size_type r_height = assert_node_consistent(p_nd->m_p_right, __file, __line); if (p_nd->m_red) { PB_DS_DEBUG_VERIFY(is_effectively_black(p_nd->m_p_left)); PB_DS_DEBUG_VERIFY(is_effectively_black(p_nd->m_p_right)); } PB_DS_DEBUG_VERIFY(l_height == r_height); return (p_nd->m_red ? 0 : 1) + l_height; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); const node_pointer p_head = base_type::m_p_head; PB_DS_DEBUG_VERIFY(p_head->m_red); if (p_head->m_p_parent != 0) { PB_DS_DEBUG_VERIFY(!p_head->m_p_parent->m_red); assert_node_consistent(p_head->m_p_parent, __file, __line); } } #endif PKgd1]Y28/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/insert_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) std::pair ins_pair = base_type::insert_leaf(r_value); if (ins_pair.second == true) { ins_pair.first.m_p_nd->m_red = true; PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) insert_fixup(ins_pair.first.m_p_nd); } PB_DS_ASSERT_VALID((*this)) return ins_pair; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_fixup(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_red == true); while (p_nd != base_type::m_p_head->m_p_parent && p_nd->m_p_parent->m_red) { if (p_nd->m_p_parent == p_nd->m_p_parent->m_p_parent->m_p_left) { node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_right; if (p_y != 0 && p_y->m_red) { p_nd->m_p_parent->m_red = false; p_y->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; p_nd = p_nd->m_p_parent->m_p_parent; } else { if (p_nd == p_nd->m_p_parent->m_p_right) { p_nd = p_nd->m_p_parent; base_type::rotate_left(p_nd); } p_nd->m_p_parent->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; base_type::rotate_right(p_nd->m_p_parent->m_p_parent); } } else { node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_left; if (p_y != 0 && p_y->m_red) { p_nd->m_p_parent->m_red = false; p_y->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; p_nd = p_nd->m_p_parent->m_p_parent; } else { if (p_nd == p_nd->m_p_parent->m_p_left) { p_nd = p_nd->m_p_parent; base_type::rotate_right(p_nd); } p_nd->m_p_parent->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; base_type::rotate_left(p_nd->m_p_parent->m_p_parent); } } } base_type::update_to_top(p_nd, (node_update* )this); base_type::m_p_head->m_p_parent->m_red = false; } PKgd1]b,8/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/rb_tree_.hpp * Contains an implementation for Red Black trees. */ #include #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #ifdef PB_DS_DATA_TRUE_INDICATOR # define PB_DS_RB_TREE_NAME rb_tree_map # define PB_DS_RB_TREE_BASE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR # define PB_DS_RB_TREE_NAME rb_tree_set # define PB_DS_RB_TREE_BASE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_C_DEC \ PB_DS_RB_TREE_NAME #define PB_DS_RB_TREE_BASE \ PB_DS_RB_TREE_BASE_NAME /** * @brief Red-Black tree. * @ingroup branch-detail * * This implementation uses an idea from the SGI STL (using a * @a header node which is needed for efficient iteration). */ template class PB_DS_RB_TREE_NAME : public PB_DS_RB_TREE_BASE { private: typedef PB_DS_RB_TREE_BASE base_type; typedef typename base_type::node_pointer node_pointer; public: typedef rb_tree_tag container_category; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_pointer key_pointer; typedef typename base_type::key_const_pointer key_const_pointer; typedef typename base_type::key_reference key_reference; typedef typename base_type::key_const_reference key_const_reference; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::mapped_pointer mapped_pointer; typedef typename base_type::mapped_const_pointer mapped_const_pointer; typedef typename base_type::mapped_reference mapped_reference; typedef typename base_type::mapped_const_reference mapped_const_reference; 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::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::node_update node_update; PB_DS_RB_TREE_NAME(); PB_DS_RB_TREE_NAME(const Cmp_Fn&); PB_DS_RB_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_RB_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); inline std::pair insert(const_reference); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) std::pair ins_pair = base_type::insert_leaf(value_type(r_key, mapped_type())); if (ins_pair.second == true) { ins_pair.first.m_p_nd->m_red = true; _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid(__FILE__, __LINE__);) insert_fixup(ins_pair.first.m_p_nd); } _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return ins_pair.first.m_p_nd->m_value.second; #else insert(r_key); return base_type::s_null_type; #endif } inline bool erase(key_const_reference); inline iterator erase(iterator); inline reverse_iterator erase(reverse_iterator); template inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); private: #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; size_type assert_node_consistent(const node_pointer, const char*, int) const; #endif inline static bool is_effectively_black(const node_pointer); void initialize(); void insert_fixup(node_pointer); void erase_node(node_pointer); void remove_node(node_pointer); void remove_fixup(node_pointer, node_pointer); void split_imp(node_pointer, PB_DS_CLASS_C_DEC&); inline node_pointer split_min(); std::pair split_min_imp(); void join_imp(node_pointer, node_pointer); std::pair find_join_pos_right(node_pointer, size_type, size_type); std::pair find_join_pos_left(node_pointer, size_type, size_type); inline size_type black_height(node_pointer); void split_at_node(node_pointer, PB_DS_CLASS_C_DEC&); }; #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);) #include #include #include #include #include #include #undef PB_DS_STRUCT_ONLY_ASSERT_VALID #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_RB_TREE_NAME #undef PB_DS_RB_TREE_BASE_NAME #undef PB_DS_RB_TREE_BASE } // namespace detail } // namespace __gnu_pbds PKgd1]M18/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/erase_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = this->find(r_key); if (it == base_type::end()) return false; erase(it); return true; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == base_type::end()) return it; iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == base_type::m_p_head) return it; reverse_iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; iterator it = base_type::begin(); while (it != base_type::end()) { if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_node(node_pointer p_nd) { remove_node(p_nd); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_z) { this->update_min_max_for_erased_node(p_z); node_pointer p_y = p_z; node_pointer p_x = 0; node_pointer p_new_x_parent = 0; if (p_y->m_p_left == 0) p_x = p_y->m_p_right; else if (p_y->m_p_right == 0) p_x = p_y->m_p_left; else { p_y = p_y->m_p_right; while (p_y->m_p_left != 0) p_y = p_y->m_p_left; p_x = p_y->m_p_right; } if (p_y == p_z) { p_new_x_parent = p_y->m_p_parent; if (p_x != 0) p_x->m_p_parent = p_y->m_p_parent; if (base_type::m_p_head->m_p_parent == p_z) base_type::m_p_head->m_p_parent = p_x; else if (p_z->m_p_parent->m_p_left == p_z) { p_y->m_p_left = p_z->m_p_parent; p_z->m_p_parent->m_p_left = p_x; } else { p_y->m_p_left = 0; p_z->m_p_parent->m_p_right = p_x; } } else { p_z->m_p_left->m_p_parent = p_y; p_y->m_p_left = p_z->m_p_left; if (p_y != p_z->m_p_right) { p_new_x_parent = p_y->m_p_parent; if (p_x != 0) p_x->m_p_parent = p_y->m_p_parent; p_y->m_p_parent->m_p_left = p_x; p_y->m_p_right = p_z->m_p_right; p_z->m_p_right->m_p_parent = p_y; } else p_new_x_parent = p_y; if (base_type::m_p_head->m_p_parent == p_z) base_type::m_p_head->m_p_parent = p_y; else if (p_z->m_p_parent->m_p_left == p_z) p_z->m_p_parent->m_p_left = p_y; else p_z->m_p_parent->m_p_right = p_y; p_y->m_p_parent = p_z->m_p_parent; std::swap(p_y->m_red, p_z->m_red); p_y = p_z; } this->update_to_top(p_new_x_parent, (node_update* )this); if (p_y->m_red) return; remove_fixup(p_x, p_new_x_parent); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_fixup(node_pointer p_x, node_pointer p_new_x_parent) { _GLIBCXX_DEBUG_ASSERT(p_x == 0 || p_x->m_p_parent == p_new_x_parent); while (p_x != base_type::m_p_head->m_p_parent && is_effectively_black(p_x)) if (p_x == p_new_x_parent->m_p_left) { node_pointer p_w = p_new_x_parent->m_p_right; if (p_w->m_red) { p_w->m_red = false; p_new_x_parent->m_red = true; base_type::rotate_left(p_new_x_parent); p_w = p_new_x_parent->m_p_right; } if (is_effectively_black(p_w->m_p_left) && is_effectively_black(p_w->m_p_right)) { p_w->m_red = true; p_x = p_new_x_parent; p_new_x_parent = p_new_x_parent->m_p_parent; } else { if (is_effectively_black(p_w->m_p_right)) { if (p_w->m_p_left != 0) p_w->m_p_left->m_red = false; p_w->m_red = true; base_type::rotate_right(p_w); p_w = p_new_x_parent->m_p_right; } p_w->m_red = p_new_x_parent->m_red; p_new_x_parent->m_red = false; if (p_w->m_p_right != 0) p_w->m_p_right->m_red = false; base_type::rotate_left(p_new_x_parent); this->update_to_top(p_new_x_parent, (node_update* )this); break; } } else { node_pointer p_w = p_new_x_parent->m_p_left; if (p_w->m_red == true) { p_w->m_red = false; p_new_x_parent->m_red = true; base_type::rotate_right(p_new_x_parent); p_w = p_new_x_parent->m_p_left; } if (is_effectively_black(p_w->m_p_right) && is_effectively_black(p_w->m_p_left)) { p_w->m_red = true; p_x = p_new_x_parent; p_new_x_parent = p_new_x_parent->m_p_parent; } else { if (is_effectively_black(p_w->m_p_left)) { if (p_w->m_p_right != 0) p_w->m_p_right->m_red = false; p_w->m_red = true; base_type::rotate_left(p_w); p_w = p_new_x_parent->m_p_left; } p_w->m_red = p_new_x_parent->m_red; p_new_x_parent->m_red = false; if (p_w->m_p_left != 0) p_w->m_p_left->m_red = false; base_type::rotate_right(p_new_x_parent); this->update_to_top(p_new_x_parent, (node_update* )this); break; } } if (p_x != 0) p_x->m_red = false; } PKgd1]Põ68/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/split_join_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::join_prep(other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } const node_pointer p_x = other.split_min(); join_imp(p_x, other.m_p_head->m_p_parent); base_type::join_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join_imp(node_pointer p_x, node_pointer p_r) { _GLIBCXX_DEBUG_ASSERT(p_x != 0); if (p_r != 0) p_r->m_red = false; const size_type h = black_height(base_type::m_p_head->m_p_parent); const size_type other_h = black_height(p_r); node_pointer p_x_l; node_pointer p_x_r; std::pair join_pos; const bool right_join = h >= other_h; if (right_join) { join_pos = find_join_pos_right(base_type::m_p_head->m_p_parent, h, other_h); p_x_l = join_pos.first; p_x_r = p_r; } else { p_x_l = base_type::m_p_head->m_p_parent; base_type::m_p_head->m_p_parent = p_r; if (p_r != 0) p_r->m_p_parent = base_type::m_p_head; join_pos = find_join_pos_left(base_type::m_p_head->m_p_parent, h, other_h); p_x_r = join_pos.first; } node_pointer p_parent = join_pos.second; if (p_parent == base_type::m_p_head) { base_type::m_p_head->m_p_parent = p_x; p_x->m_p_parent = base_type::m_p_head; } else { p_x->m_p_parent = p_parent; if (right_join) p_x->m_p_parent->m_p_right = p_x; else p_x->m_p_parent->m_p_left = p_x; } p_x->m_p_left = p_x_l; if (p_x_l != 0) p_x_l->m_p_parent = p_x; p_x->m_p_right = p_x_r; if (p_x_r != 0) p_x_r->m_p_parent = p_x; p_x->m_red = true; base_type::initialize_min_max(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) base_type::update_to_top(p_x, (node_update* )this); insert_fixup(p_x); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: split_min() { node_pointer p_min = base_type::m_p_head->m_p_left; #ifdef _GLIBCXX_DEBUG const node_pointer p_head = base_type::m_p_head; _GLIBCXX_DEBUG_ASSERT(p_min != p_head); #endif remove_node(p_min); return p_min; } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::node_pointer, typename PB_DS_CLASS_C_DEC::node_pointer> PB_DS_CLASS_C_DEC:: find_join_pos_right(node_pointer p_l, size_type h_l, size_type h_r) { _GLIBCXX_DEBUG_ASSERT(h_l >= h_r); if (base_type::m_p_head->m_p_parent == 0) return (std::make_pair((node_pointer)0, base_type::m_p_head)); node_pointer p_l_parent = base_type::m_p_head; while (h_l > h_r) { if (p_l->m_red == false) { _GLIBCXX_DEBUG_ASSERT(h_l > 0); --h_l; } p_l_parent = p_l; p_l = p_l->m_p_right; } if (!is_effectively_black(p_l)) { p_l_parent = p_l; p_l = p_l->m_p_right; } _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_l)); _GLIBCXX_DEBUG_ASSERT(black_height(p_l) == h_r); _GLIBCXX_DEBUG_ASSERT(p_l == 0 || p_l->m_p_parent == p_l_parent); return std::make_pair(p_l, p_l_parent); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::node_pointer, typename PB_DS_CLASS_C_DEC::node_pointer> PB_DS_CLASS_C_DEC:: find_join_pos_left(node_pointer p_r, size_type h_l, size_type h_r) { _GLIBCXX_DEBUG_ASSERT(h_r > h_l); if (base_type::m_p_head->m_p_parent == 0) return (std::make_pair((node_pointer)0, base_type::m_p_head)); node_pointer p_r_parent = base_type::m_p_head; while (h_r > h_l) { if (p_r->m_red == false) { _GLIBCXX_DEBUG_ASSERT(h_r > 0); --h_r; } p_r_parent = p_r; p_r = p_r->m_p_left; } if (!is_effectively_black(p_r)) { p_r_parent = p_r; p_r = p_r->m_p_left; } _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_r)); _GLIBCXX_DEBUG_ASSERT(black_height(p_r) == h_l); _GLIBCXX_DEBUG_ASSERT(p_r == 0 || p_r->m_p_parent == p_r_parent); return std::make_pair(p_r, p_r_parent); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: black_height(node_pointer p_nd) { size_type h = 1; while (p_nd != 0) { if (p_nd->m_red == false) ++h; p_nd = p_nd->m_p_left; } return h; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::split_prep(r_key, other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) node_pointer p_nd = this->upper_bound(r_key).m_p_nd; do { node_pointer p_next_nd = p_nd->m_p_parent; if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) split_at_node(p_nd, other); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) p_nd = p_next_nd; } while (p_nd != base_type::m_p_head); base_type::split_finish(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_at_node(node_pointer p_nd, PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); node_pointer p_l = p_nd->m_p_left; node_pointer p_r = p_nd->m_p_right; node_pointer p_parent = p_nd->m_p_parent; if (p_parent == base_type::m_p_head) { base_type::m_p_head->m_p_parent = p_l; if (p_l != 0) { p_l->m_p_parent = base_type::m_p_head; p_l->m_red = false; } } else { if (p_parent->m_p_left == p_nd) p_parent->m_p_left = p_l; else p_parent->m_p_right = p_l; if (p_l != 0) p_l->m_p_parent = p_parent; this->update_to_top(p_parent, (node_update* )this); if (!p_nd->m_red) remove_fixup(p_l, p_parent); } base_type::initialize_min_max(); other.join_imp(p_nd, p_r); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) } PKgd1];# *8/ext/pb_ds/detail/rb_tree_map_/traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/traits.hpp * Contains an implementation for rb_tree_. */ #ifndef PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits< Key, Mapped, Cmp_Fn, Node_Update, rb_tree_node_< typename types_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits< Key, null_type, Cmp_Fn, Node_Update, rb_tree_node_< typename types_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]2fY28/ext/pb_ds/detail/binary_heap_/const_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP #define PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_BIN_HEAP_CIT_BASE \ binary_heap_point_const_iterator_ /// Const point-type iterator. template class binary_heap_const_iterator_ : public PB_DS_BIN_HEAP_CIT_BASE { private: typedef PB_DS_BIN_HEAP_CIT_BASE base_type; typedef typename base_type::entry_pointer entry_pointer; public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef typename base_type::value_type value_type; /// Iterator's pointer type. typedef typename base_type::pointer pointer; /// Iterator's const pointer type. typedef typename base_type::const_pointer const_pointer; /// Iterator's reference type. typedef typename base_type::reference reference; /// Iterator's const reference type. typedef typename base_type::const_reference const_reference; inline binary_heap_const_iterator_(entry_pointer p_e) : base_type(p_e) { } /// Default constructor. inline binary_heap_const_iterator_() { } /// Copy constructor. inline binary_heap_const_iterator_(const binary_heap_const_iterator_& other) : base_type(other) { } /// Compares content to a different iterator object. inline bool operator==(const binary_heap_const_iterator_& other) const { return base_type::m_p_e == other.m_p_e; } /// Compares content (negatively) to a different iterator object. inline bool operator!=(const binary_heap_const_iterator_& other) const { return base_type::m_p_e != other.m_p_e; } inline binary_heap_const_iterator_& operator++() { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_e != 0); inc(); return *this; } inline binary_heap_const_iterator_ operator++(int) { binary_heap_const_iterator_ ret_it(base_type::m_p_e); operator++(); return ret_it; } private: void inc() { ++base_type::m_p_e; } }; #undef PB_DS_BIN_HEAP_CIT_BASE } // namespace detail } // namespace __gnu_pbds #endif PKgd1]uL .8/ext/pb_ds/detail/binary_heap_/entry_pred.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/entry_pred.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP #define PB_DS_BINARY_HEAP_ENTRY_PRED_HPP namespace __gnu_pbds { namespace detail { /// Entry predicate primary class template. template struct entry_pred; /// Specialization, true. template struct entry_pred<_VTp, Pred, _Alloc, true> { typedef Pred type; }; /// Specialization, false. template struct entry_pred<_VTp, Pred, _Alloc, false> { private: typedef typename _Alloc::template rebind<_VTp> __rebind_v; public: typedef typename __rebind_v::other::const_pointer entry; struct type : public Pred { inline type() { } inline type(const Pred& other) : Pred(other) { } inline bool operator()(entry p_v) const { return Pred::operator()(*p_v); } }; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP PKgd1]_v 18/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/trace_fn_imps.hpp * Contains an implementation class for a binary_heap. */ #ifdef PB_DS_BINARY_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << this << std::endl; std::cerr << m_a_entries << std::endl; for (size_type i = 0; i < m_size; ++i) trace_entry(m_a_entries[i], s_no_throw_copies_ind); std::cerr << std::endl; std::cerr << "size = " << m_size << " " << "actual_size = " << m_actual_size << std::endl; resize_policy::trace(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_entry(const entry& r_e, false_type) const { std::cout << r_e << " " <<* r_e << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_entry(const entry& r_e, true_type) const { std::cout << r_e << std::endl; } #endif // #ifdef PB_DS_BINARY_HEAP_TRACE_ PKgd1] uM_nn98/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/policy_access_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return (*this); } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return (*this); } PKgd1]GH]]C8/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for binary_heap_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::value_allocator PB_DS_CLASS_C_DEC::s_value_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::no_throw_copies_t PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) { insert_value(*first_it, s_no_throw_copies_ind); ++first_it; } make_heap(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap() : m_size(0), m_actual_size(resize_policy::min_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap(const Cmp_Fn& r_cmp_fn) : entry_cmp(r_cmp_fn), m_size(0), m_actual_size(resize_policy::min_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap(const PB_DS_CLASS_C_DEC& other) : entry_cmp(other), resize_policy(other), m_size(0), m_actual_size(other.m_actual_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); __try { copy_from_range(other.begin(), other.end()); } __catch(...) { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); s_entry_allocator.deallocate(m_a_entries, m_actual_size); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); value_swap(other); std::swap((entry_cmp&)(*this), (entry_cmp&)other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_a_entries, other.m_a_entries); std::swap(m_size, other.m_size); std::swap(m_actual_size, other.m_actual_size); static_cast(this)->swap(other); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binary_heap() { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); s_entry_allocator.deallocate(m_a_entries, m_actual_size); } PKgd1] IPl__88/ext/pb_ds/detail/binary_heap_/point_const_iterator.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/point_const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP #define PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { /// Const point-type iterator. template class binary_heap_point_const_iterator_ { protected: typedef typename _Alloc::template rebind::other::pointer entry_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef Value_Type value_type; /// Iterator's pointer type. typedef typename _Alloc::template rebind::other::pointer pointer; /// Iterator's const pointer type. typedef typename _Alloc::template rebind::other::const_pointer const_pointer; /// Iterator's reference type. typedef typename _Alloc::template rebind::other::reference reference; /// Iterator's const reference type. typedef typename _Alloc::template rebind::other::const_reference const_reference; inline binary_heap_point_const_iterator_(entry_pointer p_e) : m_p_e(p_e) { } /// Default constructor. inline binary_heap_point_const_iterator_() : m_p_e(0) { } /// Copy constructor. inline binary_heap_point_const_iterator_(const binary_heap_point_const_iterator_& other) : m_p_e(other.m_p_e) { } /// Access. inline const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_e != 0); return to_ptr(integral_constant()); } /// Access. inline const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_e != 0); return *to_ptr(integral_constant()); } /// Compares content to a different iterator object. inline bool operator==(const binary_heap_point_const_iterator_& other) const { return m_p_e == other.m_p_e; } /// Compares content (negatively) to a different iterator object. inline bool operator!=(const binary_heap_point_const_iterator_& other) const { return m_p_e != other.m_p_e; } private: inline const_pointer to_ptr(true_type) const { return m_p_e; } inline const_pointer to_ptr(false_type) const { return *m_p_e; } public: entry_pointer m_p_e; }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]?~08/ext/pb_ds/detail/binary_heap_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/info_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return m_size == 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PKgd1]O  -8/ext/pb_ds/detail/binary_heap_/entry_cmp.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/entry_cmp.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP #define PB_DS_BINARY_HEAP_ENTRY_CMP_HPP namespace __gnu_pbds { namespace detail { /// Entry compare, primary template. template struct entry_cmp; /// Specialization, true. template struct entry_cmp<_VTp, Cmp_Fn, _Alloc, true> { /// Compare. typedef Cmp_Fn type; }; /// Specialization, false. template struct entry_cmp<_VTp, Cmp_Fn, _Alloc, false> { private: typedef typename _Alloc::template rebind<_VTp> __rebind_v; public: typedef typename __rebind_v::other::const_pointer entry; /// Compare plus entry. struct type : public Cmp_Fn { type() { } type(const Cmp_Fn& other) : Cmp_Fn(other) { } bool operator()(entry lhs, entry rhs) const { return Cmp_Fn::operator()(*lhs, *rhs); } }; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP PKgd1]ιy% % 08/ext/pb_ds/detail/binary_heap_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/find_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); return top_imp(s_no_throw_copies_ind); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top_imp(true_type) const { return *m_a_entries; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top_imp(false_type) const { return **m_a_entries; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: left_child(size_type i) { return i * 2 + 1; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: right_child(size_type i) { return i * 2 + 2; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: parent(size_type i) { return (i - 1) / 2; } PKgd1].58/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/iterators_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return const_iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_a_entries + m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(m_a_entries + m_size); } PKgd1]H'B 18/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/debug_fn_imps.hpp * Contains an implementation class for a binary_heap. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { #ifdef PB_DS_REGRESSION s_entry_allocator.check_allocated(m_a_entries, m_actual_size); #endif resize_policy::assert_valid(__file, __line); PB_DS_DEBUG_VERIFY(m_size <= m_actual_size); for (size_type i = 0; i < m_size; ++i) { #ifdef PB_DS_REGRESSION s_value_allocator.check_allocated(m_a_entries[i], 1); #endif if (left_child(i) < m_size) PB_DS_DEBUG_VERIFY(!entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child(i)])); PB_DS_DEBUG_VERIFY(parent(left_child(i)) == i); if (right_child(i) < m_size) PB_DS_DEBUG_VERIFY(!entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child(i)])); PB_DS_DEBUG_VERIFY(parent(right_child(i)) == i); } } #endif PKgd1]H`rr28/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/insert_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) insert_value(r_val, s_no_throw_copies_ind); push_heap(); PB_DS_ASSERT_VALID((*this)) return point_iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_value(value_type val, true_type) { resize_for_insert_if_needed(); m_a_entries[m_size++] = val; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_value(const_reference r_val, false_type) { resize_for_insert_if_needed(); pointer p_new = s_value_allocator.allocate(1); cond_dealtor_t cond(p_new); new (p_new) value_type(r_val); cond.set_no_action(); m_a_entries[m_size++] = p_new; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_for_insert_if_needed() { if (!resize_policy::resize_needed_for_grow(m_size)) { _GLIBCXX_DEBUG_ASSERT(m_size < m_actual_size); return; } const size_type new_size = resize_policy::get_new_size_for_grow(); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_grow_resize(); std::copy(m_a_entries, m_a_entries + m_size, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; make_heap(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) swap_value_imp(it.m_p_e, r_new_val, s_no_throw_copies_ind); fix(it.m_p_e); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: fix(entry_pointer p_e) { size_type i = p_e - m_a_entries; if (i > 0 && entry_cmp::operator()(m_a_entries[parent(i)], m_a_entries[i])) { size_type parent_i = parent(i); while (i > 0 && entry_cmp::operator()(m_a_entries[parent_i], m_a_entries[i])) { std::swap(m_a_entries[i], m_a_entries[parent_i]); i = parent_i; parent_i = parent(i); } PB_DS_ASSERT_VALID((*this)) return; } while (i < m_size) { const size_type lchild_i = left_child(i); const size_type rchild_i = right_child(i); _GLIBCXX_DEBUG_ASSERT(rchild_i > lchild_i); const bool smaller_than_lchild = lchild_i < m_size && entry_cmp::operator()(m_a_entries[i], m_a_entries[lchild_i]); const bool smaller_than_rchild = rchild_i < m_size && entry_cmp::operator()(m_a_entries[i], m_a_entries[rchild_i]); const bool swap_with_rchild = smaller_than_rchild && (!smaller_than_lchild || entry_cmp::operator()(m_a_entries[lchild_i], m_a_entries[rchild_i])); const bool swap_with_lchild = !swap_with_rchild && smaller_than_lchild; if (swap_with_lchild) { std::swap(m_a_entries[i], m_a_entries[lchild_i]); i = lchild_i; } else if (swap_with_rchild) { std::swap(m_a_entries[i], m_a_entries[rchild_i]); i = rchild_i; } else i = m_size; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_value_imp(entry_pointer p_e, value_type new_val, true_type) { *p_e = new_val; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type) { value_type tmp(r_new_val); (*p_e)->swap(tmp); } PKgd1]@Ҁ18/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/erase_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); __try { const size_type new_size = resize_policy::get_new_size_for_arbitrary(0); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_arbitrary(new_size); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; } __catch(...) { } m_size = 0; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_at(entry_pointer a_entries, size_type i, false_type) { a_entries[i]->~value_type(); s_value_allocator.deallocate(a_entries[i], 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_at(entry_pointer, size_type, true_type) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); pop_heap(); erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); resize_for_erase_if_needed(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) typedef typename entry_pred::type pred_t; const size_type left = partition(pred_t(pred)); _GLIBCXX_DEBUG_ASSERT(m_size >= left); const size_type ersd = m_size - left; for (size_type i = left; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); __try { const size_type new_size = resize_policy::get_new_size_for_arbitrary(left); entry_pointer new_entries = s_entry_allocator.allocate(new_size); std::copy(m_a_entries, m_a_entries + left, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; resize_policy::notify_arbitrary(m_actual_size); } __catch(...) { }; m_size = left; make_heap(); PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); const size_type fix_pos = it.m_p_e - m_a_entries; std::swap(*it.m_p_e, m_a_entries[m_size - 1]); erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); resize_for_erase_if_needed(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size); if (fix_pos != m_size) fix(m_a_entries + fix_pos); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_for_erase_if_needed() { if (!resize_policy::resize_needed_for_shrink(m_size)) return; __try { const size_type new_size = resize_policy::get_new_size_for_shrink(); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_shrink_resize(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); std::copy(m_a_entries, m_a_entries + m_size - 1, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; } __catch(...) { } } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: partition(Pred pred) { size_type left = 0; size_type right = m_size - 1; while (right + 1 != left) { _GLIBCXX_DEBUG_ASSERT(left <= m_size); if (!pred(m_a_entries[left])) ++left; else if (pred(m_a_entries[right])) --right; else { _GLIBCXX_DEBUG_ASSERT(left < right); std::swap(m_a_entries[left], m_a_entries[right]); ++left; --right; } } return left; } PKgd1]/2#2#08/ext/pb_ds/detail/binary_heap_/binary_heap_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/binary_heap_.hpp * Contains an implementation class for a binary heap. */ #ifndef PB_DS_BINARY_HEAP_HPP #define PB_DS_BINARY_HEAP_HPP #include #include #include #include #include #include #include #include #include #include #ifdef PB_DS_BINARY_HEAP_TRACE_ #include #endif #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ binary_heap #define PB_DS_ENTRY_CMP_DEC \ entry_cmp::value>::type #define PB_DS_RESIZE_POLICY_DEC \ __gnu_pbds::detail::resize_policy /** * Binary heaps composed of resize and compare policies. * * @ingroup heap-detail * * Based on CLRS. */ template class binary_heap : public PB_DS_ENTRY_CMP_DEC, public PB_DS_RESIZE_POLICY_DEC { public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename PB_DS_ENTRY_CMP_DEC entry_cmp; typedef PB_DS_RESIZE_POLICY_DEC resize_policy; typedef cond_dealtor cond_dealtor_t; private: enum { simple_value = is_simple::value }; typedef integral_constant no_throw_copies_t; typedef typename _Alloc::template rebind __rebind_v; typedef typename __rebind_v::other value_allocator; public: typedef typename value_allocator::pointer pointer; typedef typename value_allocator::const_pointer const_pointer; typedef typename value_allocator::reference reference; typedef typename value_allocator::const_reference const_reference; typedef typename __conditional_type::__type entry; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef binary_heap_point_const_iterator_ point_const_iterator; typedef point_const_iterator point_iterator; typedef binary_heap_const_iterator_ const_iterator; typedef const_iterator iterator; binary_heap(); binary_heap(const cmp_fn&); binary_heap(const binary_heap&); void swap(binary_heap&); ~binary_heap(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; inline void pop(); inline void erase(point_iterator); template size_type erase_if(Pred); inline void erase_at(entry_pointer, size_type, false_type); inline void erase_at(entry_pointer, size_type, true_type); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; void clear(); template void split(Pred, binary_heap&); void join(binary_heap&); #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace() const; #endif protected: template void copy_from_range(It, It); private: void value_swap(binary_heap&); inline void insert_value(const_reference, false_type); inline void insert_value(value_type, true_type); inline void resize_for_insert_if_needed(); inline void swap_value_imp(entry_pointer, value_type, true_type); inline void swap_value_imp(entry_pointer, const_reference, false_type); void fix(entry_pointer); inline const_reference top_imp(true_type) const; inline const_reference top_imp(false_type) const; inline static size_type left_child(size_type); inline static size_type right_child(size_type); inline static size_type parent(size_type); inline void resize_for_erase_if_needed(); template size_type partition(Pred); void make_heap() { const entry_cmp& m_cmp = static_cast(*this); entry_pointer end = m_a_entries + m_size; std::make_heap(m_a_entries, end, m_cmp); } void push_heap() { const entry_cmp& m_cmp = static_cast(*this); entry_pointer end = m_a_entries + m_size; std::push_heap(m_a_entries, end, m_cmp); } void pop_heap() { const entry_cmp& m_cmp = static_cast(*this); entry_pointer end = m_a_entries + m_size; std::pop_heap(m_a_entries, end, m_cmp); } #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace_entry(const entry&, false_type) const; void trace_entry(const entry&, true_type) const; #endif static entry_allocator s_entry_allocator; static value_allocator s_value_allocator; static no_throw_copies_t s_no_throw_copies_ind; size_type m_size; size_type m_actual_size; entry_pointer m_a_entries; }; #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #include #include #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_ENTRY_CMP_DEC #undef PB_DS_RESIZE_POLICY_DEC } // namespace detail } // namespace __gnu_pbds #endif PKgd1]18/ext/pb_ds/detail/binary_heap_/resize_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/resize_policy.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP #define PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP #include namespace __gnu_pbds { namespace detail { /// Resize policy for binary heap. template class resize_policy { private: enum { ratio = 8, factor = 2 }; /// Next shrink size. _Tp m_shrink_size; /// Next grow size. _Tp m_grow_size; public: typedef _Tp size_type; static const _Tp min_size = 16; resize_policy() : m_shrink_size(0), m_grow_size(min_size) { PB_DS_ASSERT_VALID((*this)) } resize_policy(const resize_policy& other) : m_shrink_size(other.m_shrink_size), m_grow_size(other.m_grow_size) { PB_DS_ASSERT_VALID((*this)) } inline void swap(resize_policy<_Tp>&); inline bool resize_needed_for_grow(size_type) const; inline bool resize_needed_for_shrink(size_type) const; inline bool grow_needed(size_type) const; inline bool shrink_needed(size_type) const; inline size_type get_new_size_for_grow() const; inline size_type get_new_size_for_shrink() const; inline size_type get_new_size_for_arbitrary(size_type) const; inline void notify_grow_resize(); inline void notify_shrink_resize(); void notify_arbitrary(size_type); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace() const; #endif }; template const _Tp resize_policy<_Tp>::min_size; template inline void resize_policy<_Tp>:: swap(resize_policy<_Tp>& other) { std::swap(m_shrink_size, other.m_shrink_size); std::swap(m_grow_size, other.m_grow_size); } template inline bool resize_policy<_Tp>:: resize_needed_for_grow(size_type size) const { _GLIBCXX_DEBUG_ASSERT(size <= m_grow_size); return size == m_grow_size; } template inline bool resize_policy<_Tp>:: resize_needed_for_shrink(size_type size) const { _GLIBCXX_DEBUG_ASSERT(size <= m_grow_size); return size == m_shrink_size; } template inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_grow() const { return m_grow_size * factor; } template inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_shrink() const { const size_type half_size = m_grow_size / factor; return std::max(min_size, half_size); } template inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_arbitrary(size_type size) const { size_type ret = min_size; while (ret < size) ret *= factor; return ret; } template inline void resize_policy<_Tp>:: notify_grow_resize() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(m_grow_size >= min_size); m_grow_size *= factor; m_shrink_size = m_grow_size / ratio; PB_DS_ASSERT_VALID((*this)) } template inline void resize_policy<_Tp>:: notify_shrink_resize() { PB_DS_ASSERT_VALID((*this)) m_shrink_size /= factor; if (m_shrink_size == 1) m_shrink_size = 0; m_grow_size = std::max(m_grow_size / factor, min_size); PB_DS_ASSERT_VALID((*this)) } template inline void resize_policy<_Tp>:: notify_arbitrary(size_type actual_size) { m_grow_size = actual_size; m_shrink_size = m_grow_size / ratio; PB_DS_ASSERT_VALID((*this)) } #ifdef _GLIBCXX_DEBUG template void resize_policy<_Tp>:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_shrink_size == 0 || m_shrink_size * ratio == m_grow_size); PB_DS_DEBUG_VERIFY(m_grow_size >= min_size); } #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ template void resize_policy<_Tp>:: trace() const { std::cerr << "shrink = " << m_shrink_size << " grow = " << m_grow_size << std::endl; } #endif } // namespace detail } // namespace __gnu_pbds #endif PKgd1]!';;68/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/split_join_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) typedef typename entry_pred::type pred_t; const size_type left = partition(pred_t(pred)); _GLIBCXX_DEBUG_ASSERT(m_size >= left); const size_type ersd = m_size - left; _GLIBCXX_DEBUG_ASSERT(m_size >= ersd); const size_type new_size = resize_policy::get_new_size_for_arbitrary(left); const size_type other_actual_size = other.get_new_size_for_arbitrary(ersd); entry_pointer a_entries = 0; entry_pointer a_other_entries = 0; __try { a_entries = s_entry_allocator.allocate(new_size); a_other_entries = s_entry_allocator.allocate(other_actual_size); } __catch(...) { if (a_entries != 0) s_entry_allocator.deallocate(a_entries, new_size); if (a_other_entries != 0) s_entry_allocator.deallocate(a_other_entries, other_actual_size); __throw_exception_again; }; for (size_type i = 0; i < other.m_size; ++i) erase_at(other.m_a_entries, i, s_no_throw_copies_ind); _GLIBCXX_DEBUG_ASSERT(new_size >= left); std::copy(m_a_entries, m_a_entries + left, a_entries); std::copy(m_a_entries + left, m_a_entries + m_size, a_other_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); m_actual_size = new_size; other.m_actual_size = other_actual_size; m_size = left; other.m_size = ersd; m_a_entries = a_entries; other.m_a_entries = a_other_entries; make_heap(); other.make_heap(); resize_policy::notify_arbitrary(m_actual_size); other.notify_arbitrary(other.m_actual_size); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) const size_type len = m_size + other.m_size; const size_type new_size = resize_policy::get_new_size_for_arbitrary(len); entry_pointer a_entries = 0; entry_pointer a_other_entries = 0; __try { a_entries = s_entry_allocator.allocate(new_size); a_other_entries = s_entry_allocator.allocate(resize_policy::min_size); } __catch(...) { if (a_entries != 0) s_entry_allocator.deallocate(a_entries, new_size); if (a_other_entries != 0) s_entry_allocator.deallocate(a_other_entries, resize_policy::min_size); __throw_exception_again; } std::copy(m_a_entries, m_a_entries + m_size, a_entries); std::copy(other.m_a_entries, other.m_a_entries + other.m_size, a_entries + m_size); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_a_entries = a_entries; m_size = len; m_actual_size = new_size; resize_policy::notify_arbitrary(new_size); make_heap(); s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); other.m_a_entries = a_other_entries; other.m_size = 0; other.m_actual_size = resize_policy::min_size; other.notify_arbitrary(resize_policy::min_size); other.make_heap(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1]wӠ'8/ext/pb_ds/detail/splay_tree_/node.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/node.hpp * Contains an implementation struct for splay_tree_'s node. */ #ifndef PB_DS_SPLAY_TREE_NODE_HPP #define PB_DS_SPLAY_TREE_NODE_HPP namespace __gnu_pbds { namespace detail { /// Node for splay tree. template struct splay_tree_node_ { public: typedef Value_Type value_type; typedef Metadata metadata_type; typedef typename _Alloc::template rebind< splay_tree_node_ >::other::pointer node_pointer; typedef typename _Alloc::template rebind::other::reference metadata_reference; typedef typename _Alloc::template rebind::other::const_reference metadata_const_reference; #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) << "(" << m_metadata << ")"; } #endif inline bool special() const { return m_special; } inline metadata_const_reference get_metadata() const { return m_metadata; } inline metadata_reference get_metadata() { return m_metadata; } value_type m_value; bool m_special; node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; metadata_type m_metadata; }; template struct splay_tree_node_ { public: typedef Value_Type value_type; typedef null_type metadata_type; typedef typename _Alloc::template rebind< splay_tree_node_ >::other::pointer node_pointer; inline bool special() const { return m_special; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value); } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_special; }; } // namespace detail } // namespace __gnu_pbds #endif PKgd1]ܨ  B8/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/constructors_destructor_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME() { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : base_type(r_cmp_fn, r_node_update) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { base_type::m_p_head->m_special = true; } PKgd1]IC"/8/ext/pb_ds/detail/splay_tree_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/info_fn_imps.hpp * Contains an implementation. */ PKgd1]94 /8/ext/pb_ds/detail/splay_tree_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/find_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { node_pointer p_found = find_imp(r_key); if (p_found != base_type::m_p_head) splay(p_found); return point_iterator(p_found); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { const node_pointer p_found = find_imp(r_key); if (p_found != base_type::m_p_head) const_cast(this)->splay(p_found); return point_iterator(p_found); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) { _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid(__FILE__, __LINE__);) node_pointer p_nd = base_type::m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) return p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return base_type::m_p_head; } PB_DS_CLASS_T_DEC inline const typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) return p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return base_type::m_p_head; } PKgd1]轉[$[$.8/ext/pb_ds/detail/splay_tree_/splay_tree_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/splay_tree_.hpp * Contains an implementation class for splay trees. */ /* * This implementation uses an idea from the SGI STL (using a @a header node * which is needed for efficient iteration). Following is the SGI STL * copyright. * * 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. * * * 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. * * */ #include #include #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR # define PB_DS_S_TREE_NAME splay_tree_map # define PB_DS_S_TREE_BASE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR # define PB_DS_S_TREE_NAME splay_tree_set # define PB_DS_S_TREE_BASE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_S_TREE_NAME #define PB_DS_S_TREE_BASE \ PB_DS_S_TREE_BASE_NAME /** * @brief Splay tree. * @ingroup branch-detail */ template class PB_DS_S_TREE_NAME : public PB_DS_S_TREE_BASE { private: typedef PB_DS_S_TREE_BASE base_type; #ifdef _GLIBCXX_DEBUG typedef base_type debug_base; #endif typedef typename base_type::node_pointer node_pointer; public: typedef splay_tree_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Cmp_Fn cmp_fn; typedef typename base_type::key_type key_type; typedef typename base_type::key_pointer key_pointer; typedef typename base_type::key_const_pointer key_const_pointer; typedef typename base_type::key_reference key_reference; typedef typename base_type::key_const_reference key_const_reference; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::mapped_pointer mapped_pointer; typedef typename base_type::mapped_const_pointer mapped_const_pointer; typedef typename base_type::mapped_reference mapped_reference; typedef typename base_type::mapped_const_reference mapped_const_reference; 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::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::node_update node_update; PB_DS_S_TREE_NAME(); PB_DS_S_TREE_NAME(const Cmp_Fn&); PB_DS_S_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_S_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); void initialize(); inline std::pair insert(const_reference r_value); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) std::pair ins_pair = insert_leaf_imp(value_type(r_key, mapped_type())); ins_pair.first.m_p_nd->m_special = false; _GLIBCXX_DEBUG_ONLY(base_type::assert_valid(__FILE__, __LINE__)); splay(ins_pair.first.m_p_nd); _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return ins_pair.first.m_p_nd->m_value.second; #else insert(r_key); return base_type::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline bool erase(key_const_reference); inline iterator erase(iterator it); inline reverse_iterator erase(reverse_iterator); template inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); private: inline std::pair insert_leaf_imp(const_reference); inline node_pointer find_imp(key_const_reference); inline const node_pointer find_imp(key_const_reference) const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; void assert_special_imp(const node_pointer, const char* file, int line) const; #endif void splay(node_pointer); inline void splay_zig_zag_left(node_pointer, node_pointer, node_pointer); inline void splay_zig_zag_right(node_pointer, node_pointer, node_pointer); inline void splay_zig_zig_left(node_pointer, node_pointer, node_pointer); inline void splay_zig_zig_right(node_pointer, node_pointer, node_pointer); inline void splay_zz_start(node_pointer, node_pointer, node_pointer); inline void splay_zz_end(node_pointer, node_pointer, node_pointer); inline node_pointer leftmost(node_pointer); void erase_node(node_pointer); }; #define PB_DS_ASSERT_BASE_NODE_CONSISTENT(_Node) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, \ __FILE__, __LINE__);) #include #include #include #include #include #include #include #undef PB_DS_ASSERT_BASE_NODE_CONSISTENT #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_S_TREE_NAME #undef PB_DS_S_TREE_BASE_NAME #undef PB_DS_S_TREE_BASE } // namespace detail } // namespace __gnu_pbds PKgd1] 仧 08/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/debug_fn_imps.hpp * Contains an implementation class for splay_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); const node_pointer p_head = base_type::m_p_head; assert_special_imp(p_head, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_special_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return; if (p_nd == base_type::m_p_head) { PB_DS_DEBUG_VERIFY(p_nd->m_special); assert_special_imp(p_nd->m_p_parent, __file, __line); return; } PB_DS_DEBUG_VERIFY(!p_nd->m_special); assert_special_imp(p_nd->m_p_left, __file, __line); assert_special_imp(p_nd->m_p_right, __file, __line); } #endif PKgd1]  18/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/insert_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) std::pair ins_pair = insert_leaf_imp(r_value); ins_pair.first.m_p_nd->m_special = false; PB_DS_ASSERT_VALID((*this)) splay(ins_pair.first.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ins_pair; } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_leaf_imp(const_reference r_value) { _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid(__FILE__, __LINE__);) if (base_type::m_size == 0) return std::make_pair(base_type::insert_imp_empty(r_value), true); node_pointer p_nd = base_type::m_p_head->m_p_parent; node_pointer p_pot = base_type::m_p_head; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) { if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))) { return std::make_pair(point_iterator(p_nd), false); } p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; if (p_pot == base_type::m_p_head) return std::make_pair(base_type::insert_leaf_new(r_value, base_type::m_p_head->m_p_right, false), true); PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) p_nd = p_pot->m_p_left; if (p_nd == 0) return (std::make_pair(base_type::insert_leaf_new(r_value, p_pot, true), true)); while (p_nd->m_p_right != 0) p_nd = p_nd->m_p_right; return std::make_pair(this->insert_leaf_new(r_value, p_nd, false), true); } PKgd1]es08/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/erase_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = find(r_key); if (it == base_type::end()) return false; erase(it); return true; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == base_type::end()) return it; iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == base_type::m_p_head) return (it); reverse_iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; iterator it = base_type::begin(); while (it != base_type::end()) { if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); splay(p_nd); PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); node_pointer p_l = p_nd->m_p_left; node_pointer p_r = p_nd->m_p_right; base_type::update_min_max_for_erased_node(p_nd); base_type::actual_erase_node(p_nd); if (p_r == 0) { base_type::m_p_head->m_p_parent = p_l; if (p_l != 0) p_l->m_p_parent = base_type::m_p_head; PB_DS_ASSERT_VALID((*this)) return; } node_pointer p_target_r = leftmost(p_r); _GLIBCXX_DEBUG_ASSERT(p_target_r != 0); p_r->m_p_parent = base_type::m_p_head; base_type::m_p_head->m_p_parent = p_r; splay(p_target_r); _GLIBCXX_DEBUG_ONLY(p_target_r->m_p_left = 0); _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_parent == this->m_p_head); _GLIBCXX_DEBUG_ASSERT(this->m_p_head->m_p_parent == p_target_r); p_target_r->m_p_left = p_l; if (p_l != 0) p_l->m_p_parent = p_target_r; PB_DS_ASSERT_VALID((*this)) this->apply_update(p_target_r, (node_update*)this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: leftmost(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); while (p_nd->m_p_left != 0) p_nd = p_nd->m_p_left; return p_nd; } PKgd1]לqq08/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/splay_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: splay(node_pointer p_nd) { while (p_nd->m_p_parent != base_type::m_p_head) { #ifdef _GLIBCXX_DEBUG { node_pointer p_head = base_type::m_p_head; assert_special_imp(p_head, __FILE__, __LINE__); } #endif PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) if (p_nd->m_p_parent->m_p_parent == base_type::m_p_head) { base_type::rotate_parent(p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); } else { const node_pointer p_parent = p_nd->m_p_parent; const node_pointer p_grandparent = p_parent->m_p_parent; #ifdef _GLIBCXX_DEBUG const size_type total = base_type::recursive_count(p_grandparent); _GLIBCXX_DEBUG_ASSERT(total >= 3); #endif if (p_parent->m_p_left == p_nd && p_grandparent->m_p_right == p_parent) splay_zig_zag_left(p_nd, p_parent, p_grandparent); else if (p_parent->m_p_right == p_nd && p_grandparent->m_p_left == p_parent) splay_zig_zag_right(p_nd, p_parent, p_grandparent); else if (p_parent->m_p_left == p_nd && p_grandparent->m_p_left == p_parent) splay_zig_zig_left(p_nd, p_parent, p_grandparent); else splay_zig_zig_right(p_nd, p_parent, p_grandparent); _GLIBCXX_DEBUG_ASSERT(total ==this->recursive_count(p_nd)); } PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zag_left(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && p_grandparent->m_p_right == p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_right; node_pointer p_c = p_nd->m_p_left; p_nd->m_p_right = p_parent; p_parent->m_p_parent = p_nd; p_nd->m_p_left = p_grandparent; p_grandparent->m_p_parent = p_nd; p_parent->m_p_left = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_right = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zag_right(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && p_grandparent->m_p_left == p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_left; node_pointer p_c = p_nd->m_p_right; p_nd->m_p_left = p_parent; p_parent->m_p_parent = p_nd; p_nd->m_p_right = p_grandparent; p_grandparent->m_p_parent = p_nd; p_parent->m_p_right = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_left = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zig_left(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && p_nd->m_p_parent->m_p_parent->m_p_left == p_nd->m_p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_right; node_pointer p_c = p_parent->m_p_right; p_nd->m_p_right = p_parent; p_parent->m_p_parent = p_nd; p_parent->m_p_right = p_grandparent; p_grandparent->m_p_parent = p_parent; p_parent->m_p_left = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_left = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zig_right(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && p_nd->m_p_parent->m_p_parent->m_p_right == p_nd->m_p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_left; node_pointer p_c = p_parent->m_p_left; p_nd->m_p_left = p_parent; p_parent->m_p_parent = p_nd; p_parent->m_p_left = p_grandparent; p_grandparent->m_p_parent = p_parent; p_parent->m_p_right = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_right = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; base_type::update_to_top(p_grandparent, (node_update*)this); splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zz_start(node_pointer p_nd, #ifdef _GLIBCXX_DEBUG node_pointer p_parent, #else node_pointer /*p_parent*/, #endif node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_parent != 0); _GLIBCXX_DEBUG_ASSERT(p_grandparent != 0); const bool grandparent_head = p_grandparent->m_p_parent == base_type::m_p_head; if (grandparent_head) { base_type::m_p_head->m_p_parent = base_type::m_p_head->m_p_parent; p_nd->m_p_parent = base_type::m_p_head; return; } node_pointer p_greatgrandparent = p_grandparent->m_p_parent; p_nd->m_p_parent = p_greatgrandparent; if (p_grandparent == p_greatgrandparent->m_p_left) p_greatgrandparent->m_p_left = p_nd; else p_greatgrandparent->m_p_right = p_nd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zz_end(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { if (p_nd->m_p_parent == base_type::m_p_head) base_type::m_p_head->m_p_parent = p_nd; this->apply_update(p_grandparent, (node_update*)this); this->apply_update(p_parent, (node_update*)this); this->apply_update(p_nd, (node_update*)this); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) } PKgd1]e532258/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/split_join_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::join_prep(other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } node_pointer p_target_r = other.leftmost(other.m_p_head); _GLIBCXX_DEBUG_ASSERT(p_target_r != 0); other.splay(p_target_r); _GLIBCXX_DEBUG_ASSERT(p_target_r == other.m_p_head->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left == 0); p_target_r->m_p_left = base_type::m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left != 0); p_target_r->m_p_left->m_p_parent = p_target_r; base_type::m_p_head->m_p_parent = p_target_r; p_target_r->m_p_parent = base_type::m_p_head; this->apply_update(p_target_r, (node_update*)this); base_type::join_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::split_prep(r_key, other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } node_pointer p_upper_bound = this->upper_bound(r_key).m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_upper_bound != 0); splay(p_upper_bound); _GLIBCXX_DEBUG_ASSERT(p_upper_bound->m_p_parent == this->m_p_head); node_pointer p_new_root = p_upper_bound->m_p_left; _GLIBCXX_DEBUG_ASSERT(p_new_root != 0); base_type::m_p_head->m_p_parent = p_new_root; p_new_root->m_p_parent = base_type::m_p_head; other.m_p_head->m_p_parent = p_upper_bound; p_upper_bound->m_p_parent = other.m_p_head; p_upper_bound->m_p_left = 0; this->apply_update(p_upper_bound, (node_update*)this); base_type::split_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PKgd1]P   )8/ext/pb_ds/detail/splay_tree_/traits.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/traits.hpp * Contains an implementation for splay_tree_. */ #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP PKgd1]MM48/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cc_ht_map_.hpp * Contains an implementation class for cc_ht_map_. */ #include #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #ifdef PB_DS_HT_MAP_TRACE_ #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_CC_HASH_NAME cc_ht_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_CC_HASH_NAME cc_ht_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_CC_HASH_NAME #define PB_DS_HASH_EQ_FN_C_DEC \ hash_eq_fn #define PB_DS_RANGED_HASH_FN_C_DEC \ ranged_hash_fn #define PB_DS_CC_HASH_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base::other::const_reference> #endif /** * A collision-chaining hash-based container. * * * @ingroup hash-detail * * @tparam Key Key type. * * @tparam Mapped Map type. * * @tparam Hash_Fn Hashing functor. * Default is __gnu_cxx::hash. * * @tparam Eq_Fn Equal functor. * Default std::equal_to * * @tparam _Alloc Allocator type. * * @tparam Store_Hash If key type stores extra metadata. * Defaults to false. * * @tparam Comb_Hash_Fn Combining hash functor. * If Hash_Fn is not null_type, then this * is the ranged-hash functor; otherwise, * this is the range-hashing functor. * XXX(See Design::Hash-Based Containers::Hash Policies.) * Default direct_mask_range_hashing. * * @tparam Resize_Policy Resizes hash. * Defaults to hash_standard_resize_policy, * using hash_exponential_size_policy and * hash_load_check_resize_trigger. * * * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_hash_fn, * detail::types_traits. (Optional: detail::debug_map_base.) */ template class PB_DS_CC_HASH_NAME: #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_HASH_EQ_FN_C_DEC, public Resize_Policy, public PB_DS_RANGED_HASH_FN_C_DEC, public PB_DS_CC_HASH_TRAITS_BASE { private: typedef PB_DS_CC_HASH_TRAITS_BASE traits_base; typedef typename traits_base::comp_hash comp_hash; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; struct entry : public traits_base::stored_data_type { typename _Alloc::template rebind::other::pointer m_p_next; }; typedef cond_dealtor cond_dealtor_t; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename _Alloc::template rebind::other entry_pointer_allocator; typedef typename entry_pointer_allocator::pointer entry_pointer_array; typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base; typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; typedef Resize_Policy resize_base; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif #define PB_DS_GEN_POS std::pair #include #include #include #include #undef PB_DS_GEN_POS public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Comb_Hash_Fn comb_hash_fn; typedef Resize_Policy resize_policy; /// Value stores hash, true or false. enum { store_hash = Store_Hash }; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; PB_DS_CC_HASH_NAME(); PB_DS_CC_HASH_NAME(const Hash_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&, const Resize_Policy&); PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC&); virtual ~PB_DS_CC_HASH_NAME(); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); void initialize(); inline size_type size() const; inline size_type max_size() const; /// True if size() == 0. inline bool empty() const; /// Return current hash_fn. Hash_Fn& get_hash_fn(); /// Return current const hash_fn. const Hash_Fn& get_hash_fn() const; /// Return current eq_fn. Eq_Fn& get_eq_fn(); /// Return current const eq_fn. const Eq_Fn& get_eq_fn() const; /// Return current comb_hash_fn. Comb_Hash_Fn& get_comb_hash_fn(); /// Return current const comb_hash_fn. const Comb_Hash_Fn& get_comb_hash_fn() const; /// Return current resize_policy. Resize_Policy& get_resize_policy(); /// Return current const resize_policy. const Resize_Policy& get_resize_policy() const; inline std::pair insert(const_reference r_val) { return insert_imp(r_val, traits_base::m_store_extra_indicator); } inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return (subscript_imp(r_key, traits_base::m_store_extra_indicator)); #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator find_end(); inline point_const_iterator find_end() const; inline bool erase(key_const_reference); template inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace() const; #endif private: void deallocate_all(); inline bool do_resize_if_needed(); inline void do_resize_if_needed_no_throw(); void resize_imp(size_type); void do_resize(size_type); void resize_imp_no_exceptions(size_type, entry_pointer_array, size_type); inline entry_pointer resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, false_type); inline entry_pointer resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, true_type); void deallocate_links_in_list(entry_pointer); inline entry_pointer get_entry(const_reference, false_type); inline entry_pointer get_entry(const_reference, true_type); inline void rels_entry(entry_pointer); #ifdef PB_DS_DATA_TRUE_INDICATOR inline mapped_reference subscript_imp(key_const_reference r_key, false_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) const size_type pos = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return (p_e->m_value.second); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return insert_new_imp(value_type(r_key, mapped_type()), pos)->second; } inline mapped_reference subscript_imp(key_const_reference r_key, true_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return p_e->m_value.second; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return insert_new_imp(value_type(r_key, mapped_type()), pos_hash_pair)->second; } #endif inline std::pair insert_imp(const_reference, false_type); inline std::pair insert_imp(const_reference, true_type); inline pointer insert_new_imp(const_reference r_val, size_type pos) { if (do_resize_if_needed()) pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); // Following lines might throw an exception. entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); // At this point no exceptions can be thrown. p_e->m_p_next = m_entries[pos]; m_entries[pos] = p_e; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) { // Following lines might throw an exception. if (do_resize_if_needed()) r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); // At this point no exceptions can be thrown. p_e->m_hash = r_pos_hash_pair.second; p_e->m_p_next = m_entries[r_pos_hash_pair.first]; m_entries[r_pos_hash_pair.first] = p_e; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer find_key_pointer(key_const_reference r_key, false_type) { entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)]; resize_base::notify_find_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_find_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_find_search_end(); #ifdef _GLIBCXX_DEBUG if (p_e == 0) PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) else PB_DS_CHECK_KEY_EXISTS(r_key) #endif return &p_e->m_value; } inline pointer find_key_pointer(key_const_reference r_key, true_type) { comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_find_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_find_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_find_search_end(); #ifdef _GLIBCXX_DEBUG if (p_e == 0) PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) else PB_DS_CHECK_KEY_EXISTS(r_key) #endif return &p_e->m_value; } inline bool erase_in_pos_imp(key_const_reference, size_type); inline bool erase_in_pos_imp(key_const_reference, const comp_hash&); inline void erase_entry_pointer(entry_pointer&); #ifdef PB_DS_DATA_TRUE_INDICATOR void inc_it_state(pointer& r_p_value, std::pair& r_pos) const { inc_it_state((mapped_const_pointer& )r_p_value, r_pos); } #endif void inc_it_state(const_pointer& r_p_value, std::pair& r_pos) const { _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); r_pos.first = r_pos.first->m_p_next; if (r_pos.first != 0) { r_p_value = &r_pos.first->m_value; return; } for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second) if (m_entries[r_pos.second] != 0) { r_pos.first = m_entries[r_pos.second]; r_p_value = &r_pos.first->m_value; return; } r_p_value = 0; } void get_start_it_state(pointer& r_p_value, std::pair& r_pos) const { for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second) if (m_entries[r_pos.second] != 0) { r_pos.first = m_entries[r_pos.second]; r_p_value = &r_pos.first->m_value; return; } r_p_value = 0; } #ifdef _GLIBCXX_DEBUG void assert_entry_pointer_array_valid(const entry_pointer_array, const char*, int) const; void assert_entry_pointer_valid(const entry_pointer, true_type, const char*, int) const; void assert_entry_pointer_valid(const entry_pointer, false_type, const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace_list(const_entry_pointer) const; #endif private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; static entry_allocator s_entry_allocator; static entry_pointer_allocator s_entry_pointer_allocator; static iterator s_end_it; static const_iterator s_const_end_it; static point_iterator s_find_end_it; static point_const_iterator s_const_find_end_it; size_type m_num_e; size_type m_num_used_e; entry_pointer_array m_entries; enum { store_hash_ok = !Store_Hash || !is_same::value }; PB_DS_STATIC_ASSERT(sth, store_hash_ok); }; #include #include #include #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_HASH_EQ_FN_C_DEC #undef PB_DS_RANGED_HASH_FN_C_DEC #undef PB_DS_CC_HASH_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_CC_HASH_NAME } // namespace detail } // namespace __gnu_pbds PKgd1]v88/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: do_resize_if_needed() { if (!resize_base::is_resize_needed()) return false; resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type len) { resize_imp(resize_base::get_nearest_larger_size(len)); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: do_resize_if_needed_no_throw() { if (!resize_base::is_resize_needed()) return; __try { resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); } __catch(...) { } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(size_type new_size) { PB_DS_ASSERT_VALID((*this)) if (new_size == m_num_e) return; const size_type old_size = m_num_e; entry_pointer_array a_p_entries_resized; // Following line might throw an exception. ranged_hash_fn_base::notify_resized(new_size); __try { // Following line might throw an exception. a_p_entries_resized = s_entry_pointer_allocator.allocate(new_size); m_num_e = new_size; } __catch(...) { ranged_hash_fn_base::notify_resized(old_size); __throw_exception_again; } // At this point no exceptions can be thrown. resize_imp_no_exceptions(new_size, a_p_entries_resized, old_size); Resize_Policy::notify_resized(new_size); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions(size_type new_size, entry_pointer_array a_p_entries_resized, size_type old_size) { std::fill(a_p_entries_resized, a_p_entries_resized + m_num_e, entry_pointer(0)); for (size_type pos = 0; pos < old_size; ++pos) { entry_pointer p_e = m_entries[pos]; while (p_e != 0) p_e = resize_imp_no_exceptions_reassign_pointer(p_e, a_p_entries_resized, traits_base::m_store_extra_indicator); } m_num_e = new_size; _GLIBCXX_DEBUG_ONLY(assert_entry_pointer_array_valid(a_p_entries_resized, __FILE__, __LINE__);) s_entry_pointer_allocator.deallocate(m_entries, old_size); m_entries = a_p_entries_resized; PB_DS_ASSERT_VALID((*this)) } #include #include PKgd1]4F8/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions, when the * hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, false_type) { const size_type hash_pos = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); entry_pointer const p_next_e = p_e->m_p_next; p_e->m_p_next = a_p_entries_resized[hash_pos]; a_p_entries_resized[hash_pos] = p_e; return p_next_e; } PKgd1]A: : E8/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp * Contains a conditional key destructor, used for exception handling. */ namespace __gnu_pbds { namespace detail { /// Conditional dey destructor, cc_hash. template class cond_dealtor { public: typedef typename HT_Map::entry entry; typedef typename HT_Map::entry_allocator entry_allocator; typedef typename HT_Map::key_type key_type; cond_dealtor(entry_allocator* p_a, entry* p_e) : m_p_a(p_a), m_p_e(p_e), m_key_destruct(false), m_no_action_destructor(false) { } inline ~cond_dealtor(); void set_key_destruct() { m_key_destruct = true; } void set_no_action_destructor() { m_no_action_destructor = true; } protected: entry_allocator* const m_p_a; entry* const m_p_e; bool m_key_destruct; bool m_no_action_destructor; }; template inline cond_dealtor:: ~cond_dealtor() { if (m_no_action_destructor) return; if (m_key_destruct) m_p_e->m_value.first.~key_type(); m_p_a->deallocate(m_p_e, 1); } } // namespace detail } // namespace __gnu_pbds PKgd1] E8/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return erase_in_pos_imp(r_key, ranged_hash_fn_base::operator()(r_key)); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_in_pos_imp(key_const_reference r_key, size_type pos) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_e = m_entries[pos]; resize_base::notify_erase_search_start(); if (p_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(m_entries[pos]); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } while (true) { entry_pointer p_next_e = p_e->m_p_next; if (p_next_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), r_key)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(p_e->m_p_next); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } resize_base::notify_erase_search_collision(); p_e = p_next_e; } } PKgd1] 9: : F8/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, false_type) { PB_DS_ASSERT_VALID((*this)) key_const_reference r_key = PB_DS_V2F(r_val); const size_type pos = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos), true); } PKgd1]E}; ; 78/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/trace_fn_imps.hpp * Contains implementations of cc_ht_map_'s trace-mode functions. */ #ifdef PB_DS_HT_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << static_cast(m_num_e) << " " << static_cast(m_num_used_e) << std::endl; for (size_type i = 0; i < m_num_e; ++i) { std::cerr << static_cast(i) << " "; trace_list(m_entries[i]); std::cerr << std::endl; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_list(const_entry_pointer p_l) const { size_type iterated_num_used_e = 0; while (p_l != 0) { std::cerr << PB_DS_V2F(p_l->m_value) << " "; p_l = p_l->m_p_next; } } #endif PKgd1]vƟH8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_pointer_allocator PB_DS_CLASS_C_DEC::s_entry_pointer_allocator; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME() : ranged_hash_fn_base(resize_base::get_nearest_larger_size(1)), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn) : ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { std::fill(m_entries, m_entries + m_num_e, (entry_pointer)0); Resize_Policy::notify_cleared(); ranged_hash_fn_base::notify_resized(m_num_e); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn, const Resize_Policy& r_resize_policy) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), Resize_Policy(r_resize_policy), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : PB_DS_HASH_EQ_FN_C_DEC(other), resize_base(other), ranged_hash_fn_base(other), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) __try { copy_from_range(other.begin(), other.end()); } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_CC_HASH_NAME() { deallocate_all(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) std::swap(m_entries, other.m_entries); std::swap(m_num_e, other.m_num_e); std::swap(m_num_used_e, other.m_num_used_e); ranged_hash_fn_base::swap(other); hash_eq_fn_base::swap(other); resize_base::swap(other); _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { clear(); s_entry_pointer_allocator.deallocate(m_entries, m_num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { std::fill(m_entries, m_entries + m_num_e, entry_pointer(0)); Resize_Policy::notify_resized(m_num_e); Resize_Policy::notify_cleared(); ranged_hash_fn_base::notify_resized(m_num_e); } PKgd1]1 ?8/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/policy_access_fn_imps.hpp * Contains implementations of cc_ht_map_'s policy access * functions. */ PB_DS_CLASS_T_DEC Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() { return *this; } PB_DS_CLASS_T_DEC const Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() const { return *this; } PB_DS_CLASS_T_DEC Comb_Hash_Fn& PB_DS_CLASS_C_DEC:: get_comb_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Comb_Hash_Fn& PB_DS_CLASS_C_DEC:: get_comb_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() { return *this; } PB_DS_CLASS_T_DEC const Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() const { return *this; } PKgd1]vA8/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/find_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s find related functions, * when the hash value is stored. */ PKgd1]m' ' 68/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/info_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container info related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return m_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator==(const Other_HT_Map_Type& other) const { return cmp_with_other(other); } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: cmp_with_other(const Other_Map_Type& other) const { if (size() != other.size()) return false; for (typename Other_Map_Type::const_iterator it = other.begin(); it != other.end(); ++it) { key_const_reference r_key =(key_const_reference)PB_DS_V2F(*it); mapped_const_pointer p_mapped_value = const_cast(*this). find_key_pointer(r_key, traits_base::m_store_extra_indicator); if (p_mapped_value == 0) return false; #ifdef PB_DS_DATA_TRUE_INDICATOR if (p_mapped_value->second != it->second) return false; #endif } return true; } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator!=(const Other_HT_Map_Type& other) const { return !operator==(other); } PKgd1]Cs 68/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/find_fn_imps.hpp * Contains implementations of cc_ht_map_'s find related functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) return const_cast(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find_end() { return 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find_end() const { return 0; } PKgd1]׳h h ;8/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/iterators_fn_imps.hpp * Contains implementations of cc_ht_map_'s iterators related functions, e.g., * begin(). */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC::s_end_it; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC::s_const_end_it; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { pointer p_value; std::pair pos; get_start_it_state(p_value, pos); return iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return s_end_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { pointer p_value; std::pair pos; get_start_it_state(p_value, pos); return const_iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return s_const_end_it; } PKgd1]W, <8/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/entry_list_fn_imps.hpp * Contains implementations of cc_ht_map_'s entry-list related functions. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_links_in_list(entry_pointer p_e) { while (p_e != 0) { entry_pointer p_dealloc_e = p_e; p_e = p_e->m_p_next; s_entry_allocator.deallocate(p_dealloc_e, 1); } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: get_entry(const_reference r_val, true_type) { // Following line might throw an exception. entry_pointer p_e = s_entry_allocator.allocate(1); // Following lines* cannot* throw an exception. new (&p_e->m_value) value_type(r_val); return p_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: get_entry(const_reference r_val, false_type) { // Following line might throw an exception. entry_pointer p_e = s_entry_allocator.allocate(1); cond_dealtor_t cond(p_e); // Following lines might throw an exception. new (&p_e->m_value) value_type(r_val); cond.set_no_action(); return p_e; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rels_entry(entry_pointer p_e) { // The following lines cannot throw exceptions (unless if key-data dtors do). p_e->m_value.~value_type(); s_entry_allocator.deallocate(p_e, 1); } PKgd1]>  S8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(const_reference r_val, size_type pos, true_type) { // Following lines might throw an exception. entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); // At this point no exceptions can be thrown. p->m_p_next = m_entries[pos]; p->m_hash = ranged_hash_fn_base::operator()((key_const_reference)(PB_DS_V2F(p->m_value))).second; m_entries[pos] = p; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(r_key);) } PKgd1] l 78/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { debug_base::check_size(m_num_used_e, __file, __line); assert_entry_pointer_array_valid(m_entries, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_array_valid(const entry_pointer_array a_p_entries, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = a_p_entries[pos]; while (p_e != 0) { ++iterated_num_used_e; assert_entry_pointer_valid(p_e, traits_base::m_store_extra_indicator, __file, __line); p_e = p_e->m_p_next; } } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #include #include #endif PKgd1]뾏hh88/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions. */ #include #include PKgd1]? 78/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_entry_pointer(entry_pointer& r_p_e) { _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(r_p_e->m_value))); entry_pointer p_e = r_p_e; r_p_e = r_p_e->m_p_next; rels_entry(p_e); _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); resize_base::notify_erased(--m_num_used_e); } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { size_type num_ersd = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { while (m_entries[pos] != 0 && pred(m_entries[pos]->m_value)) { ++num_ersd; entry_pointer p_next_e = m_entries[pos]->m_p_next; erase_entry_pointer(m_entries[pos]); m_entries[pos] = p_next_e; } entry_pointer p_e = m_entries[pos]; while (p_e != 0 && p_e->m_p_next != 0) { if (pred(p_e->m_p_next->m_value)) { ++num_ersd; erase_entry_pointer(p_e->m_p_next); } else p_e = p_e->m_p_next; } } do_resize_if_needed_no_throw(); return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type pos = 0; pos < m_num_e; ++pos) while (m_entries[pos] != 0) erase_entry_pointer(m_entries[pos]); do_resize_if_needed_no_throw(); resize_base::notify_cleared(); } #include #include PKgd1]E8/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_valid(const entry_pointer p, false_type, const char* __file, int __line) const { debug_base::check_key_exists(PB_DS_V2F(p->m_value), __file, __line); } #endif PKgd1]ִ ==68/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/size_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container size related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PKgd1]C.C8/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions, when the * hash value is stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, true_type) { const comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash); entry_pointer const p_next_e = p_e->m_p_next; p_e->m_p_next = a_p_entries_resized[pos_hash_pair.first]; a_p_entries_resized[pos_hash_pair.first] = p_e; return p_next_e; } PKgd1]/r r C8/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, true_type) { PB_DS_ASSERT_VALID((*this)) key_const_reference key = PB_DS_V2F(r_val); comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, key, pos_hash_pair.second)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); } PKgd1]^YddB8/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_valid(const entry_pointer p_e, true_type, const char* __file, int __line) const { debug_base::check_key_exists(PB_DS_V2F(p_e->m_value), __file, __line); comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); PB_DS_DEBUG_VERIFY(p_e->m_hash == pos_hash_pair.second); } #endif PKgd1]& EV8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, false_type) { // Following lines might throw an exception. entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); // At this point no exceptions can be thrown. p->m_p_next = m_entries[pos]; m_entries[pos] = p; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(r_key);) } PKgd1]Զ) B8/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_in_pos_imp(key_const_reference r_key, const comp_hash& r_pos_hash_pair) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_e = m_entries[r_pos_hash_pair.first]; resize_base::notify_erase_search_start(); if (p_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, r_pos_hash_pair.second)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(m_entries[r_pos_hash_pair.first]); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } while (true) { entry_pointer p_next_e = p_e->m_p_next; if (p_next_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), p_next_e->m_hash, r_key, r_pos_hash_pair.second)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(p_e->m_p_next); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } resize_base::notify_erase_search_collision(); p_e = p_next_e; } } PKgd1] 58/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cmp_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container comparison related * functions. */ PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator==(const Other_HT_Map_Type& other) const { return cmp_with_other(other); } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: cmp_with_other(const Other_Map_Type& other) const { if (size() != other.size()) return false; for (typename Other_Map_Type::const_iterator it = other.begin(); it != other.end(); ++it) { key_const_reference r_key = key_const_reference(PB_DS_V2F(*it)); mapped_const_pointer p_mapped_value = const_cast(*this). find_key_pointer(r_key, traits_base::m_store_extra_indicator); if (p_mapped_value == 0) return false; #ifdef PB_DS_DATA_TRUE_INDICATOR if (p_mapped_value->second != it->second) return false; #endif } return true; } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator!=(const Other_HT_Map_Type& other) const { return !operator==(other); } PKgd1]q~~8/ext/pb_ds/priority_queue.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file priority_queue.hpp * Contains priority_queues. */ #ifndef PB_DS_PRIORITY_QUEUE_HPP #define PB_DS_PRIORITY_QUEUE_HPP #include #include #include #include namespace __gnu_pbds { /** * @defgroup heap-based Heap-Based * @ingroup containers-pbds * @{ */ /** * @defgroup heap-detail Base and Policy Classes * @ingroup heap-based */ /** * A priority queue composed of one specific heap policy. * * @tparam _Tv Value type. * @tparam Cmp_Fn Comparison functor. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: binary_heap_tag, binomial_heap_tag, pairing_heap_tag, * rc_binomial_heap_tag, thin_heap_tag * * Base choices are: detail::binary_heap, detail::binomial_heap, * detail::pairing_heap, detail::rc_binomial_heap, * detail::thin_heap. */ template, typename Tag = pairing_heap_tag, typename _Alloc = std::allocator > class priority_queue : public detail::container_base_dispatch<_Tv, Cmp_Fn, _Alloc, Tag>::type { public: typedef _Tv value_type; typedef Cmp_Fn cmp_fn; typedef Tag container_category; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; private: typedef typename detail::container_base_dispatch<_Tv, Cmp_Fn, _Alloc, Tag>::type base_type; typedef typename _Alloc::template rebind<_Tv> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; priority_queue() { } /// Constructor taking some policy objects. r_cmp_fn will be /// copied by the Cmp_Fn object of the container object. priority_queue(const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template priority_queue(It first_it, It last_it) { base_type::copy_from_range(first_it, last_it); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_cmp_fn /// will be copied by the cmp_fn object of the container object. template priority_queue(It first_it, It last_it, const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { base_type::copy_from_range(first_it, last_it); } priority_queue(const priority_queue& other) : base_type((const base_type& )other) { } virtual ~priority_queue() { } priority_queue& operator=(const priority_queue& other) { if (this != &other) { priority_queue tmp(other); swap(tmp); } return *this; } void swap(priority_queue& other) { base_type::swap(other); } }; } // namespace __gnu_pbds //@} heap-based #endif PKgd1]8p//8/ext/pb_ds/trie_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy.hpp * Contains trie-related policies. */ #ifndef PB_DS_TRIE_POLICY_HPP #define PB_DS_TRIE_POLICY_HPP #include #include #include #include namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ trie_string_access_traits /** * Element access traits for string types. * * @tparam String String type. * @tparam Min_E_Val Minimal element value. * @tparam Max_E_Val Maximum element value. * @tparam Reverse Reverse iteration should be used. * Default: false. * @tparam _Alloc Allocator type. */ template::__min, typename String::value_type Max_E_Val = detail::__numeric_traits::__max, bool Reverse = false, typename _Alloc = std::allocator > struct trie_string_access_traits { public: typedef typename _Alloc::size_type size_type; typedef String key_type; typedef typename _Alloc::template rebind __rebind_k; typedef typename __rebind_k::other::const_reference key_const_reference; enum { reverse = Reverse }; /// Element const iterator type. typedef typename detail::__conditional_type::__type const_iterator; /// Element type. typedef typename std::iterator_traits::value_type e_type; enum { min_e_val = Min_E_Val, max_e_val = Max_E_Val, max_size = max_e_val - min_e_val + 1 }; PB_DS_STATIC_ASSERT(min_max_size, max_size >= 2); /// Returns a const_iterator to the first element of /// key_const_reference agumnet. inline static const_iterator begin(key_const_reference); /// Returns a const_iterator to the after-last element of /// key_const_reference argument. inline static const_iterator end(key_const_reference); /// Maps an element to a position. inline static size_type e_pos(e_type e); private: inline static const_iterator begin_imp(key_const_reference, detail::false_type); inline static const_iterator begin_imp(key_const_reference, detail::true_type); inline static const_iterator end_imp(key_const_reference, detail::false_type); inline static const_iterator end_imp(key_const_reference, detail::true_type); static detail::integral_constant s_rev_ind; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ trie_prefix_search_node_update #define PB_DS_TRIE_POLICY_BASE \ detail::trie_policy_base /// A node updator that allows tries to be searched for the range of /// values that match a certain prefix. template class trie_prefix_search_node_update : private PB_DS_TRIE_POLICY_BASE { private: typedef PB_DS_TRIE_POLICY_BASE base_type; public: typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; /// Element access traits. typedef _ATraits access_traits; /// Const element iterator. typedef typename access_traits::const_iterator a_const_iterator; /// _Alloc type. typedef _Alloc allocator_type; /// Size type. typedef typename allocator_type::size_type size_type; typedef null_type metadata_type; typedef Node_Itr node_iterator; typedef Node_CItr node_const_iterator; typedef typename node_iterator::value_type iterator; typedef typename node_const_iterator::value_type const_iterator; /// Finds the const iterator range corresponding to all values /// whose prefixes match r_key. std::pair prefix_range(key_const_reference) const; /// Finds the iterator range corresponding to all values whose /// prefixes match r_key. std::pair prefix_range(key_const_reference); /// Finds the const iterator range corresponding to all values /// whose prefixes match [b, e). std::pair prefix_range(a_const_iterator, a_const_iterator) const; /// Finds the iterator range corresponding to all values whose /// prefixes match [b, e). std::pair prefix_range(a_const_iterator, a_const_iterator); protected: /// Called to update a node's metadata. inline void operator()(node_iterator node_it, node_const_iterator end_nd_it) const; private: node_iterator next_child(node_iterator, a_const_iterator, a_const_iterator, node_iterator, const access_traits&); /// Returns the const iterator associated with the just-after last element. virtual const_iterator end() const = 0; /// Returns the iterator associated with the just-after last element. virtual iterator end() = 0; /// Returns the node_const_iterator associated with the trie's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the trie's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual const access_traits& get_access_traits() const = 0; }; #include #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_C_DEC \ trie_order_statistics_node_update /// Functor updating ranks of entrees. template class trie_order_statistics_node_update : private PB_DS_TRIE_POLICY_BASE { private: typedef PB_DS_TRIE_POLICY_BASE base_type; public: typedef _ATraits access_traits; typedef typename access_traits::const_iterator a_const_iterator; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; typedef size_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; /// Finds an entry by __order. Returns a const_iterator to the /// entry with the __order order, or a const_iterator to the /// container object's end if order is at least the size of the /// container object. inline const_iterator find_by_order(size_type) const; /// Finds an entry by __order. Returns an iterator to the entry /// with the __order order, or an iterator to the container /// object's end if order is at least the size of the container /// object. inline iterator find_by_order(size_type); /// Returns the order of a key within a sequence. For exapmle, if /// r_key is the smallest key, this method will return 0; if r_key /// is a key between the smallest and next key, this method will /// return 1; if r_key is a key larger than the largest key, this /// method will return the size of r_c. inline size_type order_of_key(key_const_reference) const; /// Returns the order of a prefix within a sequence. For exapmle, /// if [b, e] is the smallest prefix, this method will return 0; if /// r_key is a key between the smallest and next key, this method /// will return 1; if r_key is a key larger than the largest key, /// this method will return the size of r_c. inline size_type order_of_prefix(a_const_iterator, a_const_iterator) const; protected: /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; private: typedef typename base_type::const_reference const_reference; typedef typename base_type::const_pointer const_pointer; typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename __rebind_ma::const_reference metadata_const_reference; typedef typename __rebind_ma::reference metadata_reference; /// Returns true if the container is empty. virtual bool empty() const = 0; /// Returns the iterator associated with the trie's first element. virtual iterator begin() = 0; /// Returns the iterator associated with the trie's /// just-after-last element. virtual iterator end() = 0; /// Returns the node_const_iterator associated with the trie's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the trie's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after /// leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual access_traits& get_access_traits() = 0; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_TRIE_POLICY_BASE } // namespace __gnu_pbds #endif PKgd1]W^AA8/ext/pb_ds/hash_policy.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_policy.hpp * Contains hash-related policies. */ #ifndef PB_DS_HASH_POLICY_HPP #define PB_DS_HASH_POLICY_HPP #include #include #include #include #include #include #include #include #include namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC linear_probe_fn /// A probe sequence policy using fixed increments. template class linear_probe_fn { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: /// Returns the i-th offset from the hash value. inline size_type operator()(size_type i) const; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC quadratic_probe_fn /// A probe sequence policy using square increments. template class quadratic_probe_fn { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: /// Returns the i-th offset from the hash value. inline size_type operator()(size_type i) const; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC direct_mask_range_hashing /// A mask range-hashing class (uses a bitmask). template class direct_mask_range_hashing : public detail::mask_based_range_hashing { private: typedef detail::mask_based_range_hashing mask_based_base; public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: void notify_resized(size_type size); /// Transforms the __hash value hash into a ranged-hash value /// (using a bit-mask). inline size_type operator()(size_type hash) const; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC direct_mod_range_hashing /// A mod range-hashing class (uses the modulo function). template class direct_mod_range_hashing : public detail::mod_based_range_hashing { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: void notify_resized(size_type size); /// Transforms the __hash value hash into a ranged-hash value /// (using a modulo operation). inline size_type operator()(size_type hash) const; private: typedef detail::mod_based_range_hashing mod_based_base; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger #define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base /// A resize trigger policy based on a load check. It keeps the /// load factor between some load factors load_min and load_max. template class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC { public: typedef Size_Type size_type; enum { /// Specifies whether the load factor can be accessed /// externally. The two options have different trade-offs in /// terms of flexibility, genericity, and encapsulation. external_load_access = External_Load_Access }; /// Default constructor, or constructor taking load_min and /// load_max load factors between which this policy will keep the /// actual load. hash_load_check_resize_trigger(float load_min = 0.125, float load_max = 0.5); void swap(hash_load_check_resize_trigger& other); virtual ~hash_load_check_resize_trigger(); /// Returns a pair of the minimal and maximal loads, respectively. inline std::pair get_loads() const; /// Sets the loads through a pair of the minimal and maximal /// loads, respectively. void set_loads(std::pair load_pair); protected: inline void notify_insert_search_start(); inline void notify_insert_search_collision(); inline void notify_insert_search_end(); inline void notify_find_search_start(); inline void notify_find_search_collision(); inline void notify_find_search_end(); inline void notify_erase_search_start(); inline void notify_erase_search_collision(); inline void notify_erase_search_end(); /// Notifies an element was inserted. The total number of entries /// in the table is num_entries. inline void notify_inserted(size_type num_entries); inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); void notify_externally_resized(size_type new_size); inline bool is_resize_needed() const; inline bool is_grow_needed(size_type size, size_type num_entries) const; private: virtual void do_resize(size_type new_size); typedef PB_DS_SIZE_BASE_C_DEC size_base; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; #endif float m_load_min; float m_load_max; size_type m_next_shrink_size; size_type m_next_grow_size; bool m_resize_needed; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_SIZE_BASE_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger /// A resize trigger policy based on collision checks. It keeps the /// simulated load factor lower than some given load factor. template class cc_hash_max_collision_check_resize_trigger { public: typedef Size_Type size_type; enum { /// Specifies whether the load factor can be accessed /// externally. The two options have different trade-offs in /// terms of flexibility, genericity, and encapsulation. external_load_access = External_Load_Access }; /// Default constructor, or constructor taking load, a __load /// factor which it will attempt to maintain. cc_hash_max_collision_check_resize_trigger(float load = 0.5); void swap(PB_DS_CLASS_C_DEC& other); /// Returns the current load. inline float get_load() const; /// Sets the load; does not resize the container. void set_load(float load); protected: /// Notifies an insert search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a find search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies an erase search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. inline void notify_inserted(size_type num_entries); /// Notifies an element was erased. inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); /// Notifies the table was resized externally. void notify_externally_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries whether a grow is needed. This method is called only /// if this object indicated is needed. inline bool is_grow_needed(size_type size, size_type num_entries) const; private: void calc_max_num_coll(); inline void calc_resize_needed(); float m_load; size_type m_size; size_type m_num_col; size_type m_max_col; bool m_resize_needed; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC hash_exponential_size_policy /// A size policy whose sequence of sizes form an exponential /// sequence (typically powers of 2. template class hash_exponential_size_policy { public: typedef Size_Type size_type; /// Default constructor, or onstructor taking a start_size, or /// constructor taking a start size and grow_factor. The policy /// will use the sequence of sizes start_size, start_size* /// grow_factor, start_size* grow_factor^2, ... hash_exponential_size_policy(size_type start_size = 8, size_type grow_factor = 2); void swap(PB_DS_CLASS_C_DEC& other); protected: size_type get_nearest_larger_size(size_type size) const; size_type get_nearest_smaller_size(size_type size) const; private: size_type m_start_size; size_type m_grow_factor; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC #define PB_DS_CLASS_C_DEC hash_prime_size_policy /// A size policy whose sequence of sizes form a nearly-exponential /// sequence of primes. class hash_prime_size_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor, or onstructor taking a start_size The /// policy will use the sequence of sizes approximately /// start_size, start_size* 2, start_size* 2^2, ... hash_prime_size_policy(size_type start_size = 8); inline void swap(PB_DS_CLASS_C_DEC& other); protected: size_type get_nearest_larger_size(size_type size) const; size_type get_nearest_smaller_size(size_type size) const; private: size_type m_start_size; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC hash_standard_resize_policy /// A resize policy which delegates operations to size and trigger policies. template, typename Trigger_Policy = hash_load_check_resize_trigger<>, bool External_Size_Access = false, typename Size_Type = std::size_t> class hash_standard_resize_policy : public Size_Policy, public Trigger_Policy { public: typedef Size_Type size_type; typedef Trigger_Policy trigger_policy; typedef Size_Policy size_policy; enum { external_size_access = External_Size_Access }; /// Default constructor. hash_standard_resize_policy(); /// constructor taking some policies r_size_policy will be copied /// by the Size_Policy object of this object. hash_standard_resize_policy(const Size_Policy& r_size_policy); /// constructor taking some policies. r_size_policy will be /// copied by the Size_Policy object of this /// object. r_trigger_policy will be copied by the Trigger_Policy /// object of this object. hash_standard_resize_policy(const Size_Policy& r_size_policy, const Trigger_Policy& r_trigger_policy); virtual ~hash_standard_resize_policy(); inline void swap(PB_DS_CLASS_C_DEC& other); /// Access to the Size_Policy object used. Size_Policy& get_size_policy(); /// Const access to the Size_Policy object used. const Size_Policy& get_size_policy() const; /// Access to the Trigger_Policy object used. Trigger_Policy& get_trigger_policy(); /// Access to the Trigger_Policy object used. const Trigger_Policy& get_trigger_policy() const; /// Returns the actual size of the container. inline size_type get_actual_size() const; /// Resizes the container to suggested_new_size, a suggested size /// (the actual size will be determined by the Size_Policy /// object). void resize(size_type suggested_new_size); protected: inline void notify_insert_search_start(); inline void notify_insert_search_collision(); inline void notify_insert_search_end(); inline void notify_find_search_start(); inline void notify_find_search_collision(); inline void notify_find_search_end(); inline void notify_erase_search_start(); inline void notify_erase_search_collision(); inline void notify_erase_search_end(); inline void notify_inserted(size_type num_e); inline void notify_erased(size_type num_e); void notify_cleared(); void notify_resized(size_type new_size); inline bool is_resize_needed() const; /// Queries what the new size should be, when the container is /// resized naturally. The current __size of the container is /// size, and the number of used entries within the container is /// num_used_e. size_type get_new_size(size_type size, size_type num_used_e) const; private: /// Resizes to new_size. virtual void do_resize(size_type new_size); typedef Trigger_Policy trigger_policy_base; typedef Size_Policy size_policy_base; size_type m_size; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace __gnu_pbds #endif PKgd1]AƖuu8/ext/pb_ds/assoc_container.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file assoc_container.hpp * Contains associative containers. */ #ifndef PB_DS_ASSOC_CNTNR_HPP #define PB_DS_ASSOC_CNTNR_HPP #include #include #include #include #include #include namespace __gnu_pbds { /** * @defgroup containers-pbds Containers * @ingroup pbds * @{ */ /** * @defgroup hash-based Hash-Based * @ingroup containers-pbds * @{ */ #define PB_DS_HASH_BASE \ detail::container_base_dispatch >::type, Policy_Tl>::type>::type /** * @defgroup hash-detail Base and Policy Classes * @ingroup hash-based */ /** * A hashed container abstraction. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Policy_TL Policy typelist. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: cc_hash_tag, gp_hash_tag, and descendants of basic_hash_tag. * * Base choices are: detail::cc_ht_map, detail::gp_ht_map */ template class basic_hash_table : public PB_DS_HASH_BASE { private: typedef typename PB_DS_HASH_BASE base_type; public: virtual ~basic_hash_table() { } protected: basic_hash_table() { } basic_hash_table(const basic_hash_table& other) : base_type((const base_type&)other) { } template basic_hash_table(T0 t0) : base_type(t0) { } template basic_hash_table(T0 t0, T1 t1) : base_type(t0, t1) { } template basic_hash_table(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3) : base_type(t0, t1, t2, t3) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) : base_type(t0, t1, t2, t3, t4) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : base_type(t0, t1, t2, t3, t4, t5) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) : base_type(t0, t1, t2, t3, t4, t5, t6) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : base_type(t0, t1, t2, t3, t4, t5, t6, t7) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) : base_type(t0, t1, t2, t3, t4, t5, t6, t7, t8) { } private: basic_hash_table& operator=(const base_type&); }; #undef PB_DS_HASH_BASE #define PB_DS_CC_HASH_BASE \ basic_hash_table::type, _Alloc> /** * A collision-chaining hash-based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Comb_Hash_Fn Combining hash functor. * If Hash_Fn is not null_type, then this * is the ranged-hash functor; otherwise, * this is the range-hashing functor. * XXX(See Design::Hash-Based Containers::Hash Policies.) * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * If Hash_Fn is null_type, then the * container will not compile if this * value is true * @tparam _Alloc Allocator type. * * Base tag choices are: cc_hash_tag. * * Base is basic_hash_table. */ template::type, typename Eq_Fn = typename detail::default_eq_fn::type, typename Comb_Hash_Fn = detail::default_comb_hash_fn::type, typename Resize_Policy = typename detail::default_resize_policy::type, bool Store_Hash = detail::default_store_hash, typename _Alloc = std::allocator > class cc_hash_table : public PB_DS_CC_HASH_BASE { private: typedef PB_DS_CC_HASH_BASE base_type; public: typedef cc_hash_tag container_category; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Resize_Policy resize_policy; typedef Comb_Hash_Fn comb_hash_fn; /// Default constructor. cc_hash_table() { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the Hash_Fn object of the container object. cc_hash_table(const hash_fn& h) : base_type(h) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, and /// r_eq_fn will be copied by the eq_fn object of the container /// object. cc_hash_table(const hash_fn& h, const eq_fn& e) : base_type(h, e) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// and r_comb_hash_fn will be copied by the comb_hash_fn object /// of the container object. cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) : base_type(h, e, ch) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_hash_fn will be copied by the comb_hash_fn object of /// the container object, and r_resize_policy will be copied by /// the resize_policy object of the container object. cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, const resize_policy& rp) : base_type(h, e, ch, rp) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template cc_hash_table(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. template cc_hash_table(It first, It last, const hash_fn& h) : base_type(h) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// and r_eq_fn will be copied by the eq_fn object of the /// container object. template cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) : base_type(h, e) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, and r_comb_hash_fn will be copied by the comb_hash_fn /// object of the container object. template cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) : base_type(h, e, ch) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_hash_fn will be copied by the comb_hash_fn /// object of the container object, and r_resize_policy will be /// copied by the resize_policy object of the container object. template cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, const resize_policy& rp) : base_type(h, e, ch, rp) { this->copy_from_range(first, last); } cc_hash_table(const cc_hash_table& other) : base_type((const base_type&)other) { } virtual ~cc_hash_table() { } cc_hash_table& operator=(const cc_hash_table& other) { if (this != &other) { cc_hash_table tmp(other); swap(tmp); } return *this; } void swap(cc_hash_table& other) { base_type::swap(other); } }; #undef PB_DS_CC_HASH_BASE #define PB_DS_GP_HASH_BASE \ basic_hash_table::type, _Alloc> /** * A general-probing hash-based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Comb_Probe_Fn Combining probe functor. * If Hash_Fn is not null_type, then this * is the ranged-probe functor; otherwise, * this is the range-hashing functor. * XXX See Design::Hash-Based Containers::Hash Policies. * @tparam Probe_Fn Probe functor. * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * If Hash_Fn is null_type, then the * container will not compile if this * value is true * @tparam _Alloc Allocator type. * * Base tag choices are: gp_hash_tag. * * Base is basic_hash_table. */ template::type, typename Eq_Fn = typename detail::default_eq_fn::type, typename Comb_Probe_Fn = detail::default_comb_hash_fn::type, typename Probe_Fn = typename detail::default_probe_fn::type, typename Resize_Policy = typename detail::default_resize_policy::type, bool Store_Hash = detail::default_store_hash, typename _Alloc = std::allocator > class gp_hash_table : public PB_DS_GP_HASH_BASE { private: typedef PB_DS_GP_HASH_BASE base_type; public: typedef gp_hash_tag container_category; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Comb_Probe_Fn comb_probe_fn; typedef Probe_Fn probe_fn; typedef Resize_Policy resize_policy; /// Default constructor. gp_hash_table() { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object. gp_hash_table(const hash_fn& h) : base_type(h) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, and /// r_eq_fn will be copied by the eq_fn object of the container /// object. gp_hash_table(const hash_fn& h, const eq_fn& e) : base_type(h, e) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// and r_comb_probe_fn will be copied by the comb_probe_fn object /// of the container object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) : base_type(h, e, cp) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_probe_fn will be copied by the comb_probe_fn object of /// the container object, and r_probe_fn will be copied by the /// probe_fn object of the container object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p) : base_type(h, e, cp, p) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_probe_fn will be copied by the comb_probe_fn object of /// the container object, r_probe_fn will be copied by the /// probe_fn object of the container object, and r_resize_policy /// will be copied by the Resize_Policy object of the container /// object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p, const resize_policy& rp) : base_type(h, e, cp, p, rp) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template gp_hash_table(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object. template gp_hash_table(It first, It last, const hash_fn& h) : base_type(h) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// and r_eq_fn will be copied by the eq_fn object of the /// container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) : base_type(h, e) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, and r_comb_probe_fn will be copied by the /// comb_probe_fn object of the container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) : base_type(h, e, cp) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_probe_fn will be copied by the comb_probe_fn /// object of the container object, and r_probe_fn will be copied /// by the probe_fn object of the container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p) : base_type(h, e, cp, p) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_probe_fn will be copied by the comb_probe_fn /// object of the container object, r_probe_fn will be copied by /// the probe_fn object of the container object, and /// r_resize_policy will be copied by the resize_policy object of /// the container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p, const resize_policy& rp) : base_type(h, e, cp, p, rp) { base_type::copy_from_range(first, last); } gp_hash_table(const gp_hash_table& other) : base_type((const base_type&)other) { } virtual ~gp_hash_table() { } gp_hash_table& operator=(const gp_hash_table& other) { if (this != &other) { gp_hash_table tmp(other); swap(tmp); } return *this; } void swap(gp_hash_table& other) { base_type::swap(other); } }; //@} hash-based #undef PB_DS_GP_HASH_BASE /** * @defgroup branch-based Branch-Based * @ingroup containers-pbds * @{ */ #define PB_DS_BRANCH_BASE \ detail::container_base_dispatch::type /** * @defgroup branch-detail Base and Policy Classes * @ingroup branch-based */ /** * A branched, tree-like (tree, trie) container abstraction. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates nodes, restores invariants. * @tparam Policy_TL Policy typelist. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: tree_tag, trie_tag, and their descendants. * * Base choices are: detail::ov_tree_map, detail::rb_tree_map, * detail::splay_tree_map, and detail::pat_trie_map. */ template class basic_branch : public PB_DS_BRANCH_BASE { private: typedef typename PB_DS_BRANCH_BASE base_type; public: typedef Node_Update node_update; virtual ~basic_branch() { } protected: basic_branch() { } basic_branch(const basic_branch& other) : base_type((const base_type&)other) { } template basic_branch(T0 t0) : base_type(t0) { } template basic_branch(T0 t0, T1 t1) : base_type(t0, t1) { } template basic_branch(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3) : base_type(t0, t1, t2, t3) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) : base_type(t0, t1, t2, t3, t4) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : base_type(t0, t1, t2, t3, t4, t5) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) : base_type(t0, t1, t2, t3, t4, t5, t6) { } }; #undef PB_DS_BRANCH_BASE #define PB_DS_TREE_NODE_AND_IT_TRAITS \ detail::tree_traits #define PB_DS_TREE_BASE \ basic_branch::type, _Alloc> /** * A tree-based container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Cmp_Fn Comparison functor. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates tree internal-nodes, * restores invariants when invalidated. * XXX See design::tree-based-containers::node invariants. * @tparam _Alloc Allocator type. * * Base tag choices are: ov_tree_tag, rb_tree_tag, splay_tree_tag. * * Base is basic_branch. */ template, typename Tag = rb_tree_tag, template class Node_Update = null_node_update, typename _Alloc = std::allocator > class tree : public PB_DS_TREE_BASE { private: typedef PB_DS_TREE_BASE base_type; public: /// Comparison functor type. typedef Cmp_Fn cmp_fn; tree() { } /// Constructor taking some policy objects. r_cmp_fn will be /// copied by the Cmp_Fn object of the container object. tree(const cmp_fn& c) : base_type(c) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template tree(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_cmp_fn /// will be copied by the cmp_fn object of the container object. template tree(It first, It last, const cmp_fn& c) : base_type(c) { base_type::copy_from_range(first, last); } tree(const tree& other) : base_type((const base_type&)other) { } virtual ~tree() { } tree& operator=(const tree& other) { if (this != &other) { tree tmp(other); swap(tmp); } return *this; } void swap(tree& other) { base_type::swap(other); } }; #undef PB_DS_TREE_BASE #undef PB_DS_TREE_NODE_AND_IT_TRAITS #define PB_DS_TRIE_NODE_AND_IT_TRAITS \ detail::trie_traits #define PB_DS_TRIE_BASE \ basic_branch::type, _Alloc> /** * A trie-based container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam _ATraits Element access traits. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates trie internal-nodes, * restores invariants when invalidated. * XXX See design::tree-based-containers::node invariants. * @tparam _Alloc Allocator type. * * Base tag choice is pat_trie_tag. * * Base is basic_branch. */ template::type, typename Tag = pat_trie_tag, template class Node_Update = null_node_update, typename _Alloc = std::allocator > class trie : public PB_DS_TRIE_BASE { private: typedef PB_DS_TRIE_BASE base_type; public: /// Element access traits type. typedef _ATraits access_traits; trie() { } /// Constructor taking some policy objects. r_access_traits will /// be copied by the _ATraits object of the container object. trie(const access_traits& t) : base_type(t) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template trie(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. template trie(It first, It last, const access_traits& t) : base_type(t) { base_type::copy_from_range(first, last); } trie(const trie& other) : base_type((const base_type&)other) { } virtual ~trie() { } trie& operator=(const trie& other) { if (this != &other) { trie tmp(other); swap(tmp); } return *this; } void swap(trie& other) { base_type::swap(other); } }; //@} branch-based #undef PB_DS_TRIE_BASE #undef PB_DS_TRIE_NODE_AND_IT_TRAITS /** * @defgroup list-based List-Based * @ingroup containers-pbds * @{ */ #define PB_DS_LU_BASE \ detail::container_base_dispatch::type>::type /** * A list-update based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Eq_Fn Equal functor. * @tparam Update_Policy Update policy, determines when an element * will be moved to the front of the list. * @tparam _Alloc Allocator type. * * Base is detail::lu_map. */ template::type, class Update_Policy = detail::default_update_policy::type, class _Alloc = std::allocator > class list_update : public PB_DS_LU_BASE { private: typedef typename PB_DS_LU_BASE base_type; public: typedef list_update_tag container_category; typedef Eq_Fn eq_fn; typedef Update_Policy update_policy; list_update() { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template list_update(It first, It last) { base_type::copy_from_range(first, last); } list_update(const list_update& other) : base_type((const base_type&)other) { } virtual ~list_update() { } list_update& operator=(const list_update& other) { if (this !=& other) { list_update tmp(other); swap(tmp); } return *this; } void swap(list_update& other) { base_type::swap(other); } }; //@} list-based #undef PB_DS_LU_BASE // @} group containers-pbds } // namespace __gnu_pbds #endif PKgd1]Dq 8/ext/pb_ds/exception.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file exception.hpp * Contains exception classes. */ #ifndef PB_DS_EXCEPTION_HPP #define PB_DS_EXCEPTION_HPP #include #include #include namespace __gnu_pbds { /** * @defgroup exceptions-pbds Exceptions * @ingroup pbds * @{ */ /// Base class for exceptions. struct container_error : public std::logic_error { container_error() : std::logic_error(__N("__gnu_pbds::container_error")) { } }; /// An entry cannot be inserted into a container object for logical /// reasons (not, e.g., if memory is unabvailable, in which case /// the allocator_type's exception will be thrown). struct insert_error : public container_error { }; /// A join cannot be performed logical reasons (i.e., the ranges of /// the two container objects being joined overlaps. struct join_error : public container_error { }; /// A container cannot be resized. struct resize_error : public container_error { }; inline void __throw_container_error() { _GLIBCXX_THROW_OR_ABORT(container_error()); } inline void __throw_insert_error() { _GLIBCXX_THROW_OR_ABORT(insert_error()); } inline void __throw_join_error() { _GLIBCXX_THROW_OR_ABORT(join_error()); } inline void __throw_resize_error() { _GLIBCXX_THROW_OR_ABORT(resize_error()); } //@} } // namespace __gnu_pbds #endif PKgd1]T9//8/ext/pb_ds/tag_and_trait.hppnu[// -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tag_and_trait.hpp * Contains tags and traits, e.g., ones describing underlying * data structures. */ #ifndef PB_DS_TAG_AND_TRAIT_HPP #define PB_DS_TAG_AND_TRAIT_HPP #include #include /** * @namespace __gnu_pbds * @brief GNU extensions for policy-based data structures for public use. */ namespace __gnu_pbds { /** @defgroup pbds Policy-Based Data Structures * @ingroup extensions * * This is a library of policy-based elementary data structures: * associative containers and priority queues. It is designed for * high-performance, flexibility, semantic safety, and conformance * to the corresponding containers in std (except for some points * where it differs by design). * * For details, see: * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/index.html * * @{ */ /** * @defgroup tags Tags * @{ */ /// A trivial iterator tag. Signifies that the iterators has none of /// std::iterators's movement abilities. struct trivial_iterator_tag { }; /// Prohibit moving trivial iterators. typedef void trivial_iterator_difference_type; /** * @defgroup invalidation_tags Invalidation Guarantees * @ingroup tags * @{ */ /** * Signifies a basic invalidation guarantee that any iterator, * pointer, or reference to a container object's mapped value type * is valid as long as the container is not modified. */ struct basic_invalidation_guarantee { }; /** * Signifies an invalidation guarantee that includes all those of * its base, and additionally, that any point-type iterator, * pointer, or reference to a container object's mapped value type * is valid as long as its corresponding entry has not be erased, * regardless of modifications to the container object. */ struct point_invalidation_guarantee : public basic_invalidation_guarantee { }; /** * Signifies an invalidation guarantee that includes all those of * its base, and additionally, that any range-type iterator * (including the returns of begin() and end()) is in the correct * relative positions to other range-type iterators as long as its * corresponding entry has not be erased, regardless of * modifications to the container object. */ struct range_invalidation_guarantee : public point_invalidation_guarantee { }; //@} /** * @defgroup ds_tags Data Structure Type * @ingroup tags * @{ */ /// Base data structure tag. struct container_tag { }; /// Basic sequence. struct sequence_tag : public container_tag { }; /// Basic string container, inclusive of strings, ropes, etc. struct string_tag : public sequence_tag { }; /// Basic associative-container. struct associative_tag : public container_tag { }; /// Basic hash structure. struct basic_hash_tag : public associative_tag { }; /// Collision-chaining hash. struct cc_hash_tag : public basic_hash_tag { }; /// General-probing hash. struct gp_hash_tag : public basic_hash_tag { }; /// Basic branch structure. struct basic_branch_tag : public associative_tag { }; /// Basic tree structure. struct tree_tag : public basic_branch_tag { }; /// Red-black tree. struct rb_tree_tag : public tree_tag { }; /// Splay tree. struct splay_tree_tag : public tree_tag { }; /// Ordered-vector tree. struct ov_tree_tag : public tree_tag { }; /// Basic trie structure. struct trie_tag : public basic_branch_tag { }; /// PATRICIA trie. struct pat_trie_tag : public trie_tag { }; /// List-update. struct list_update_tag : public associative_tag { }; /// Basic priority-queue. struct priority_queue_tag : public container_tag { }; /// Pairing-heap. struct pairing_heap_tag : public priority_queue_tag { }; /// Binomial-heap. struct binomial_heap_tag : public priority_queue_tag { }; /// Redundant-counter binomial-heap. struct rc_binomial_heap_tag : public priority_queue_tag { }; /// Binary-heap (array-based). struct binary_heap_tag : public priority_queue_tag { }; /// Thin heap. struct thin_heap_tag : public priority_queue_tag { }; //@} //@} /** * @defgroup traits Traits * @{ */ /** * @brief Represents no type, or absence of type, for template tricks. * * In a mapped-policy, indicates that an associative container is a set. * * In a list-update policy, indicates that each link does not need * metadata. * * In a hash policy, indicates that the combining hash function * is actually a ranged hash function. * * In a probe policy, indicates that the combining probe function * is actually a ranged probe function. */ struct null_type { }; /// A null node updator, indicating that no node updates are required. template struct null_node_update : public null_type { }; /// Primary template, container traits base. template struct container_traits_base; /// Specialization, cc hash. template<> struct container_traits_base { typedef cc_hash_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, gp hash. template<> struct container_traits_base { typedef gp_hash_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, rb tree. template<> struct container_traits_base { typedef rb_tree_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = true }; }; /// Specialization, splay tree. template<> struct container_traits_base { typedef splay_tree_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = true }; }; /// Specialization, ov tree. template<> struct container_traits_base { typedef ov_tree_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = true, split_join_can_throw = true, reverse_iteration = false }; }; /// Specialization, pat trie. template<> struct container_traits_base { typedef pat_trie_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = true, reverse_iteration = true }; }; /// Specialization, list update. template<> struct container_traits_base { typedef list_update_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, pairing heap. template<> struct container_traits_base { typedef pairing_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, thin heap. template<> struct container_traits_base { typedef thin_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, binomial heap. template<> struct container_traits_base { typedef binomial_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, rc binomial heap. template<> struct container_traits_base { typedef rc_binomial_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, binary heap. template<> struct container_traits_base { typedef binary_heap_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = true, reverse_iteration = false }; }; /// Container traits. // See Matt Austern for the name, S. Meyers MEFC++ #2, others. template struct container_traits : public container_traits_base { typedef Cntnr container_type; typedef typename Cntnr::container_category container_category; typedef container_traits_base base_type; typedef typename base_type::invalidation_guarantee invalidation_guarantee; enum { /// True only if Cntnr objects guarantee storing keys by order. order_preserving = base_type::order_preserving, /// True only if erasing a key can throw. erase_can_throw = base_type::erase_can_throw, /// True only if split or join operations can throw. split_join_can_throw = base_type::split_join_can_throw, /// True only reverse iterators are supported. reverse_iteration = base_type::reverse_iteration }; }; //@} namespace detail { /// Dispatch mechanism, primary template for associative types. template struct container_base_dispatch; } // namespace detail //@} } // namespace __gnu_pbds #endif PKgd1]igZKZK8/ext/algorithmnu[// Algorithm extensions -*- C++ -*- // Copyright (C) 2001-2018 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 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file ext/algorithm * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ALGORITHM #define _EXT_ALGORITHM 1 #pragma GCC system_header #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::ptrdiff_t; using std::min; using std::pair; using std::input_iterator_tag; using std::random_access_iterator_tag; using std::iterator_traits; //-------------------------------------------------- // copy_n (not part of the C++ standard) template pair<_InputIterator, _OutputIterator> __copy_n(_InputIterator __first, _Size __count, _OutputIterator __result, input_iterator_tag) { for ( ; __count > 0; --__count) { *__result = *__first; ++__first; ++__result; } return pair<_InputIterator, _OutputIterator>(__first, __result); } template inline pair<_RAIterator, _OutputIterator> __copy_n(_RAIterator __first, _Size __count, _OutputIterator __result, random_access_iterator_tag) { _RAIterator __last = __first + __count; return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, __last, __result)); } /** * @brief Copies the range [first,first+count) into [result,result+count). * @param __first An input iterator. * @param __count The number of elements to copy. * @param __result An output iterator. * @return A std::pair composed of first+count and result+count. * * This is an SGI extension. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * @ingroup SGIextensions */ template inline pair<_InputIterator, _OutputIterator> copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) return __gnu_cxx::__copy_n(__first, __count, __result, std::__iterator_category(__first)); } template int __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { while (__first1 != __last1 && __first2 != __last2) { if (*__first1 < *__first2) return -1; if (*__first2 < *__first1) return 1; ++__first1; ++__first2; } if (__first2 == __last2) return !(__first1 == __last1); else return -1; } inline int __lexicographical_compare_3way(const unsigned char* __first1, const unsigned char* __last1, const unsigned char* __first2, const unsigned char* __last2) { const ptrdiff_t __len1 = __last1 - __first1; const ptrdiff_t __len2 = __last2 - __first2; const int __result = __builtin_memcmp(__first1, __first2, min(__len1, __len2)); return __result != 0 ? __result : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } inline int __lexicographical_compare_3way(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX return __lexicographical_compare_3way((const signed char*) __first1, (const signed char*) __last1, (const signed char*) __first2, (const signed char*) __last2); #else return __lexicographical_compare_3way((const unsigned char*) __first1, (const unsigned char*) __last1, (const unsigned char*) __first2, (const unsigned char*) __last2); #endif } /** * @brief @c memcmp on steroids. * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return An int, as with @c memcmp. * * The return value will be less than zero if the first range is * lexigraphically less than the second, greater than zero * if the second range is lexigraphically less than the * first, and zero otherwise. * This is an SGI extension. * @ingroup SGIextensions */ template int lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } // count and count_if: this version, whose return type is void, was present // in the HP STL, and is retained as an extension for backward compatibility. template void count(_InputIterator __first, _InputIterator __last, const _Tp& __value, _Size& __n) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type >) __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; } template void count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, _Size& __n) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; } // random_sample and random_sample_n (extensions, not part of the standard). /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { if ((std::rand() % __remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n, _RandomNumberGenerator& __rand) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__rand(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, const _Distance __n) { _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = std::rand() % (__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, _RandomNumberGenerator& __rand, const _Distance __n) { // concept requirements __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __rand(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __out_last - __out_first); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, _RandomNumberGenerator& __rand) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } #if __cplusplus >= 201103L using std::is_heap; #else /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__is_heap(__first, __last - __first); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__is_heap(__first, __comp, __last - __first); } #endif #if __cplusplus >= 201103L using std::is_sorted; #else // is_sorted, a predicated testing whether a range is sorted in // nondescending order. This is an extension, not part of the C++ // standard. /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) if (*__next < *__first) return false; return true; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) if (__comp(*__next, *__first)) return false; return true; } #endif // C++11 /** * @brief Find the median of three values. * @param __a A value. * @param __b A value. * @param __c A value. * @return One of @p a, @p b or @p c. * * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n * then the value returned will be @c m. * This is an SGI extension. * @ingroup SGIextensions */ template const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) if (__a < __b) if (__b < __c) return __b; else if (__a < __c) return __c; else return __a; else if (__a < __c) return __a; else if (__b < __c) return __c; else return __b; } /** * @brief Find the median of three values using a predicate for comparison. * @param __a A value. * @param __b A value. * @param __c A value. * @param __comp A binary predicate. * @return One of @p a, @p b or @p c. * * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) * and @p comp(m,n) are both true then the value returned will be @c m. * This is an SGI extension. * @ingroup SGIextensions */ template const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { // concept requirements __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, _Tp, _Tp>) if (__comp(__a, __b)) if (__comp(__b, __c)) return __b; else if (__comp(__a, __c)) return __c; else return __a; else if (__comp(__a, __c)) return __a; else if (__comp(__b, __c)) return __c; else return __b; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _EXT_ALGORITHM */ PKgd1]+C+C8/ext/hash_setnu[// Hashing set implementation -*- C++ -*- // Copyright (C) 2001-2018 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 * 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. * * * 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. * */ /** @file backward/hash_set * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_SET #define _BACKWARD_HASH_SET 1 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH #include "backward_warning.h" #endif #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::equal_to; using std::allocator; using std::pair; using std::_Identity; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_set { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_set() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_set(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_set(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator==(const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } pair insert(const value_type& __obj) { pair __p = _M_ht.insert_unique(__obj); return pair(__p.first, __p.second); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } pair insert_noresize(const value_type& __obj) { pair __p = _M_ht.insert_unique_noresize(__obj); return pair(__p.first, __p.second); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_multiset { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_multiset() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multiset(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_multiset(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } template friend bool operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) { return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that it will work for hash_set // and hash_multiset. template class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]2  8/ext/string_conversions.hnu[// String Conversions -*- C++ -*- // Copyright (C) 2008-2018 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/string_conversions.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STRING_CONVERSIONS_H #define _STRING_CONVERSIONS_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Helper for all the sto* functions. template _Ret __stoa(_TRet (*__convf) (const _CharT*, _CharT**, _Base...), const char* __name, const _CharT* __str, std::size_t* __idx, _Base... __base) { _Ret __ret; _CharT* __endptr; struct _Save_errno { _Save_errno() : _M_errno(errno) { errno = 0; } ~_Save_errno() { if (errno == 0) errno = _M_errno; } int _M_errno; } const __save_errno; struct _Range_chk { static bool _S_chk(_TRet, std::false_type) { return false; } static bool _S_chk(_TRet __val, std::true_type) // only called when _Ret is int { return __val < _TRet(__numeric_traits::__min) || __val > _TRet(__numeric_traits::__max); } }; const _TRet __tmp = __convf(__str, &__endptr, __base...); if (__endptr == __str) std::__throw_invalid_argument(__name); else if (errno == ERANGE || _Range_chk::_S_chk(__tmp, std::is_same<_Ret, int>{})) std::__throw_out_of_range(__name); else __ret = __tmp; if (__idx) *__idx = __endptr - __str; return __ret; } // Helper for the to_string / to_wstring functions. template _String __to_xstring(int (*__convf) (_CharT*, std::size_t, const _CharT*, __builtin_va_list), std::size_t __n, const _CharT* __fmt, ...) { // XXX Eventually the result should be constructed in-place in // the __cxx11 string, likely with the help of internal hooks. _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); __builtin_va_list __args; __builtin_va_start(__args, __fmt); const int __len = __convf(__s, __n, __fmt, __args); __builtin_va_end(__args); return _String(__s, __s + __len); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _STRING_CONVERSIONS_H PKgd1]*v?2??8/ext/codecvt_specializations.hnu[// Locale support (codecvt) -*- C++ -*- // Copyright (C) 2000-2018 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 // . // // ISO C++ 14882: 22.2.1.5 Template class codecvt // // Written by Benjamin Kosnik /** @file ext/codecvt_specializations.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_CODECVT_SPECIALIZATIONS_H #define _EXT_CODECVT_SPECIALIZATIONS_H 1 #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// Extension to use iconv for dealing with character encodings. // This includes conversions and comparisons between various character // sets. This object encapsulates data that may need to be shared between // char_traits, codecvt and ctype. class encoding_state { public: // Types: // NB: A conversion descriptor subsumes and enhances the // functionality of a simple state type such as mbstate_t. typedef iconv_t descriptor_type; protected: // Name of internal character set encoding. std::string _M_int_enc; // Name of external character set encoding. std::string _M_ext_enc; // Conversion descriptor between external encoding to internal encoding. descriptor_type _M_in_desc; // Conversion descriptor between internal encoding to external encoding. descriptor_type _M_out_desc; // The byte-order marker for the external encoding, if necessary. int _M_ext_bom; // The byte-order marker for the internal encoding, if necessary. int _M_int_bom; // Number of external bytes needed to construct one complete // character in the internal encoding. // NB: -1 indicates variable, or stateful, encodings. int _M_bytes; public: explicit encoding_state() : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0), _M_bytes(0) { } explicit encoding_state(const char* __int, const char* __ext, int __ibom = 0, int __ebom = 0, int __bytes = 1) : _M_int_enc(__int), _M_ext_enc(__ext), _M_in_desc(0), _M_out_desc(0), _M_ext_bom(__ebom), _M_int_bom(__ibom), _M_bytes(__bytes) { init(); } // 21.1.2 traits typedefs // p4 // typedef STATE_T state_type // requires: state_type shall meet the requirements of // CopyConstructible types (20.1.3) // NB: This does not preserve the actual state of the conversion // descriptor member, but it does duplicate the encoding // information. encoding_state(const encoding_state& __obj) : _M_in_desc(0), _M_out_desc(0) { construct(__obj); } // Need assignment operator as well. encoding_state& operator=(const encoding_state& __obj) { construct(__obj); return *this; } ~encoding_state() { destroy(); } bool good() const throw() { const descriptor_type __err = (iconv_t)(-1); bool __test = _M_in_desc && _M_in_desc != __err; __test &= _M_out_desc && _M_out_desc != __err; return __test; } int character_ratio() const { return _M_bytes; } const std::string internal_encoding() const { return _M_int_enc; } int internal_bom() const { return _M_int_bom; } const std::string external_encoding() const { return _M_ext_enc; } int external_bom() const { return _M_ext_bom; } const descriptor_type& in_descriptor() const { return _M_in_desc; } const descriptor_type& out_descriptor() const { return _M_out_desc; } protected: void init() { const descriptor_type __err = (iconv_t)(-1); const bool __have_encodings = _M_int_enc.size() && _M_ext_enc.size(); if (!_M_in_desc && __have_encodings) { _M_in_desc = iconv_open(_M_int_enc.c_str(), _M_ext_enc.c_str()); if (_M_in_desc == __err) std::__throw_runtime_error(__N("encoding_state::_M_init " "creating iconv input descriptor failed")); } if (!_M_out_desc && __have_encodings) { _M_out_desc = iconv_open(_M_ext_enc.c_str(), _M_int_enc.c_str()); if (_M_out_desc == __err) std::__throw_runtime_error(__N("encoding_state::_M_init " "creating iconv output descriptor failed")); } } void construct(const encoding_state& __obj) { destroy(); _M_int_enc = __obj._M_int_enc; _M_ext_enc = __obj._M_ext_enc; _M_ext_bom = __obj._M_ext_bom; _M_int_bom = __obj._M_int_bom; _M_bytes = __obj._M_bytes; init(); } void destroy() throw() { const descriptor_type __err = (iconv_t)(-1); if (_M_in_desc && _M_in_desc != __err) { iconv_close(_M_in_desc); _M_in_desc = 0; } if (_M_out_desc && _M_out_desc != __err) { iconv_close(_M_out_desc); _M_out_desc = 0; } } }; /// encoding_char_traits // Custom traits type with encoding_state for the state type, and the // associated fpos for the position type, all other // bits equivalent to the required char_traits instantiations. template struct encoding_char_traits : public std::char_traits<_CharT> { typedef encoding_state state_type; typedef typename std::fpos pos_type; }; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using __gnu_cxx::encoding_state; /// codecvt specialization. // This partial specialization takes advantage of iconv to provide // code conversions between a large number of character encodings. template class codecvt<_InternT, _ExternT, encoding_state> : public __codecvt_abstract_base<_InternT, _ExternT, encoding_state> { public: // Types: typedef codecvt_base::result result; typedef _InternT intern_type; typedef _ExternT extern_type; typedef __gnu_cxx::encoding_state state_type; typedef state_type::descriptor_type descriptor_type; // Data Members: static locale::id id; explicit codecvt(size_t __refs = 0) : __codecvt_abstract_base(__refs) { } explicit codecvt(state_type& __enc, size_t __refs = 0) : __codecvt_abstract_base(__refs) { } protected: virtual ~codecvt() { } virtual result do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int do_max_length() const throw(); }; template locale::id codecvt<_InternT, _ExternT, encoding_state>::id; // This adaptor works around the signature problems of the second // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 // uses 'char**', which matches the POSIX 1003.1-2001 standard. // Using this adaptor, g++ will do the work for us. template inline size_t __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*), iconv_t __cd, char** __inbuf, size_t* __inbytes, char** __outbuf, size_t* __outbytes) { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); } template codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.out_descriptor(); const size_t __fmultiple = sizeof(intern_type); size_t __fbytes = __fmultiple * (__from_end - __from); const size_t __tmultiple = sizeof(extern_type); size_t __tbytes = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast(__to); char* __cfrom; size_t __conv; // Some encodings need a byte order marker as the first item // in the byte stream, to designate endian-ness. The default // value for the byte order marker is NULL, so if this is // the case, it's not necessary and we can just go on our // merry way. int __int_bom = __state.internal_bom(); if (__int_bom) { size_t __size = __from_end - __from; intern_type* __cfixed = static_cast (__builtin_alloca(sizeof(intern_type) * (__size + 1))); __cfixed[0] = static_cast(__int_bom); char_traits::copy(__cfixed + 1, __from, __size); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, &__cto, &__tbytes); } else { intern_type* __cfixed = const_cast(__from); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, &__cto, &__tbytes); } if (__conv != size_t(-1)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::ok; } else { if (__fbytes < __fmultiple * (__from_end - __from)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } } return __ret; } template codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.in_descriptor(); const size_t __tmultiple = sizeof(intern_type); size_t __tlen = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast(__to); size_t __conv = __iconv_adaptor(iconv,__desc, 0, 0, &__cto, &__tlen); if (__conv != size_t(-1)) { __to_next = reinterpret_cast(__cto); if (__tlen == __tmultiple * (__to_end - __to)) __ret = codecvt_base::noconv; else if (__tlen == 0) __ret = codecvt_base::ok; else __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } return __ret; } template codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.in_descriptor(); const size_t __fmultiple = sizeof(extern_type); size_t __flen = __fmultiple * (__from_end - __from); const size_t __tmultiple = sizeof(intern_type); size_t __tlen = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast(__to); char* __cfrom; size_t __conv; // Some encodings need a byte order marker as the first item // in the byte stream, to designate endian-ness. The default // value for the byte order marker is NULL, so if this is // the case, it's not necessary and we can just go on our // merry way. int __ext_bom = __state.external_bom(); if (__ext_bom) { size_t __size = __from_end - __from; extern_type* __cfixed = static_cast (__builtin_alloca(sizeof(extern_type) * (__size + 1))); __cfixed[0] = static_cast(__ext_bom); char_traits::copy(__cfixed + 1, __from, __size); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__flen, &__cto, &__tlen); } else { extern_type* __cfixed = const_cast(__from); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__flen, &__cto, &__tlen); } if (__conv != size_t(-1)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::ok; } else { if (__flen < static_cast(__from_end - __from)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } } return __ret; } template int codecvt<_InternT, _ExternT, encoding_state>:: do_encoding() const throw() { int __ret = 0; if (sizeof(_ExternT) <= sizeof(_InternT)) __ret = sizeof(_InternT) / sizeof(_ExternT); return __ret; } template bool codecvt<_InternT, _ExternT, encoding_state>:: do_always_noconv() const throw() { return false; } template int codecvt<_InternT, _ExternT, encoding_state>:: do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { return std::min(__max, static_cast(__end - __from)); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 74. Garbled text for codecvt::do_max_length template int codecvt<_InternT, _ExternT, encoding_state>:: do_max_length() const throw() { return 1; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]]'8/ext/enc_filebuf.hnu[// filebuf with encoding state type -*- C++ -*- // Copyright (C) 2002-2018 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/enc_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_ENC_FILEBUF_H #define _EXT_ENC_FILEBUF_H 1 #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// class enc_filebuf. template class enc_filebuf : public std::basic_filebuf<_CharT, encoding_char_traits<_CharT> > { public: typedef encoding_char_traits<_CharT> traits_type; typedef typename traits_type::state_type state_type; typedef typename traits_type::pos_type pos_type; enc_filebuf(state_type& __state) : std::basic_filebuf<_CharT, encoding_char_traits<_CharT> >() { this->_M_state_beg = __state; } private: // concept requirements: // Set state type to something useful. // Something more than copyconstructible is needed here, so // require default and copy constructible + assignment operator. __glibcxx_class_requires(state_type, _SGIAssignableConcept) }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]8/ext/vstring_util.hnu[// Versatile string utility -*- C++ -*- // Copyright (C) 2005-2018 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/vstring_util.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _VSTRING_UTIL_H #define _VSTRING_UTIL_H 1 #pragma GCC system_header #include #include #include // For less #include #include #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __vstring_utility { typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef typename _CharT_alloc_type::size_type size_type; typedef typename _CharT_alloc_type::difference_type difference_type; typedef typename _CharT_alloc_type::pointer pointer; typedef typename _CharT_alloc_type::const_pointer const_pointer; // For __sso_string. typedef __gnu_cxx:: __normal_iterator > __sso_iterator; typedef __gnu_cxx:: __normal_iterator > __const_sso_iterator; // For __rc_string. typedef __gnu_cxx:: __normal_iterator > __rc_iterator; typedef __gnu_cxx:: __normal_iterator > __const_rc_iterator; // NB: When the allocator is empty, deriving from it saves space // (http://www.cantrip.org/emptyopt.html). template struct _Alloc_hider : public _Alloc1 { _Alloc_hider(_CharT* __ptr) : _Alloc1(), _M_p(__ptr) { } _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) : _Alloc1(__a), _M_p(__ptr) { } _CharT* _M_p; // The actual data. }; // When __n = 1 way faster than the general multichar // traits_type::copy/move/assign. static void _S_copy(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::copy(__d, __s, __n); } static void _S_move(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::move(__d, __s, __n); } static void _S_assign(_CharT* __d, size_type __n, _CharT __c) { if (__n == 1) traits_type::assign(*__d, __c); else traits_type::assign(__d, __n, __c); } // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { for (; __k1 != __k2; ++__k1, ++__p) traits_type::assign(*__p, *__k1); // These types are off. } static void _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __const_sso_iterator __k1, __const_sso_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __const_rc_iterator __k1, __const_rc_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } static int _S_compare(size_type __n1, size_type __n2) { const difference_type __d = difference_type(__n1 - __n2); if (__d > __numeric_traits_integer::__max) return __numeric_traits_integer::__max; else if (__d < __numeric_traits_integer::__min) return __numeric_traits_integer::__min; else return int(__d); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _VSTRING_UTIL_H */ PKgd1]}h  8/ext/array_allocator.hnu[// array allocator -*- C++ -*- // Copyright (C) 2004-2018 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/array_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _ARRAY_ALLOCATOR_H #define _ARRAY_ALLOCATOR_H 1 #include #include #include #include #include #if __cplusplus >= 201103L #include #endif // Suppress deprecated warning for this file. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /// Base class. template class array_allocator_base { 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; pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } void deallocate(pointer, size_type) { // Does nothing. } 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) value_type(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif } _GLIBCXX_DEPRECATED; /** * @brief An allocator that uses previously allocated memory. * This memory can be externally, globally, or otherwise allocated. * @ingroup allocators */ template > class array_allocator : public array_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; typedef _Array array_type; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; typedef std::true_type is_always_equal; #endif private: array_type* _M_array; size_type _M_used; public: template struct rebind { typedef array_allocator<_Tp1, _Array1> other _GLIBCXX_DEPRECATED; } _GLIBCXX_DEPRECATED; array_allocator(array_type* __array = 0) _GLIBCXX_USE_NOEXCEPT : _M_array(__array), _M_used(size_type()) { } array_allocator(const array_allocator& __o) _GLIBCXX_USE_NOEXCEPT : _M_array(__o._M_array), _M_used(__o._M_used) { } template array_allocator(const array_allocator<_Tp1, _Array1>&) _GLIBCXX_USE_NOEXCEPT : _M_array(0), _M_used(size_type()) { } ~array_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer allocate(size_type __n, const void* = 0) { if (_M_array == 0 || _M_used + __n > _M_array->size()) std::__throw_bad_alloc(); pointer __ret = _M_array->begin() + _M_used; _M_used += __n; return __ret; } } _GLIBCXX_DEPRECATED; template inline bool operator==(const array_allocator<_Tp, _Array>&, const array_allocator<_Tp, _Array>&) { return true; } template inline bool operator!=(const array_allocator<_Tp, _Array>&, const array_allocator<_Tp, _Array>&) { return false; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #pragma GCC diagnostic pop #endif PKgd1]u3iu"u"8/ext/pool_allocator.hnu[// Allocators -*- C++ -*- // Copyright (C) 2001-2018 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 ext/pool_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _POOL_ALLOCATOR_H #define _POOL_ALLOCATOR_H 1 #include #include #include #include #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 Base class for __pool_alloc. * * Uses various allocators to fulfill underlying requests (and makes as * few requests as possible when in default high-speed pool mode). * * Important implementation properties: * 0. If globally mandated, then allocate objects from new * 1. If the clients request an object of size > _S_max_bytes, the resulting * object will be obtained directly from new * 2. In all other cases, we allocate an object of size exactly * _S_round_up(requested_size). Thus the client has enough size * information that we can return the object to the proper free list * without permanently losing part of the object. */ class __pool_alloc_base { protected: enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; enum { _S_free_list_size = (size_t)_S_max_bytes / (size_t)_S_align }; union _Obj { union _Obj* _M_free_list_link; char _M_client_data[1]; // The client sees this. }; static _Obj* volatile _S_free_list[_S_free_list_size]; // Chunk allocation state. static char* _S_start_free; static char* _S_end_free; static size_t _S_heap_size; size_t _M_round_up(size_t __bytes) { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); } _GLIBCXX_CONST _Obj* volatile* _M_get_free_list(size_t __bytes) throw (); __mutex& _M_get_mutex() throw (); // Returns an object of size __n, and optionally adds to size __n // free list. void* _M_refill(size_t __n); // Allocates a chunk for nobjs of size size. nobjs may be reduced // if it is inconvenient to allocate the requested number. char* _M_allocate_chunk(size_t __n, int& __nobjs); }; /** * @brief Allocator using a memory pool with a single lock. * @ingroup allocators */ template class __pool_alloc : private __pool_alloc_base { private: static _Atomic_word _S_force_new; 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 __pool_alloc<_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 __pool_alloc() _GLIBCXX_USE_NOEXCEPT { } __pool_alloc(const __pool_alloc&) _GLIBCXX_USE_NOEXCEPT { } template __pool_alloc(const __pool_alloc<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~__pool_alloc() _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); } 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 pointer allocate(size_type __n, const void* = 0); void deallocate(pointer __p, size_type __n); }; template inline bool operator==(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) { return true; } template inline bool operator!=(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) { return false; } template _Atomic_word __pool_alloc<_Tp>::_S_force_new; template _Tp* __pool_alloc<_Tp>::allocate(size_type __n, const void*) { pointer __ret = 0; if (__builtin_expect(__n != 0, true)) { if (__n > this->max_size()) std::__throw_bad_alloc(); const size_t __bytes = __n * sizeof(_Tp); #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__bytes, __al)); } #endif // If there is a race through here, assume answer from getenv // will resolve in same direction. Inspired by techniques // to efficiently support threading found in basic_string.h. if (_S_force_new == 0) { if (std::getenv("GLIBCXX_FORCE_NEW")) __atomic_add_dispatch(&_S_force_new, 1); else __atomic_add_dispatch(&_S_force_new, -1); } if (__bytes > size_t(_S_max_bytes) || _S_force_new > 0) __ret = static_cast<_Tp*>(::operator new(__bytes)); else { _Obj* volatile* __free_list = _M_get_free_list(__bytes); __scoped_lock sentry(_M_get_mutex()); _Obj* __restrict__ __result = *__free_list; if (__builtin_expect(__result == 0, 0)) __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); else { *__free_list = __result->_M_free_list_link; __ret = reinterpret_cast<_Tp*>(__result); } if (__ret == 0) std::__throw_bad_alloc(); } } return __ret; } template void __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) { if (__builtin_expect(__n != 0 && __p != 0, true)) { #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif const size_t __bytes = __n * sizeof(_Tp); if (__bytes > static_cast(_S_max_bytes) || _S_force_new > 0) ::operator delete(__p); else { _Obj* volatile* __free_list = _M_get_free_list(__bytes); _Obj* __q = reinterpret_cast<_Obj*>(__p); __scoped_lock sentry(_M_get_mutex()); __q ->_M_free_list_link = *__free_list; *__free_list = __q; } } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]8cN"N"8/ext/stdio_sync_filebuf.hnu[// Iostreams wrapper for stdio FILE* -*- C++ -*- // Copyright (C) 2003-2018 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/stdio_sync_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STDIO_SYNC_FILEBUF_H #define _STDIO_SYNC_FILEBUF_H 1 #pragma GCC system_header #include #include #include #include // For __c_file #include // For __exchange #ifdef _GLIBCXX_USE_WCHAR_T #include #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Provides a layer of compatibility for C. * @ingroup io * * This GNU extension provides extensions for working with standard * C FILE*'s. It must be instantiated by the user with the type of * character used in the file stream, e.g., stdio_filebuf. */ template > class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; private: typedef std::basic_streambuf<_CharT, _Traits> __streambuf_type; // Underlying stdio FILE std::__c_file* _M_file; // Last character gotten. This is used when pbackfail is // called from basic_streambuf::sungetc() int_type _M_unget_buf; public: explicit stdio_sync_filebuf(std::__c_file* __f) : _M_file(__f), _M_unget_buf(traits_type::eof()) { } #if __cplusplus >= 201103L stdio_sync_filebuf(stdio_sync_filebuf&& __fb) noexcept : __streambuf_type(std::move(__fb)), _M_file(__fb._M_file), _M_unget_buf(__fb._M_unget_buf) { __fb._M_file = nullptr; __fb._M_unget_buf = traits_type::eof(); } stdio_sync_filebuf& operator=(stdio_sync_filebuf&& __fb) noexcept { __streambuf_type::operator=(__fb); _M_file = std::__exchange(__fb._M_file, nullptr); _M_unget_buf = std::__exchange(__fb._M_unget_buf, traits_type::eof()); return *this; } void swap(stdio_sync_filebuf& __fb) { __streambuf_type::swap(__fb); std::swap(_M_file, __fb._M_file); std::swap(_M_unget_buf, __fb._M_unget_buf); } #endif /** * @return The underlying FILE*. * * This function can be used to access the underlying C file pointer. * Note that there is no way for the library to track what you do * with the file, so be careful. */ std::__c_file* file() { return this->_M_file; } protected: int_type syncgetc(); int_type syncungetc(int_type __c); int_type syncputc(int_type __c); virtual int_type underflow() { int_type __c = this->syncgetc(); return this->syncungetc(__c); } virtual int_type uflow() { // Store the gotten character in case we need to unget it. _M_unget_buf = this->syncgetc(); return _M_unget_buf; } virtual int_type pbackfail(int_type __c = traits_type::eof()) { int_type __ret; const int_type __eof = traits_type::eof(); // Check if the unget or putback was requested if (traits_type::eq_int_type(__c, __eof)) // unget { if (!traits_type::eq_int_type(_M_unget_buf, __eof)) __ret = this->syncungetc(_M_unget_buf); else // buffer invalid, fail. __ret = __eof; } else // putback __ret = this->syncungetc(__c); // The buffered character is no longer valid, discard it. _M_unget_buf = __eof; return __ret; } virtual std::streamsize xsgetn(char_type* __s, std::streamsize __n); virtual int_type overflow(int_type __c = traits_type::eof()) { int_type __ret; if (traits_type::eq_int_type(__c, traits_type::eof())) { if (std::fflush(_M_file)) __ret = traits_type::eof(); else __ret = traits_type::not_eof(__c); } else __ret = this->syncputc(__c); return __ret; } virtual std::streamsize xsputn(const char_type* __s, std::streamsize __n); virtual int sync() { return std::fflush(_M_file); } virtual std::streampos seekoff(std::streamoff __off, std::ios_base::seekdir __dir, std::ios_base::openmode = std::ios_base::in | std::ios_base::out) { std::streampos __ret(std::streamoff(-1)); int __whence; if (__dir == std::ios_base::beg) __whence = SEEK_SET; else if (__dir == std::ios_base::cur) __whence = SEEK_CUR; else __whence = SEEK_END; #ifdef _GLIBCXX_USE_LFS if (!fseeko64(_M_file, __off, __whence)) __ret = std::streampos(ftello64(_M_file)); #else if (!fseek(_M_file, __off, __whence)) __ret = std::streampos(std::ftell(_M_file)); #endif return __ret; } virtual std::streampos seekpos(std::streampos __pos, std::ios_base::openmode __mode = std::ios_base::in | std::ios_base::out) { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); } }; template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncgetc() { return std::getc(_M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncungetc(int_type __c) { return std::ungetc(__c, _M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncputc(int_type __c) { return std::putc(__c, _M_file); } template<> inline std::streamsize stdio_sync_filebuf::xsgetn(char* __s, std::streamsize __n) { std::streamsize __ret = std::fread(__s, 1, __n, _M_file); if (__ret > 0) _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); else _M_unget_buf = traits_type::eof(); return __ret; } template<> inline std::streamsize stdio_sync_filebuf::xsputn(const char* __s, std::streamsize __n) { return std::fwrite(__s, 1, __n, _M_file); } #ifdef _GLIBCXX_USE_WCHAR_T template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncgetc() { return std::getwc(_M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncungetc(int_type __c) { return std::ungetwc(__c, _M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncputc(int_type __c) { return std::putwc(__c, _M_file); } template<> inline std::streamsize stdio_sync_filebuf::xsgetn(wchar_t* __s, std::streamsize __n) { std::streamsize __ret = 0; const int_type __eof = traits_type::eof(); while (__n--) { int_type __c = this->syncgetc(); if (traits_type::eq_int_type(__c, __eof)) break; __s[__ret] = traits_type::to_char_type(__c); ++__ret; } if (__ret > 0) _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); else _M_unget_buf = traits_type::eof(); return __ret; } template<> inline std::streamsize stdio_sync_filebuf::xsputn(const wchar_t* __s, std::streamsize __n) { std::streamsize __ret = 0; const int_type __eof = traits_type::eof(); while (__n--) { if (traits_type::eq_int_type(this->syncputc(*__s++), __eof)) break; ++__ret; } return __ret; } #endif #if _GLIBCXX_EXTERN_TEMPLATE extern template class stdio_sync_filebuf; #ifdef _GLIBCXX_USE_WCHAR_T extern template class stdio_sync_filebuf; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]LލWW8/ext/random.tccnu[// Random number extensions -*- C++ -*- // Copyright (C) 2012-2018 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/random.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/random} */ #ifndef _EXT_RANDOM_TCC #define _EXT_RANDOM_TCC 1 #pragma GCC system_header namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: seed(_UIntType __seed) { _M_state32[0] = static_cast(__seed); for (size_t __i = 1; __i < _M_nstate32; ++__i) _M_state32[__i] = (1812433253UL * (_M_state32[__i - 1] ^ (_M_state32[__i - 1] >> 30)) + __i); _M_pos = state_size; _M_period_certification(); } namespace { inline uint32_t _Func1(uint32_t __x) { return (__x ^ (__x >> 27)) * UINT32_C(1664525); } inline uint32_t _Func2(uint32_t __x) { return (__x ^ (__x >> 27)) * UINT32_C(1566083941); } } template template typename std::enable_if::value>::type simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: seed(_Sseq& __q) { size_t __lag; if (_M_nstate32 >= 623) __lag = 11; else if (_M_nstate32 >= 68) __lag = 7; else if (_M_nstate32 >= 39) __lag = 5; else __lag = 3; const size_t __mid = (_M_nstate32 - __lag) / 2; std::fill(_M_state32, _M_state32 + _M_nstate32, UINT32_C(0x8b8b8b8b)); uint32_t __arr[_M_nstate32]; __q.generate(__arr + 0, __arr + _M_nstate32); uint32_t __r = _Func1(_M_state32[0] ^ _M_state32[__mid] ^ _M_state32[_M_nstate32 - 1]); _M_state32[__mid] += __r; __r += _M_nstate32; _M_state32[__mid + __lag] += __r; _M_state32[0] = __r; for (size_t __i = 1, __j = 0; __j < _M_nstate32; ++__j) { __r = _Func1(_M_state32[__i] ^ _M_state32[(__i + __mid) % _M_nstate32] ^ _M_state32[(__i + _M_nstate32 - 1) % _M_nstate32]); _M_state32[(__i + __mid) % _M_nstate32] += __r; __r += __arr[__j] + __i; _M_state32[(__i + __mid + __lag) % _M_nstate32] += __r; _M_state32[__i] = __r; __i = (__i + 1) % _M_nstate32; } for (size_t __j = 0; __j < _M_nstate32; ++__j) { const size_t __i = (__j + 1) % _M_nstate32; __r = _Func2(_M_state32[__i] + _M_state32[(__i + __mid) % _M_nstate32] + _M_state32[(__i + _M_nstate32 - 1) % _M_nstate32]); _M_state32[(__i + __mid) % _M_nstate32] ^= __r; __r -= __i; _M_state32[(__i + __mid + __lag) % _M_nstate32] ^= __r; _M_state32[__i] = __r; } _M_pos = state_size; _M_period_certification(); } template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_period_certification(void) { static const uint32_t __parity[4] = { __parity1, __parity2, __parity3, __parity4 }; uint32_t __inner = 0; for (size_t __i = 0; __i < 4; ++__i) if (__parity[__i] != 0) __inner ^= _M_state32[__i] & __parity[__i]; if (__builtin_parity(__inner) & 1) return; for (size_t __i = 0; __i < 4; ++__i) if (__parity[__i] != 0) { _M_state32[__i] ^= 1 << (__builtin_ffs(__parity[__i]) - 1); return; } __builtin_unreachable(); } template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: discard(unsigned long long __z) { while (__z > state_size - _M_pos) { __z -= state_size - _M_pos; _M_gen_rand(); } _M_pos += __z; } #ifndef _GLIBCXX_OPT_HAVE_RANDOM_SFMT_GEN_READ namespace { template inline void __rshift(uint32_t *__out, const uint32_t *__in) { uint64_t __th = ((static_cast(__in[3]) << 32) | static_cast(__in[2])); uint64_t __tl = ((static_cast(__in[1]) << 32) | static_cast(__in[0])); uint64_t __oh = __th >> (__shift * 8); uint64_t __ol = __tl >> (__shift * 8); __ol |= __th << (64 - __shift * 8); __out[1] = static_cast(__ol >> 32); __out[0] = static_cast(__ol); __out[3] = static_cast(__oh >> 32); __out[2] = static_cast(__oh); } template inline void __lshift(uint32_t *__out, const uint32_t *__in) { uint64_t __th = ((static_cast(__in[3]) << 32) | static_cast(__in[2])); uint64_t __tl = ((static_cast(__in[1]) << 32) | static_cast(__in[0])); uint64_t __oh = __th << (__shift * 8); uint64_t __ol = __tl << (__shift * 8); __oh |= __tl >> (64 - __shift * 8); __out[1] = static_cast(__ol >> 32); __out[0] = static_cast(__ol); __out[3] = static_cast(__oh >> 32); __out[2] = static_cast(__oh); } template inline void __recursion(uint32_t *__r, const uint32_t *__a, const uint32_t *__b, const uint32_t *__c, const uint32_t *__d) { uint32_t __x[4]; uint32_t __y[4]; __lshift<__sl2>(__x, __a); __rshift<__sr2>(__y, __c); __r[0] = (__a[0] ^ __x[0] ^ ((__b[0] >> __sr1) & __msk1) ^ __y[0] ^ (__d[0] << __sl1)); __r[1] = (__a[1] ^ __x[1] ^ ((__b[1] >> __sr1) & __msk2) ^ __y[1] ^ (__d[1] << __sl1)); __r[2] = (__a[2] ^ __x[2] ^ ((__b[2] >> __sr1) & __msk3) ^ __y[2] ^ (__d[2] << __sl1)); __r[3] = (__a[3] ^ __x[3] ^ ((__b[3] >> __sr1) & __msk4) ^ __y[3] ^ (__d[3] << __sl1)); } } template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_gen_rand(void) { const uint32_t *__r1 = &_M_state32[_M_nstate32 - 8]; const uint32_t *__r2 = &_M_state32[_M_nstate32 - 4]; static constexpr size_t __pos1_32 = __pos1 * 4; size_t __i; for (__i = 0; __i < _M_nstate32 - __pos1_32; __i += 4) { __recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (&_M_state32[__i], &_M_state32[__i], &_M_state32[__i + __pos1_32], __r1, __r2); __r1 = __r2; __r2 = &_M_state32[__i]; } for (; __i < _M_nstate32; __i += 4) { __recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (&_M_state32[__i], &_M_state32[__i], &_M_state32[__i + __pos1_32 - _M_nstate32], __r1, __r2); __r1 = __r2; __r2 = &_M_state32[__i]; } _M_pos = 0; } #endif #ifndef _GLIBCXX_OPT_HAVE_RANDOM_SFMT_OPERATOREQUAL template bool operator==(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { typedef __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4> __engine; return (std::equal(__lhs._M_stateT, __lhs._M_stateT + __engine::state_size, __rhs._M_stateT) && __lhs._M_pos == __rhs._M_pos); } #endif template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); for (size_t __i = 0; __i < __x._M_nstate32; ++__i) __os << __x._M_state32[__i] << __space; __os << __x._M_pos; __os.flags(__flags); __os.fill(__fill); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); for (size_t __i = 0; __i < __x._M_nstate32; ++__i) __is >> __x._M_state32[__i]; __is >> __x._M_pos; __is.flags(__flags); return __is; } #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /** * Iteration method due to M.D. Jhnk. * * M.D. Jhnk, Erzeugung von betaverteilten und gammaverteilten * Zufallszahlen, Metrika, Volume 8, 1964 */ template template typename beta_distribution<_RealType>::result_type beta_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __x, __y; do { __x = std::exp(std::log(__aurng()) / __param.alpha()); __y = std::exp(std::log(__aurng()) / __param.beta()); } while (__x + __y > result_type(1)); return __x / (__x + __y); } template template void beta_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { result_type __x, __y; do { __x = std::exp(std::log(__aurng()) / __param.alpha()); __y = std::exp(std::log(__aurng()) / __param.beta()); } while (__x + __y > result_type(1)); *__f++ = __x / (__x + __y); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.beta(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __beta_val; __is >> __alpha_val >> __beta_val; __x.param(typename __gnu_cxx::beta_distribution<_RealType>:: param_type(__alpha_val, __beta_val)); __is.flags(__flags); return __is; } template template void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); // Perform the Cholesky decomposition auto __w = _M_t.begin(); for (size_t __j = 0; __j < _Dimen; ++__j) { _RealType __sum = _RealType(0); auto __slitbegin = __w; auto __cit = _M_t.begin(); for (size_t __i = 0; __i < __j; ++__i) { auto __slit = __slitbegin; _RealType __s = *__varcovbegin++; for (size_t __k = 0; __k < __i; ++__k) __s -= *__slit++ * *__cit++; *__w++ = __s /= *__cit++; __sum += __s * __s; } __sum = *__varcovbegin - __sum; if (__builtin_expect(__sum <= _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_full")); *__w++ = std::sqrt(__sum); std::advance(__varcovbegin, _Dimen - __j); } } template template void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); // Perform the Cholesky decomposition auto __w = _M_t.begin(); for (size_t __j = 0; __j < _Dimen; ++__j) { _RealType __sum = _RealType(0); auto __slitbegin = __w; auto __cit = _M_t.begin(); for (size_t __i = 0; __i < __j; ++__i) { auto __slit = __slitbegin; _RealType __s = *__varcovbegin++; for (size_t __k = 0; __k < __i; ++__k) __s -= *__slit++ * *__cit++; *__w++ = __s /= *__cit++; __sum += __s * __s; } __sum = *__varcovbegin++ - __sum; if (__builtin_expect(__sum <= _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_full")); *__w++ = std::sqrt(__sum); } } template template void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); auto __w = _M_t.begin(); size_t __step = 0; while (__varbegin != __varend) { std::fill_n(__w, __step, _RealType(0)); __w += __step++; if (__builtin_expect(*__varbegin < _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_diagonal")); *__w++ = std::sqrt(*__varbegin++); } } template template typename normal_mv_distribution<_Dimen, _RealType>::result_type normal_mv_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { result_type __ret; _M_nd.__generate(__ret.begin(), __ret.end(), __urng); auto __t_it = __param._M_t.crbegin(); for (size_t __i = _Dimen; __i > 0; --__i) { _RealType __sum = _RealType(0); for (size_t __j = __i; __j > 0; --__j) __sum += __ret[__j - 1] * *__t_it++; __ret[__i - 1] = __sum; } return __ret; } template template void normal_mv_distribution<_Dimen, _RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); auto __mean = __x._M_param.mean(); for (auto __it : __mean) __os << __it << __space; auto __t = __x._M_param.varcov(); for (auto __it : __t) __os << __it << __space; __os << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); std::array<_RealType, _Dimen> __mean; for (auto& __it : __mean) __is >> __it; std::array<_RealType, _Dimen * (_Dimen + 1) / 2> __varcov; for (auto& __it : __varcov) __is >> __it; __is >> __x._M_nd; __x.param(typename normal_mv_distribution<_Dimen, _RealType>:: param_type(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end())); __is.flags(__flags); return __is; } template template void rice_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) { typename std::normal_distribution::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 *__f++ = std::hypot(__x, __y); #else *__f++ = std::sqrt(__x * __x + __y * __y); #endif } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const rice_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.nu() << __space << __x.sigma(); __os << __space << __x._M_ndx; __os << __space << __x._M_ndy; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, rice_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __nu_val, __sigma_val; __is >> __nu_val >> __sigma_val; __is >> __x._M_ndx; __is >> __x._M_ndy; __x.param(typename rice_distribution<_RealType>:: param_type(__nu_val, __sigma_val)); __is.flags(__flags); return __is; } template template void nakagami_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) typename std::gamma_distribution::param_type __pg(__p.mu(), __p.omega() / __p.mu()); while (__f != __t) *__f++ = std::sqrt(this->_M_gd(__pg, __urng)); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const nakagami_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mu() << __space << __x.omega(); __os << __space << __x._M_gd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, nakagami_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __mu_val, __omega_val; __is >> __mu_val >> __omega_val; __is >> __x._M_gd; __x.param(typename nakagami_distribution<_RealType>:: param_type(__mu_val, __omega_val)); __is.flags(__flags); return __is; } template template void pareto_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __mu_val = __p.mu(); result_type __malphinv = -result_type(1) / __p.alpha(); while (__f != __t) *__f++ = __mu_val * std::pow(this->_M_ud(__urng), __malphinv); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const pareto_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.mu(); __os << __space << __x._M_ud; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, pareto_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __mu_val; __is >> __alpha_val >> __mu_val; __is >> __x._M_ud; __x.param(typename pareto_distribution<_RealType>:: param_type(__alpha_val, __mu_val)); __is.flags(__flags); return __is; } template template typename k_distribution<_RealType>::result_type k_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_gd1(__urng); result_type __y = this->_M_gd2(__urng); return std::sqrt(__x * __y); } template template typename k_distribution<_RealType>::result_type k_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution::param_type __p1(__p.lambda(), result_type(1) / __p.lambda()), __p2(__p.nu(), __p.mu() / __p.nu()); result_type __x = this->_M_gd1(__p1, __urng); result_type __y = this->_M_gd2(__p2, __urng); return std::sqrt(__x * __y); } template template void k_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) typename std::gamma_distribution::param_type __p1(__p.lambda(), result_type(1) / __p.lambda()), __p2(__p.nu(), __p.mu() / __p.nu()); while (__f != __t) { result_type __x = this->_M_gd1(__p1, __urng); result_type __y = this->_M_gd2(__p2, __urng); *__f++ = std::sqrt(__x * __y); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const k_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.lambda() << __space << __x.mu() << __space << __x.nu(); __os << __space << __x._M_gd1; __os << __space << __x._M_gd2; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, k_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __lambda_val, __mu_val, __nu_val; __is >> __lambda_val >> __mu_val >> __nu_val; __is >> __x._M_gd1; __is >> __x._M_gd2; __x.param(typename k_distribution<_RealType>:: param_type(__lambda_val, __mu_val, __nu_val)); __is.flags(__flags); return __is; } template template void arcsine_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __dif = __p.b() - __p.a(); result_type __sum = __p.a() + __p.b(); while (__f != __t) { result_type __x = std::sin(this->_M_ud(__urng)); *__f++ = (__x * __dif + __sum) / result_type(2); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const arcsine_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os << __space << __x._M_ud; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, arcsine_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; __is >> __a >> __b; __is >> __x._M_ud; __x.param(typename arcsine_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template template typename hoyt_distribution<_RealType>::result_type hoyt_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ad(__urng); result_type __y = this->_M_ed(__urng); return (result_type(2) * this->q() / (result_type(1) + this->q() * this->q())) * std::sqrt(this->omega() * __x * __y); } template template typename hoyt_distribution<_RealType>::result_type hoyt_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { result_type __q2 = __p.q() * __p.q(); result_type __num = result_type(0.5L) * (result_type(1) + __q2); typename __gnu_cxx::arcsine_distribution::param_type __pa(__num, __num / __q2); result_type __x = this->_M_ad(__pa, __urng); result_type __y = this->_M_ed(__urng); return (result_type(2) * __p.q() / (result_type(1) + __q2)) * std::sqrt(__p.omega() * __x * __y); } template template void hoyt_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __2q = result_type(2) * __p.q(); result_type __q2 = __p.q() * __p.q(); result_type __q2p1 = result_type(1) + __q2; result_type __num = result_type(0.5L) * __q2p1; result_type __omega = __p.omega(); typename __gnu_cxx::arcsine_distribution::param_type __pa(__num, __num / __q2); while (__f != __t) { result_type __x = this->_M_ad(__pa, __urng); result_type __y = this->_M_ed(__urng); *__f++ = (__2q / __q2p1) * std::sqrt(__omega * __x * __y); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const hoyt_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.q() << __space << __x.omega(); __os << __space << __x._M_ad; __os << __space << __x._M_ed; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, hoyt_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __q, __omega; __is >> __q >> __omega; __is >> __x._M_ad; __is >> __x._M_ed; __x.param(typename hoyt_distribution<_RealType>:: param_type(__q, __omega)); __is.flags(__flags); return __is; } template template void triangular_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::triangular_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b() << __space << __x.c(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::triangular_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b, __c; __is >> __a >> __b >> __c; __x.param(typename __gnu_cxx::triangular_distribution<_RealType>:: param_type(__a, __b, __c)); __is.flags(__flags); return __is; } template template typename von_mises_distribution<_RealType>::result_type von_mises_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { const result_type __pi = __gnu_cxx::__math_constants::__pi; std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __f; while (1) { result_type __rnd = std::cos(__pi * __aurng()); __f = (result_type(1) + __p._M_r * __rnd) / (__p._M_r + __rnd); result_type __c = __p._M_kappa * (__p._M_r - __f); result_type __rnd2 = __aurng(); if (__c * (result_type(2) - __c) > __rnd2) break; if (std::log(__c / __rnd2) >= __c - result_type(1)) break; } result_type __res = std::acos(__f); #if _GLIBCXX_USE_C99_MATH_TR1 __res = std::copysign(__res, __aurng() - result_type(0.5)); #else if (__aurng() < result_type(0.5)) __res = -__res; #endif __res += __p._M_mu; if (__res > __pi) __res -= result_type(2) * __pi; else if (__res < -__pi) __res += result_type(2) * __pi; return __res; } template template void von_mises_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::von_mises_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mu() << __space << __x.kappa(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::von_mises_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __mu, __kappa; __is >> __mu >> __kappa; __x.param(typename __gnu_cxx::von_mises_distribution<_RealType>:: param_type(__mu, __kappa)); __is.flags(__flags); return __is; } template template typename hypergeometric_distribution<_UIntType>::result_type hypergeometric_distribution<_UIntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); result_type __a = __param.successful_size(); result_type __b = __param.total_size(); result_type __k = 0; if (__param.total_draws() < __param.total_size() / 2) { for (result_type __i = 0; __i < __param.total_draws(); ++__i) { if (__b * __aurng() < __a) { ++__k; if (__k == __param.successful_size()) return __k; --__a; } --__b; } return __k; } else { for (result_type __i = 0; __i < __param.unsuccessful_size(); ++__i) { if (__b * __aurng() < __a) { ++__k; if (__k == __param.successful_size()) return __param.successful_size() - __k; --__a; } --__b; } return __param.successful_size() - __k; } } template template void hypergeometric_distribution<_UIntType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_UIntType>::max_digits10); __os << __x.total_size() << __space << __x.successful_size() << __space << __x.total_draws(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _UIntType __total_size, __successful_size, __total_draws; __is >> __total_size >> __successful_size >> __total_draws; __x.param(typename __gnu_cxx::hypergeometric_distribution<_UIntType>:: param_type(__total_size, __successful_size, __total_draws)); __is.flags(__flags); return __is; } template template typename logistic_distribution<_RealType>::result_type logistic_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __arg = result_type(1); while (__arg == result_type(1) || __arg == result_type(0)) __arg = __aurng(); return __p.a() + __p.b() * std::log(__arg / (result_type(1) - __arg)); } template template void logistic_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { result_type __arg = result_type(1); while (__arg == result_type(1) || __arg == result_type(0)) __arg = __aurng(); *__f++ = __p.a() + __p.b() * std::log(__arg / (result_type(1) - __arg)); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const logistic_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, logistic_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; __is >> __a >> __b; __x.param(typename logistic_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } namespace { // Helper class for the uniform_on_sphere_distribution generation // function. template class uniform_on_sphere_helper { typedef typename uniform_on_sphere_distribution<_Dimen, _RealType>:: result_type result_type; public: template result_type operator()(_NormalDistribution& __nd, _UniformRandomNumberGenerator& __urng) { result_type __ret; typename result_type::value_type __norm; do { auto __sum = _RealType(0); std::generate(__ret.begin(), __ret.end(), [&__nd, &__urng, &__sum](){ _RealType __t = __nd(__urng); __sum += __t * __t; return __t; }); __norm = std::sqrt(__sum); } while (__norm == _RealType(0) || ! __builtin_isfinite(__norm)); std::transform(__ret.begin(), __ret.end(), __ret.begin(), [__norm](_RealType __val){ return __val / __norm; }); return __ret; } }; template class uniform_on_sphere_helper<2, _RealType> { typedef typename uniform_on_sphere_distribution<2, _RealType>:: result_type result_type; public: template result_type operator()(_NormalDistribution&, _UniformRandomNumberGenerator& __urng) { result_type __ret; _RealType __sq; std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); do { __ret[0] = _RealType(2) * __aurng() - _RealType(1); __ret[1] = _RealType(2) * __aurng() - _RealType(1); __sq = __ret[0] * __ret[0] + __ret[1] * __ret[1]; } while (__sq == _RealType(0) || __sq > _RealType(1)); #if _GLIBCXX_USE_C99_MATH_TR1 // Yes, we do not just use sqrt(__sq) because hypot() is more // accurate. auto __norm = std::hypot(__ret[0], __ret[1]); #else auto __norm = std::sqrt(__sq); #endif __ret[0] /= __norm; __ret[1] /= __norm; return __ret; } }; } template template typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type uniform_on_sphere_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { uniform_on_sphere_helper<_Dimen, _RealType> __helper; return __helper(_M_nd, __urng); } template template void uniform_on_sphere_distribution<_Dimen, _RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __x) { return __os << __x._M_nd; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __x) { return __is >> __x._M_nd; } namespace { // Helper class for the uniform_inside_sphere_distribution generation // function. template class uniform_inside_sphere_helper; template class uniform_inside_sphere_helper<_Dimen, false, _RealType> { using result_type = typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: result_type; public: template result_type operator()(_UniformOnSphereDistribution& __uosd, _UniformRandomNumberGenerator& __urng, _RealType __radius) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); _RealType __pow = 1 / _RealType(_Dimen); _RealType __urt = __radius * std::pow(__aurng(), __pow); result_type __ret = __uosd(__aurng); std::transform(__ret.begin(), __ret.end(), __ret.begin(), [__urt](_RealType __val) { return __val * __urt; }); return __ret; } }; // Helper class for the uniform_inside_sphere_distribution generation // function specialized for small dimensions. template class uniform_inside_sphere_helper<_Dimen, true, _RealType> { using result_type = typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: result_type; public: template result_type operator()(_UniformOnSphereDistribution&, _UniformRandomNumberGenerator& __urng, _RealType __radius) { result_type __ret; _RealType __sq; _RealType __radsq = __radius * __radius; std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); do { __sq = _RealType(0); for (int i = 0; i < _Dimen; ++i) { __ret[i] = _RealType(2) * __aurng() - _RealType(1); __sq += __ret[i] * __ret[i]; } } while (__sq > _RealType(1)); for (int i = 0; i < _Dimen; ++i) __ret[i] *= __radius; return __ret; } }; } // namespace // // Experiments have shown that rejection is more efficient than transform // for dimensions less than 8. // template template typename uniform_inside_sphere_distribution<_Dimen, _RealType>::result_type uniform_inside_sphere_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { uniform_inside_sphere_helper<_Dimen, _Dimen < 8, _RealType> __helper; return __helper(_M_uosd, __urng, __p.radius()); } template template void uniform_inside_sphere_distribution<_Dimen, _RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.radius() << __space << __x._M_uosd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __radius_val; __is >> __radius_val >> __x._M_uosd; __x.param(typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: param_type(__radius_val)); __is.flags(__flags); return __is; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif // _EXT_RANDOM_TCC PKgd1]FF8/ext/alloc_traits.hnu[// Allocator traits -*- C++ -*- // Copyright (C) 2011-2018 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. */ #ifndef _EXT_ALLOC_TRAITS_H #define _EXT_ALLOC_TRAITS_H 1 #pragma GCC system_header #if __cplusplus >= 201103L # include # include #else # include // for __alloc_swap #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Uniform interface to C++98 and C++11 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::__and_, std::__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::__to_address(__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::__to_address(__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) { std::__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 _Base_type::is_always_equal::value; } static constexpr bool _S_nothrow_move() { return _S_propagate_on_move_assign() || _S_always_equal(); } 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 __gnu_cxx #endif PKgd1],y1778/ext/functionalnu[// Functional extensions -*- C++ -*- // Copyright (C) 2002-2018 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 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file ext/functional * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_FUNCTIONAL #define _EXT_FUNCTIONAL 1 #pragma GCC system_header #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::unary_function; using std::binary_function; using std::mem_fun1_t; using std::const_mem_fun1_t; using std::mem_fun1_ref_t; using std::const_mem_fun1_ref_t; /** The @c identity_element functions are not part of the C++ * standard; SGI provided them as an extension. Its argument is an * operation, and its return value is the identity element for that * operation. It is overloaded for addition and multiplication, * and you can overload it for your own nefarious operations. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template inline _Tp identity_element(std::plus<_Tp>) { return _Tp(0); } /// An \link SGIextensions SGI extension \endlink. template inline _Tp identity_element(std::multiplies<_Tp>) { return _Tp(1); } /** @} */ /** As an extension to the binders, SGI provided composition functors and * wrapper functions to aid in their creation. The @c unary_compose * functor is constructed from two functions/functors, @c f and @c g. * Calling @c operator() with a single argument @c x returns @c f(g(x)). * The function @c compose1 takes the two functions and constructs a * @c unary_compose variable for you. * * @c binary_compose is constructed from three functors, @c f, @c g1, * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function * compose2 takes f, g1, and g2, and constructs the @c binary_compose * instance for you. For example, if @c f returns an int, then * \code * int answer = (compose2(f,g1,g2))(x); * \endcode * is equivalent to * \code * int temp1 = g1(x); * int temp2 = g2(x); * int answer = f(temp1,temp2); * \endcode * But the first form is more compact, and can be passed around as a * functor to other algorithms. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template class unary_compose : public unary_function { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; public: unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {} typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x)); } }; /// An \link SGIextensions SGI extension \endlink. template inline unary_compose<_Operation1, _Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } /// An \link SGIextensions SGI extension \endlink. template class binary_compose : public unary_function { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; _Operation3 _M_fn3; public: binary_compose(const _Operation1& __x, const _Operation2& __y, const _Operation3& __z) : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } }; /// An \link SGIextensions SGI extension \endlink. template inline binary_compose<_Operation1, _Operation2, _Operation3> compose2(const _Operation1& __fn1, const _Operation2& __fn2, const _Operation3& __fn3) { return binary_compose<_Operation1, _Operation2, _Operation3> (__fn1, __fn2, __fn3); } /** @} */ /** As an extension, SGI provided a functor called @c identity. When a * functor is required but no operations are desired, this can be used as a * pass-through. Its @c operator() returns its argument unchanged. * * @addtogroup SGIextensions */ template struct identity : public std::_Identity<_Tp> {}; /** @c select1st and @c select2nd are extensions provided by SGI. Their * @c operator()s * take a @c std::pair as an argument, and return either the first member * or the second member, respectively. They can be used (especially with * the composition functors) to @a strip data from a sequence before * performing the remainder of an algorithm. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template struct select1st : public std::_Select1st<_Pair> {}; /// An \link SGIextensions SGI extension \endlink. template struct select2nd : public std::_Select2nd<_Pair> {}; /** @} */ // extension documented next template struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } }; template struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; /** The @c operator() of the @c project1st functor takes two arbitrary * arguments and returns the first one, while @c project2nd returns the * second one. They are extensions provided by SGI. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template struct project1st : public _Project1st<_Arg1, _Arg2> {}; /// An \link SGIextensions SGI extension \endlink. template struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; /** @} */ // extension documented next template struct _Constant_void_fun { typedef _Result result_type; result_type _M_val; _Constant_void_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()() const { return _M_val; } }; template struct _Constant_unary_fun { typedef _Argument argument_type; typedef _Result result_type; result_type _M_val; _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()(const _Argument&) const { return _M_val; } }; template struct _Constant_binary_fun { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; _Result _M_val; _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} const result_type& operator()(const _Arg1&, const _Arg2&) const { return _M_val; } }; /** These three functors are each constructed from a single arbitrary * variable/value. Later, their @c operator()s completely ignore any * arguments passed, and return the stored value. * - @c constant_void_fun's @c operator() takes no arguments * - @c constant_unary_fun's @c operator() takes one argument (ignored) * - @c constant_binary_fun's @c operator() takes two arguments (ignored) * * The helper creator functions @c constant0, @c constant1, and * @c constant2 each take a @a result argument and construct variables of * the appropriate functor type. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template struct constant_void_fun : public _Constant_void_fun<_Result> { constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> { constant_unary_fun(const _Result& __v) : _Constant_unary_fun<_Result, _Argument>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template struct constant_binary_fun : public _Constant_binary_fun<_Result, _Arg1, _Arg2> { constant_binary_fun(const _Result& __v) : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template inline constant_void_fun<_Result> constant0(const _Result& __val) { return constant_void_fun<_Result>(__val); } /// An \link SGIextensions SGI extension \endlink. template inline constant_unary_fun<_Result, _Result> constant1(const _Result& __val) { return constant_unary_fun<_Result, _Result>(__val); } /// An \link SGIextensions SGI extension \endlink. template inline constant_binary_fun<_Result,_Result,_Result> constant2(const _Result& __val) { return constant_binary_fun<_Result, _Result, _Result>(__val); } /** @} */ /** The @c subtractive_rng class is documented on * SGI's site. * Note that this code assumes that @c int is 32 bits. * * @ingroup SGIextensions */ class subtractive_rng : public unary_function { private: unsigned int _M_table[55]; size_t _M_index1; size_t _M_index2; public: /// Returns a number less than the argument. unsigned int operator()(unsigned int __limit) { _M_index1 = (_M_index1 + 1) % 55; _M_index2 = (_M_index2 + 1) % 55; _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; return _M_table[_M_index1] % __limit; } void _M_initialize(unsigned int __seed) { unsigned int __k = 1; _M_table[54] = __seed; size_t __i; for (__i = 0; __i < 54; __i++) { size_t __ii = (21 * (__i + 1) % 55) - 1; _M_table[__ii] = __k; __k = __seed - __k; __seed = _M_table[__ii]; } for (int __loop = 0; __loop < 4; __loop++) { for (__i = 0; __i < 55; __i++) _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; } _M_index1 = 0; _M_index2 = 31; } /// Ctor allowing you to initialize the seed. subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } /// Default ctor; initializes its state with some number you don't see. subtractive_rng() { _M_initialize(161803398u); } }; // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, // provided for backward compatibility, they are no longer part of // the C++ standard. template inline mem_fun1_t<_Ret, _Tp, _Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template inline const_mem_fun1_t<_Ret, _Tp, _Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template inline mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun1_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_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1]pл8/ext/concurrence.hnu[// Support for concurrent programing -*- C++ -*- // Copyright (C) 2003-2018 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/concurrence.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _CONCURRENCE_H #define _CONCURRENCE_H 1 #pragma GCC system_header #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Available locking policies: // _S_single single-threaded code that doesn't need to be locked. // _S_mutex multi-threaded code that requires additional support // from gthr.h or abstraction layers in concurrence.h. // _S_atomic multi-threaded code using atomic operations. enum _Lock_policy { _S_single, _S_mutex, _S_atomic }; // Compile time constant that indicates prefered locking policy in // the current configuration. static const _Lock_policy __default_lock_policy = #ifdef __GTHREADS #if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \ && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) _S_atomic; #else _S_mutex; #endif #else _S_single; #endif // NB: As this is used in libsupc++, need to only depend on // exception. No stdexception classes, no use of std::string. class __concurrence_lock_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_lock_error"; } }; class __concurrence_unlock_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_unlock_error"; } }; class __concurrence_broadcast_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_broadcast_error"; } }; class __concurrence_wait_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_wait_error"; } }; // Substitute for concurrence_error object in the case of -fno-exceptions. inline void __throw_concurrence_lock_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_lock_error()); } inline void __throw_concurrence_unlock_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_unlock_error()); } #ifdef __GTHREAD_HAS_COND inline void __throw_concurrence_broadcast_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_broadcast_error()); } inline void __throw_concurrence_wait_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_wait_error()); } #endif class __mutex { private: #if __GTHREADS && defined __GTHREAD_MUTEX_INIT __gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT; #else __gthread_mutex_t _M_mutex; #endif __mutex(const __mutex&); __mutex& operator=(const __mutex&); public: __mutex() { #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT if (__gthread_active_p()) __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); #endif } #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT ~__mutex() { if (__gthread_active_p()) __gthread_mutex_destroy(&_M_mutex); } #endif void lock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_mutex_lock(&_M_mutex) != 0) __throw_concurrence_lock_error(); } #endif } void unlock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_mutex_unlock(&_M_mutex) != 0) __throw_concurrence_unlock_error(); } #endif } __gthread_mutex_t* gthread_mutex(void) { return &_M_mutex; } }; class __recursive_mutex { private: #if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT __gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; #else __gthread_recursive_mutex_t _M_mutex; #endif __recursive_mutex(const __recursive_mutex&); __recursive_mutex& operator=(const __recursive_mutex&); public: __recursive_mutex() { #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT if (__gthread_active_p()) __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); #endif } #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT ~__recursive_mutex() { if (__gthread_active_p()) __gthread_recursive_mutex_destroy(&_M_mutex); } #endif void lock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_recursive_mutex_lock(&_M_mutex) != 0) __throw_concurrence_lock_error(); } #endif } void unlock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0) __throw_concurrence_unlock_error(); } #endif } __gthread_recursive_mutex_t* gthread_recursive_mutex(void) { return &_M_mutex; } }; /// Scoped lock idiom. // Acquire the mutex here with a constructor call, then release with // the destructor call in accordance with RAII style. class __scoped_lock { public: typedef __mutex __mutex_type; private: __mutex_type& _M_device; __scoped_lock(const __scoped_lock&); __scoped_lock& operator=(const __scoped_lock&); public: explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) { _M_device.lock(); } ~__scoped_lock() throw() { _M_device.unlock(); } }; #ifdef __GTHREAD_HAS_COND class __cond { private: #if __GTHREADS && defined __GTHREAD_COND_INIT __gthread_cond_t _M_cond = __GTHREAD_COND_INIT; #else __gthread_cond_t _M_cond; #endif __cond(const __cond&); __cond& operator=(const __cond&); public: __cond() { #if __GTHREADS && ! defined __GTHREAD_COND_INIT if (__gthread_active_p()) __GTHREAD_COND_INIT_FUNCTION(&_M_cond); #endif } #if __GTHREADS && ! defined __GTHREAD_COND_INIT ~__cond() { if (__gthread_active_p()) __gthread_cond_destroy(&_M_cond); } #endif void broadcast() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_cond_broadcast(&_M_cond) != 0) __throw_concurrence_broadcast_error(); } #endif } void wait(__mutex *mutex) { #if __GTHREADS { if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0) __throw_concurrence_wait_error(); } #endif } void wait_recursive(__recursive_mutex *mutex) { #if __GTHREADS { if (__gthread_cond_wait_recursive(&_M_cond, mutex->gthread_recursive_mutex()) != 0) __throw_concurrence_wait_error(); } #endif } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif PKgd1].[[8/ext/mt_allocator.hnu[// MT-optimized allocator -*- C++ -*- // Copyright (C) 2003-2018 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/mt_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _MT_ALLOCATOR_H #define _MT_ALLOCATOR_H 1 #include #include #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; typedef void (*__destroy_handler)(void*); /// Base class for pool object. struct __pool_base { // Using short int as type for the binmap implies we are never // caching blocks larger than 32768 with this allocator. typedef unsigned short int _Binmap_type; // Variables used to configure the behavior of the allocator, // assigned and explained in detail below. struct _Tune { // Compile time constants for the default _Tune values. enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; enum { _S_min_bin = 8 }; enum { _S_chunk_size = 4096 - 4 * sizeof(void*) }; enum { _S_max_threads = 4096 }; enum { _S_freelist_headroom = 10 }; // Alignment needed. // NB: In any case must be >= sizeof(_Block_record), that // is 4 on 32 bit machines and 8 on 64 bit machines. size_t _M_align; // Allocation requests (after round-up to power of 2) below // this value will be handled by the allocator. A raw new/ // call will be used for requests larger than this value. // NB: Must be much smaller than _M_chunk_size and in any // case <= 32768. size_t _M_max_bytes; // Size in bytes of the smallest bin. // NB: Must be a power of 2 and >= _M_align (and of course // much smaller than _M_max_bytes). size_t _M_min_bin; // In order to avoid fragmenting and minimize the number of // new() calls we always request new memory using this // value. Based on previous discussions on the libstdc++ // mailing list we have chosen the value below. // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html // NB: At least one order of magnitude > _M_max_bytes. size_t _M_chunk_size; // The maximum number of supported threads. For // single-threaded operation, use one. Maximum values will // vary depending on details of the underlying system. (For // instance, Linux 2.4.18 reports 4070 in // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports // 65534) size_t _M_max_threads; // Each time a deallocation occurs in a threaded application // we make sure that there are no more than // _M_freelist_headroom % of used memory on the freelist. If // the number of additional records is more than // _M_freelist_headroom % of the freelist, we move these // records back to the global pool. size_t _M_freelist_headroom; // Set to true forces all allocations to use new(). bool _M_force_new; explicit _Tune() : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin), _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads), _M_freelist_headroom(_S_freelist_headroom), _M_force_new(std::getenv("GLIBCXX_FORCE_NEW") ? true : false) { } explicit _Tune(size_t __align, size_t __maxb, size_t __minbin, size_t __chunk, size_t __maxthreads, size_t __headroom, bool __force) : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), _M_chunk_size(__chunk), _M_max_threads(__maxthreads), _M_freelist_headroom(__headroom), _M_force_new(__force) { } }; struct _Block_address { void* _M_initial; _Block_address* _M_next; }; const _Tune& _M_get_options() const { return _M_options; } void _M_set_options(_Tune __t) { if (!_M_init) _M_options = __t; } bool _M_check_threshold(size_t __bytes) { return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; } size_t _M_get_binmap(size_t __bytes) { return _M_binmap[__bytes]; } size_t _M_get_align() { return _M_options._M_align; } explicit __pool_base() : _M_options(_Tune()), _M_binmap(0), _M_init(false) { } explicit __pool_base(const _Tune& __options) : _M_options(__options), _M_binmap(0), _M_init(false) { } private: explicit __pool_base(const __pool_base&); __pool_base& operator=(const __pool_base&); protected: // Configuration options. _Tune _M_options; _Binmap_type* _M_binmap; // Configuration of the pool object via _M_options can happen // after construction but before initialization. After // initialization is complete, this variable is set to true. bool _M_init; }; /** * @brief Data describing the underlying memory pool, parameterized on * threading support. */ template class __pool; /// Specialization for single thread. template<> class __pool : public __pool_base { public: union _Block_record { // Points to the block_record of the next free block. _Block_record* _M_next; }; struct _Bin_record { // An "array" of pointers to the first free block. _Block_record** _M_first; // A list of the initial addresses of all allocated blocks. _Block_address* _M_address; }; void _M_initialize_once() { if (__builtin_expect(_M_init == false, false)) _M_initialize(); } void _M_destroy() throw(); char* _M_reserve_block(size_t __bytes, const size_t __thread_id); void _M_reclaim_block(char* __p, size_t __bytes) throw (); size_t _M_get_thread_id() { return 0; } const _Bin_record& _M_get_bin(size_t __which) { return _M_bin[__which]; } void _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) { } explicit __pool() : _M_bin(0), _M_bin_size(1) { } explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(0), _M_bin_size(1) { } private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in // _M_initialize(). _Bin_record* _M_bin; // Actual value calculated in _M_initialize(). size_t _M_bin_size; void _M_initialize(); }; #ifdef __GTHREADS /// Specialization for thread enabled, via gthreads.h. template<> class __pool : public __pool_base { public: // Each requesting thread is assigned an id ranging from 1 to // _S_max_threads. Thread id 0 is used as a global memory pool. // In order to get constant performance on the thread assignment // routine, we keep a list of free ids. When a thread first // requests memory we remove the first record in this list and // stores the address in a __gthread_key. When initializing the // __gthread_key we specify a destructor. When this destructor // (i.e. the thread dies) is called, we return the thread id to // the front of this list. struct _Thread_record { // Points to next free thread id record. NULL if last record in list. _Thread_record* _M_next; // Thread id ranging from 1 to _S_max_threads. size_t _M_id; }; union _Block_record { // Points to the block_record of the next free block. _Block_record* _M_next; // The thread id of the thread which has requested this block. size_t _M_thread_id; }; struct _Bin_record { // An "array" of pointers to the first free block for each // thread id. Memory to this "array" is allocated in // _S_initialize() for _S_max_threads + global pool 0. _Block_record** _M_first; // A list of the initial addresses of all allocated blocks. _Block_address* _M_address; // An "array" of counters used to keep track of the amount of // blocks that are on the freelist/used for each thread id. // - Note that the second part of the allocated _M_used "array" // actually hosts (atomic) counters of reclaimed blocks: in // _M_reserve_block and in _M_reclaim_block those numbers are // subtracted from the first ones to obtain the actual size // of the "working set" of the given thread. // - Memory to these "arrays" is allocated in _S_initialize() // for _S_max_threads + global pool 0. size_t* _M_free; size_t* _M_used; // Each bin has its own mutex which is used to ensure data // integrity while changing "ownership" on a block. The mutex // is initialized in _S_initialize(). __gthread_mutex_t* _M_mutex; }; // XXX GLIBCXX_ABI Deprecated void _M_initialize(__destroy_handler); void _M_initialize_once() { if (__builtin_expect(_M_init == false, false)) _M_initialize(); } void _M_destroy() throw(); char* _M_reserve_block(size_t __bytes, const size_t __thread_id); void _M_reclaim_block(char* __p, size_t __bytes) throw (); const _Bin_record& _M_get_bin(size_t __which) { return _M_bin[__which]; } void _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block, size_t __thread_id) { if (__gthread_active_p()) { __block->_M_thread_id = __thread_id; --__bin._M_free[__thread_id]; ++__bin._M_used[__thread_id]; } } // XXX GLIBCXX_ABI Deprecated void _M_destroy_thread_key(void*) throw (); size_t _M_get_thread_id(); explicit __pool() : _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) { } explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) { } private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in // _M_initialize(). _Bin_record* _M_bin; // Actual value calculated in _M_initialize(). size_t _M_bin_size; _Thread_record* _M_thread_freelist; void* _M_thread_freelist_initial; void _M_initialize(); }; #endif template