1*404b540aSrobert// Functional extensions -*- C++ -*- 2*404b540aSrobert 3*404b540aSrobert// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 4*404b540aSrobert// 5*404b540aSrobert// This file is part of the GNU ISO C++ Library. This library is free 6*404b540aSrobert// software; you can redistribute it and/or modify it under the 7*404b540aSrobert// terms of the GNU General Public License as published by the 8*404b540aSrobert// Free Software Foundation; either version 2, or (at your option) 9*404b540aSrobert// any later version. 10*404b540aSrobert 11*404b540aSrobert// This library is distributed in the hope that it will be useful, 12*404b540aSrobert// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*404b540aSrobert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*404b540aSrobert// GNU General Public License for more details. 15*404b540aSrobert 16*404b540aSrobert// You should have received a copy of the GNU General Public License along 17*404b540aSrobert// with this library; see the file COPYING. If not, write to the Free 18*404b540aSrobert// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19*404b540aSrobert// USA. 20*404b540aSrobert 21*404b540aSrobert// As a special exception, you may use this file as part of a free software 22*404b540aSrobert// library without restriction. Specifically, if other files instantiate 23*404b540aSrobert// templates or use macros or inline functions from this file, or you compile 24*404b540aSrobert// this file and link it with other files to produce an executable, this 25*404b540aSrobert// file does not by itself cause the resulting executable to be covered by 26*404b540aSrobert// the GNU General Public License. This exception does not however 27*404b540aSrobert// invalidate any other reasons why the executable file might be covered by 28*404b540aSrobert// the GNU General Public License. 29*404b540aSrobert 30*404b540aSrobert/* 31*404b540aSrobert * 32*404b540aSrobert * Copyright (c) 1994 33*404b540aSrobert * Hewlett-Packard Company 34*404b540aSrobert * 35*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software 36*404b540aSrobert * and its documentation for any purpose is hereby granted without fee, 37*404b540aSrobert * provided that the above copyright notice appear in all copies and 38*404b540aSrobert * that both that copyright notice and this permission notice appear 39*404b540aSrobert * in supporting documentation. Hewlett-Packard Company makes no 40*404b540aSrobert * representations about the suitability of this software for any 41*404b540aSrobert * purpose. It is provided "as is" without express or implied warranty. 42*404b540aSrobert * 43*404b540aSrobert * 44*404b540aSrobert * Copyright (c) 1996 45*404b540aSrobert * Silicon Graphics Computer Systems, Inc. 46*404b540aSrobert * 47*404b540aSrobert * Permission to use, copy, modify, distribute and sell this software 48*404b540aSrobert * and its documentation for any purpose is hereby granted without fee, 49*404b540aSrobert * provided that the above copyright notice appear in all copies and 50*404b540aSrobert * that both that copyright notice and this permission notice appear 51*404b540aSrobert * in supporting documentation. Silicon Graphics makes no 52*404b540aSrobert * representations about the suitability of this software for any 53*404b540aSrobert * purpose. It is provided "as is" without express or implied warranty. 54*404b540aSrobert */ 55*404b540aSrobert 56*404b540aSrobert/** @file ext/functional 57*404b540aSrobert * This file is a GNU extension to the Standard C++ Library (possibly 58*404b540aSrobert * containing extensions from the HP/SGI STL subset). 59*404b540aSrobert */ 60*404b540aSrobert 61*404b540aSrobert#ifndef _EXT_FUNCTIONAL 62*404b540aSrobert#define _EXT_FUNCTIONAL 1 63*404b540aSrobert 64*404b540aSrobert#pragma GCC system_header 65*404b540aSrobert 66*404b540aSrobert#include <functional> 67*404b540aSrobert 68*404b540aSrobert_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 69*404b540aSrobert 70*404b540aSrobert using std::size_t; 71*404b540aSrobert using std::unary_function; 72*404b540aSrobert using std::binary_function; 73*404b540aSrobert using std::mem_fun1_t; 74*404b540aSrobert using std::const_mem_fun1_t; 75*404b540aSrobert using std::mem_fun1_ref_t; 76*404b540aSrobert using std::const_mem_fun1_ref_t; 77*404b540aSrobert 78*404b540aSrobert /** The @c identity_element functions are not part of the C++ 79*404b540aSrobert * standard; SGI provided them as an extension. Its argument is an 80*404b540aSrobert * operation, and its return value is the identity element for that 81*404b540aSrobert * operation. It is overloaded for addition and multiplication, 82*404b540aSrobert * and you can overload it for your own nefarious operations. 83*404b540aSrobert * 84*404b540aSrobert * @addtogroup SGIextensions 85*404b540aSrobert * @{ 86*404b540aSrobert */ 87*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 88*404b540aSrobert template <class _Tp> 89*404b540aSrobert inline _Tp 90*404b540aSrobert identity_element(std::plus<_Tp>) 91*404b540aSrobert { return _Tp(0); } 92*404b540aSrobert 93*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 94*404b540aSrobert template <class _Tp> 95*404b540aSrobert inline _Tp 96*404b540aSrobert identity_element(std::multiplies<_Tp>) 97*404b540aSrobert { return _Tp(1); } 98*404b540aSrobert /** @} */ 99*404b540aSrobert 100*404b540aSrobert /** As an extension to the binders, SGI provided composition functors and 101*404b540aSrobert * wrapper functions to aid in their creation. The @c unary_compose 102*404b540aSrobert * functor is constructed from two functions/functors, @c f and @c g. 103*404b540aSrobert * Calling @c operator() with a single argument @c x returns @c f(g(x)). 104*404b540aSrobert * The function @c compose1 takes the two functions and constructs a 105*404b540aSrobert * @c unary_compose variable for you. 106*404b540aSrobert * 107*404b540aSrobert * @c binary_compose is constructed from three functors, @c f, @c g1, 108*404b540aSrobert * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function 109*404b540aSrobert * @compose2 takes f, g1, and g2, and constructs the @c binary_compose 110*404b540aSrobert * instance for you. For example, if @c f returns an int, then 111*404b540aSrobert * \code 112*404b540aSrobert * int answer = (compose2(f,g1,g2))(x); 113*404b540aSrobert * \endcode 114*404b540aSrobert * is equivalent to 115*404b540aSrobert * \code 116*404b540aSrobert * int temp1 = g1(x); 117*404b540aSrobert * int temp2 = g2(x); 118*404b540aSrobert * int answer = f(temp1,temp2); 119*404b540aSrobert * \endcode 120*404b540aSrobert * But the first form is more compact, and can be passed around as a 121*404b540aSrobert * functor to other algorithms. 122*404b540aSrobert * 123*404b540aSrobert * @addtogroup SGIextensions 124*404b540aSrobert * @{ 125*404b540aSrobert */ 126*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 127*404b540aSrobert template <class _Operation1, class _Operation2> 128*404b540aSrobert class unary_compose 129*404b540aSrobert : public unary_function<typename _Operation2::argument_type, 130*404b540aSrobert typename _Operation1::result_type> 131*404b540aSrobert { 132*404b540aSrobert protected: 133*404b540aSrobert _Operation1 _M_fn1; 134*404b540aSrobert _Operation2 _M_fn2; 135*404b540aSrobert 136*404b540aSrobert public: 137*404b540aSrobert unary_compose(const _Operation1& __x, const _Operation2& __y) 138*404b540aSrobert : _M_fn1(__x), _M_fn2(__y) {} 139*404b540aSrobert 140*404b540aSrobert typename _Operation1::result_type 141*404b540aSrobert operator()(const typename _Operation2::argument_type& __x) const 142*404b540aSrobert { return _M_fn1(_M_fn2(__x)); } 143*404b540aSrobert }; 144*404b540aSrobert 145*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 146*404b540aSrobert template <class _Operation1, class _Operation2> 147*404b540aSrobert inline unary_compose<_Operation1, _Operation2> 148*404b540aSrobert compose1(const _Operation1& __fn1, const _Operation2& __fn2) 149*404b540aSrobert { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } 150*404b540aSrobert 151*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 152*404b540aSrobert template <class _Operation1, class _Operation2, class _Operation3> 153*404b540aSrobert class binary_compose 154*404b540aSrobert : public unary_function<typename _Operation2::argument_type, 155*404b540aSrobert typename _Operation1::result_type> 156*404b540aSrobert { 157*404b540aSrobert protected: 158*404b540aSrobert _Operation1 _M_fn1; 159*404b540aSrobert _Operation2 _M_fn2; 160*404b540aSrobert _Operation3 _M_fn3; 161*404b540aSrobert 162*404b540aSrobert public: 163*404b540aSrobert binary_compose(const _Operation1& __x, const _Operation2& __y, 164*404b540aSrobert const _Operation3& __z) 165*404b540aSrobert : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } 166*404b540aSrobert 167*404b540aSrobert typename _Operation1::result_type 168*404b540aSrobert operator()(const typename _Operation2::argument_type& __x) const 169*404b540aSrobert { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } 170*404b540aSrobert }; 171*404b540aSrobert 172*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 173*404b540aSrobert template <class _Operation1, class _Operation2, class _Operation3> 174*404b540aSrobert inline binary_compose<_Operation1, _Operation2, _Operation3> 175*404b540aSrobert compose2(const _Operation1& __fn1, const _Operation2& __fn2, 176*404b540aSrobert const _Operation3& __fn3) 177*404b540aSrobert { return binary_compose<_Operation1, _Operation2, _Operation3> 178*404b540aSrobert (__fn1, __fn2, __fn3); } 179*404b540aSrobert /** @} */ 180*404b540aSrobert 181*404b540aSrobert /** As an extension, SGI provided a functor called @c identity. When a 182*404b540aSrobert * functor is required but no operations are desired, this can be used as a 183*404b540aSrobert * pass-through. Its @c operator() returns its argument unchanged. 184*404b540aSrobert * 185*404b540aSrobert * @addtogroup SGIextensions 186*404b540aSrobert */ 187*404b540aSrobert template <class _Tp> 188*404b540aSrobert struct identity : public std::_Identity<_Tp> {}; 189*404b540aSrobert 190*404b540aSrobert /** @c select1st and @c select2nd are extensions provided by SGI. Their 191*404b540aSrobert * @c operator()s 192*404b540aSrobert * take a @c std::pair as an argument, and return either the first member 193*404b540aSrobert * or the second member, respectively. They can be used (especially with 194*404b540aSrobert * the composition functors) to "strip" data from a sequence before 195*404b540aSrobert * performing the remainder of an algorithm. 196*404b540aSrobert * 197*404b540aSrobert * @addtogroup SGIextensions 198*404b540aSrobert * @{ 199*404b540aSrobert */ 200*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 201*404b540aSrobert template <class _Pair> 202*404b540aSrobert struct select1st : public std::_Select1st<_Pair> {}; 203*404b540aSrobert 204*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 205*404b540aSrobert template <class _Pair> 206*404b540aSrobert struct select2nd : public std::_Select2nd<_Pair> {}; 207*404b540aSrobert /** @} */ 208*404b540aSrobert 209*404b540aSrobert // extension documented next 210*404b540aSrobert template <class _Arg1, class _Arg2> 211*404b540aSrobert struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> 212*404b540aSrobert { 213*404b540aSrobert _Arg1 214*404b540aSrobert operator()(const _Arg1& __x, const _Arg2&) const 215*404b540aSrobert { return __x; } 216*404b540aSrobert }; 217*404b540aSrobert 218*404b540aSrobert template <class _Arg1, class _Arg2> 219*404b540aSrobert struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> 220*404b540aSrobert { 221*404b540aSrobert _Arg2 222*404b540aSrobert operator()(const _Arg1&, const _Arg2& __y) const 223*404b540aSrobert { return __y; } 224*404b540aSrobert }; 225*404b540aSrobert 226*404b540aSrobert /** The @c operator() of the @c project1st functor takes two arbitrary 227*404b540aSrobert * arguments and returns the first one, while @c project2nd returns the 228*404b540aSrobert * second one. They are extensions provided by SGI. 229*404b540aSrobert * 230*404b540aSrobert * @addtogroup SGIextensions 231*404b540aSrobert * @{ 232*404b540aSrobert */ 233*404b540aSrobert 234*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 235*404b540aSrobert template <class _Arg1, class _Arg2> 236*404b540aSrobert struct project1st : public _Project1st<_Arg1, _Arg2> {}; 237*404b540aSrobert 238*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 239*404b540aSrobert template <class _Arg1, class _Arg2> 240*404b540aSrobert struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; 241*404b540aSrobert /** @} */ 242*404b540aSrobert 243*404b540aSrobert // extension documented next 244*404b540aSrobert template <class _Result> 245*404b540aSrobert struct _Constant_void_fun 246*404b540aSrobert { 247*404b540aSrobert typedef _Result result_type; 248*404b540aSrobert result_type _M_val; 249*404b540aSrobert 250*404b540aSrobert _Constant_void_fun(const result_type& __v) : _M_val(__v) {} 251*404b540aSrobert 252*404b540aSrobert const result_type& 253*404b540aSrobert operator()() const 254*404b540aSrobert { return _M_val; } 255*404b540aSrobert }; 256*404b540aSrobert 257*404b540aSrobert template <class _Result, class _Argument> 258*404b540aSrobert struct _Constant_unary_fun 259*404b540aSrobert { 260*404b540aSrobert typedef _Argument argument_type; 261*404b540aSrobert typedef _Result result_type; 262*404b540aSrobert result_type _M_val; 263*404b540aSrobert 264*404b540aSrobert _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} 265*404b540aSrobert 266*404b540aSrobert const result_type& 267*404b540aSrobert operator()(const _Argument&) const 268*404b540aSrobert { return _M_val; } 269*404b540aSrobert }; 270*404b540aSrobert 271*404b540aSrobert template <class _Result, class _Arg1, class _Arg2> 272*404b540aSrobert struct _Constant_binary_fun 273*404b540aSrobert { 274*404b540aSrobert typedef _Arg1 first_argument_type; 275*404b540aSrobert typedef _Arg2 second_argument_type; 276*404b540aSrobert typedef _Result result_type; 277*404b540aSrobert _Result _M_val; 278*404b540aSrobert 279*404b540aSrobert _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} 280*404b540aSrobert 281*404b540aSrobert const result_type& 282*404b540aSrobert operator()(const _Arg1&, const _Arg2&) const 283*404b540aSrobert { return _M_val; } 284*404b540aSrobert }; 285*404b540aSrobert 286*404b540aSrobert /** These three functors are each constructed from a single arbitrary 287*404b540aSrobert * variable/value. Later, their @c operator()s completely ignore any 288*404b540aSrobert * arguments passed, and return the stored value. 289*404b540aSrobert * - @c constant_void_fun's @c operator() takes no arguments 290*404b540aSrobert * - @c constant_unary_fun's @c operator() takes one argument (ignored) 291*404b540aSrobert * - @c constant_binary_fun's @c operator() takes two arguments (ignored) 292*404b540aSrobert * 293*404b540aSrobert * The helper creator functions @c constant0, @c constant1, and 294*404b540aSrobert * @c constant2 each take a "result" argument and construct variables of 295*404b540aSrobert * the appropriate functor type. 296*404b540aSrobert * 297*404b540aSrobert * @addtogroup SGIextensions 298*404b540aSrobert * @{ 299*404b540aSrobert */ 300*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 301*404b540aSrobert template <class _Result> 302*404b540aSrobert struct constant_void_fun 303*404b540aSrobert : public _Constant_void_fun<_Result> 304*404b540aSrobert { 305*404b540aSrobert constant_void_fun(const _Result& __v) 306*404b540aSrobert : _Constant_void_fun<_Result>(__v) {} 307*404b540aSrobert }; 308*404b540aSrobert 309*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 310*404b540aSrobert template <class _Result, class _Argument = _Result> 311*404b540aSrobert struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> 312*404b540aSrobert { 313*404b540aSrobert constant_unary_fun(const _Result& __v) 314*404b540aSrobert : _Constant_unary_fun<_Result, _Argument>(__v) {} 315*404b540aSrobert }; 316*404b540aSrobert 317*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 318*404b540aSrobert template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1> 319*404b540aSrobert struct constant_binary_fun 320*404b540aSrobert : public _Constant_binary_fun<_Result, _Arg1, _Arg2> 321*404b540aSrobert { 322*404b540aSrobert constant_binary_fun(const _Result& __v) 323*404b540aSrobert : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} 324*404b540aSrobert }; 325*404b540aSrobert 326*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 327*404b540aSrobert template <class _Result> 328*404b540aSrobert inline constant_void_fun<_Result> 329*404b540aSrobert constant0(const _Result& __val) 330*404b540aSrobert { return constant_void_fun<_Result>(__val); } 331*404b540aSrobert 332*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 333*404b540aSrobert template <class _Result> 334*404b540aSrobert inline constant_unary_fun<_Result, _Result> 335*404b540aSrobert constant1(const _Result& __val) 336*404b540aSrobert { return constant_unary_fun<_Result, _Result>(__val); } 337*404b540aSrobert 338*404b540aSrobert /// An \link SGIextensions SGI extension \endlink. 339*404b540aSrobert template <class _Result> 340*404b540aSrobert inline constant_binary_fun<_Result,_Result,_Result> 341*404b540aSrobert constant2(const _Result& __val) 342*404b540aSrobert { return constant_binary_fun<_Result, _Result, _Result>(__val); } 343*404b540aSrobert /** @} */ 344*404b540aSrobert 345*404b540aSrobert /** The @c subtractive_rng class is documented on 346*404b540aSrobert * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>. 347*404b540aSrobert * Note that this code assumes that @c int is 32 bits. 348*404b540aSrobert * 349*404b540aSrobert * @ingroup SGIextensions 350*404b540aSrobert */ 351*404b540aSrobert class subtractive_rng 352*404b540aSrobert : public unary_function<unsigned int, unsigned int> 353*404b540aSrobert { 354*404b540aSrobert private: 355*404b540aSrobert unsigned int _M_table[55]; 356*404b540aSrobert size_t _M_index1; 357*404b540aSrobert size_t _M_index2; 358*404b540aSrobert 359*404b540aSrobert public: 360*404b540aSrobert /// Returns a number less than the argument. 361*404b540aSrobert unsigned int 362*404b540aSrobert operator()(unsigned int __limit) 363*404b540aSrobert { 364*404b540aSrobert _M_index1 = (_M_index1 + 1) % 55; 365*404b540aSrobert _M_index2 = (_M_index2 + 1) % 55; 366*404b540aSrobert _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; 367*404b540aSrobert return _M_table[_M_index1] % __limit; 368*404b540aSrobert } 369*404b540aSrobert 370*404b540aSrobert void 371*404b540aSrobert _M_initialize(unsigned int __seed) 372*404b540aSrobert { 373*404b540aSrobert unsigned int __k = 1; 374*404b540aSrobert _M_table[54] = __seed; 375*404b540aSrobert size_t __i; 376*404b540aSrobert for (__i = 0; __i < 54; __i++) 377*404b540aSrobert { 378*404b540aSrobert size_t __ii = (21 * (__i + 1) % 55) - 1; 379*404b540aSrobert _M_table[__ii] = __k; 380*404b540aSrobert __k = __seed - __k; 381*404b540aSrobert __seed = _M_table[__ii]; 382*404b540aSrobert } 383*404b540aSrobert for (int __loop = 0; __loop < 4; __loop++) 384*404b540aSrobert { 385*404b540aSrobert for (__i = 0; __i < 55; __i++) 386*404b540aSrobert _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; 387*404b540aSrobert } 388*404b540aSrobert _M_index1 = 0; 389*404b540aSrobert _M_index2 = 31; 390*404b540aSrobert } 391*404b540aSrobert 392*404b540aSrobert /// Ctor allowing you to initialize the seed. 393*404b540aSrobert subtractive_rng(unsigned int __seed) 394*404b540aSrobert { _M_initialize(__seed); } 395*404b540aSrobert 396*404b540aSrobert /// Default ctor; initializes its state with some number you don't see. 397*404b540aSrobert subtractive_rng() 398*404b540aSrobert { _M_initialize(161803398u); } 399*404b540aSrobert }; 400*404b540aSrobert 401*404b540aSrobert // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, 402*404b540aSrobert // provided for backward compatibility, they are no longer part of 403*404b540aSrobert // the C++ standard. 404*404b540aSrobert 405*404b540aSrobert template <class _Ret, class _Tp, class _Arg> 406*404b540aSrobert inline mem_fun1_t<_Ret, _Tp, _Arg> 407*404b540aSrobert mem_fun1(_Ret (_Tp::*__f)(_Arg)) 408*404b540aSrobert { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } 409*404b540aSrobert 410*404b540aSrobert template <class _Ret, class _Tp, class _Arg> 411*404b540aSrobert inline const_mem_fun1_t<_Ret, _Tp, _Arg> 412*404b540aSrobert mem_fun1(_Ret (_Tp::*__f)(_Arg) const) 413*404b540aSrobert { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } 414*404b540aSrobert 415*404b540aSrobert template <class _Ret, class _Tp, class _Arg> 416*404b540aSrobert inline mem_fun1_ref_t<_Ret, _Tp, _Arg> 417*404b540aSrobert mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) 418*404b540aSrobert { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } 419*404b540aSrobert 420*404b540aSrobert template <class _Ret, class _Tp, class _Arg> 421*404b540aSrobert inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> 422*404b540aSrobert mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) 423*404b540aSrobert { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } 424*404b540aSrobert 425*404b540aSrobert_GLIBCXX_END_NAMESPACE 426*404b540aSrobert 427*404b540aSrobert#endif 428*404b540aSrobert 429