100db7afdSDavid E. O'Brien// Functional extensions -*- C++ -*- 200db7afdSDavid E. O'Brien 3*f8a1b7d9SAlexander Kabaev// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 400db7afdSDavid E. O'Brien// 500db7afdSDavid E. O'Brien// This file is part of the GNU ISO C++ Library. This library is free 600db7afdSDavid E. O'Brien// software; you can redistribute it and/or modify it under the 700db7afdSDavid E. O'Brien// terms of the GNU General Public License as published by the 800db7afdSDavid E. O'Brien// Free Software Foundation; either version 2, or (at your option) 900db7afdSDavid E. O'Brien// any later version. 1000db7afdSDavid E. O'Brien 1100db7afdSDavid E. O'Brien// This library is distributed in the hope that it will be useful, 1200db7afdSDavid E. O'Brien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1300db7afdSDavid E. O'Brien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1400db7afdSDavid E. O'Brien// GNU General Public License for more details. 1500db7afdSDavid E. O'Brien 1600db7afdSDavid E. O'Brien// You should have received a copy of the GNU General Public License along 1700db7afdSDavid E. O'Brien// with this library; see the file COPYING. If not, write to the Free 18*f8a1b7d9SAlexander Kabaev// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 1900db7afdSDavid E. O'Brien// USA. 2000db7afdSDavid E. O'Brien 2100db7afdSDavid E. O'Brien// As a special exception, you may use this file as part of a free software 2200db7afdSDavid E. O'Brien// library without restriction. Specifically, if other files instantiate 2300db7afdSDavid E. O'Brien// templates or use macros or inline functions from this file, or you compile 2400db7afdSDavid E. O'Brien// this file and link it with other files to produce an executable, this 2500db7afdSDavid E. O'Brien// file does not by itself cause the resulting executable to be covered by 2600db7afdSDavid E. O'Brien// the GNU General Public License. This exception does not however 2700db7afdSDavid E. O'Brien// invalidate any other reasons why the executable file might be covered by 2800db7afdSDavid E. O'Brien// the GNU General Public License. 2900db7afdSDavid E. O'Brien 3000db7afdSDavid E. O'Brien/* 3100db7afdSDavid E. O'Brien * 3200db7afdSDavid E. O'Brien * Copyright (c) 1994 3300db7afdSDavid E. O'Brien * Hewlett-Packard Company 3400db7afdSDavid E. O'Brien * 3500db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software 3600db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee, 3700db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and 3800db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear 3900db7afdSDavid E. O'Brien * in supporting documentation. Hewlett-Packard Company makes no 4000db7afdSDavid E. O'Brien * representations about the suitability of this software for any 4100db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty. 4200db7afdSDavid E. O'Brien * 4300db7afdSDavid E. O'Brien * 4400db7afdSDavid E. O'Brien * Copyright (c) 1996 4500db7afdSDavid E. O'Brien * Silicon Graphics Computer Systems, Inc. 4600db7afdSDavid E. O'Brien * 4700db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software 4800db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee, 4900db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and 5000db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear 5100db7afdSDavid E. O'Brien * in supporting documentation. Silicon Graphics makes no 5200db7afdSDavid E. O'Brien * representations about the suitability of this software for any 5300db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty. 5400db7afdSDavid E. O'Brien */ 5500db7afdSDavid E. O'Brien 5600db7afdSDavid E. O'Brien/** @file ext/functional 5700db7afdSDavid E. O'Brien * This file is a GNU extension to the Standard C++ Library (possibly 58*f8a1b7d9SAlexander Kabaev * containing extensions from the HP/SGI STL subset). 5900db7afdSDavid E. O'Brien */ 6000db7afdSDavid E. O'Brien 6100db7afdSDavid E. O'Brien#ifndef _EXT_FUNCTIONAL 62ffeaf689SAlexander Kabaev#define _EXT_FUNCTIONAL 1 6300db7afdSDavid E. O'Brien 6400db7afdSDavid E. O'Brien#pragma GCC system_header 65ffeaf689SAlexander Kabaev 6600db7afdSDavid E. O'Brien#include <functional> 6700db7afdSDavid E. O'Brien 68*f8a1b7d9SAlexander Kabaev_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 69*f8a1b7d9SAlexander Kabaev 70*f8a1b7d9SAlexander Kabaev using std::size_t; 7100db7afdSDavid E. O'Brien using std::unary_function; 7200db7afdSDavid E. O'Brien using std::binary_function; 7300db7afdSDavid E. O'Brien using std::mem_fun1_t; 7400db7afdSDavid E. O'Brien using std::const_mem_fun1_t; 7500db7afdSDavid E. O'Brien using std::mem_fun1_ref_t; 7600db7afdSDavid E. O'Brien using std::const_mem_fun1_ref_t; 7700db7afdSDavid E. O'Brien 78*f8a1b7d9SAlexander Kabaev /** The @c identity_element functions are not part of the C++ 79*f8a1b7d9SAlexander Kabaev * standard; SGI provided them as an extension. Its argument is an 80*f8a1b7d9SAlexander Kabaev * operation, and its return value is the identity element for that 81*f8a1b7d9SAlexander Kabaev * operation. It is overloaded for addition and multiplication, 82*f8a1b7d9SAlexander Kabaev * and you can overload it for your own nefarious operations. 8300db7afdSDavid E. O'Brien * 8400db7afdSDavid E. O'Brien * @addtogroup SGIextensions 8500db7afdSDavid E. O'Brien * @{ 8600db7afdSDavid E. O'Brien */ 8700db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 88*f8a1b7d9SAlexander Kabaev template <class _Tp> 89*f8a1b7d9SAlexander Kabaev inline _Tp 90*f8a1b7d9SAlexander Kabaev identity_element(std::plus<_Tp>) 91*f8a1b7d9SAlexander Kabaev { return _Tp(0); } 92*f8a1b7d9SAlexander Kabaev 9300db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 94*f8a1b7d9SAlexander Kabaev template <class _Tp> 95*f8a1b7d9SAlexander Kabaev inline _Tp 96*f8a1b7d9SAlexander Kabaev identity_element(std::multiplies<_Tp>) 97*f8a1b7d9SAlexander Kabaev { return _Tp(1); } 9800db7afdSDavid E. O'Brien /** @} */ 9900db7afdSDavid E. O'Brien 10000db7afdSDavid E. O'Brien /** As an extension to the binders, SGI provided composition functors and 10100db7afdSDavid E. O'Brien * wrapper functions to aid in their creation. The @c unary_compose 10200db7afdSDavid E. O'Brien * functor is constructed from two functions/functors, @c f and @c g. 10300db7afdSDavid E. O'Brien * Calling @c operator() with a single argument @c x returns @c f(g(x)). 10400db7afdSDavid E. O'Brien * The function @c compose1 takes the two functions and constructs a 10500db7afdSDavid E. O'Brien * @c unary_compose variable for you. 10600db7afdSDavid E. O'Brien * 10700db7afdSDavid E. O'Brien * @c binary_compose is constructed from three functors, @c f, @c g1, 10800db7afdSDavid E. O'Brien * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function 10900db7afdSDavid E. O'Brien * @compose2 takes f, g1, and g2, and constructs the @c binary_compose 11000db7afdSDavid E. O'Brien * instance for you. For example, if @c f returns an int, then 11100db7afdSDavid E. O'Brien * \code 11200db7afdSDavid E. O'Brien * int answer = (compose2(f,g1,g2))(x); 11300db7afdSDavid E. O'Brien * \endcode 11400db7afdSDavid E. O'Brien * is equivalent to 11500db7afdSDavid E. O'Brien * \code 11600db7afdSDavid E. O'Brien * int temp1 = g1(x); 11700db7afdSDavid E. O'Brien * int temp2 = g2(x); 11800db7afdSDavid E. O'Brien * int answer = f(temp1,temp2); 11900db7afdSDavid E. O'Brien * \endcode 12000db7afdSDavid E. O'Brien * But the first form is more compact, and can be passed around as a 12100db7afdSDavid E. O'Brien * functor to other algorithms. 12200db7afdSDavid E. O'Brien * 12300db7afdSDavid E. O'Brien * @addtogroup SGIextensions 12400db7afdSDavid E. O'Brien * @{ 12500db7afdSDavid E. O'Brien */ 12600db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 12700db7afdSDavid E. O'Brien template <class _Operation1, class _Operation2> 12800db7afdSDavid E. O'Brien class unary_compose 12900db7afdSDavid E. O'Brien : public unary_function<typename _Operation2::argument_type, 13000db7afdSDavid E. O'Brien typename _Operation1::result_type> 13100db7afdSDavid E. O'Brien { 13200db7afdSDavid E. O'Brien protected: 13300db7afdSDavid E. O'Brien _Operation1 _M_fn1; 13400db7afdSDavid E. O'Brien _Operation2 _M_fn2; 135*f8a1b7d9SAlexander Kabaev 13600db7afdSDavid E. O'Brien public: 13700db7afdSDavid E. O'Brien unary_compose(const _Operation1& __x, const _Operation2& __y) 13800db7afdSDavid E. O'Brien : _M_fn1(__x), _M_fn2(__y) {} 139*f8a1b7d9SAlexander Kabaev 14000db7afdSDavid E. O'Brien typename _Operation1::result_type 141*f8a1b7d9SAlexander Kabaev operator()(const typename _Operation2::argument_type& __x) const 142*f8a1b7d9SAlexander Kabaev { return _M_fn1(_M_fn2(__x)); } 14300db7afdSDavid E. O'Brien }; 14400db7afdSDavid E. O'Brien 14500db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 14600db7afdSDavid E. O'Brien template <class _Operation1, class _Operation2> 14700db7afdSDavid E. O'Brien inline unary_compose<_Operation1, _Operation2> 14800db7afdSDavid E. O'Brien compose1(const _Operation1& __fn1, const _Operation2& __fn2) 149*f8a1b7d9SAlexander Kabaev { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } 15000db7afdSDavid E. O'Brien 15100db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 15200db7afdSDavid E. O'Brien template <class _Operation1, class _Operation2, class _Operation3> 15300db7afdSDavid E. O'Brien class binary_compose 15400db7afdSDavid E. O'Brien : public unary_function<typename _Operation2::argument_type, 155*f8a1b7d9SAlexander Kabaev typename _Operation1::result_type> 156*f8a1b7d9SAlexander Kabaev { 15700db7afdSDavid E. O'Brien protected: 15800db7afdSDavid E. O'Brien _Operation1 _M_fn1; 15900db7afdSDavid E. O'Brien _Operation2 _M_fn2; 16000db7afdSDavid E. O'Brien _Operation3 _M_fn3; 161*f8a1b7d9SAlexander Kabaev 16200db7afdSDavid E. O'Brien public: 16300db7afdSDavid E. O'Brien binary_compose(const _Operation1& __x, const _Operation2& __y, 16400db7afdSDavid E. O'Brien const _Operation3& __z) 16500db7afdSDavid E. O'Brien : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } 166*f8a1b7d9SAlexander Kabaev 16700db7afdSDavid E. O'Brien typename _Operation1::result_type 168*f8a1b7d9SAlexander Kabaev operator()(const typename _Operation2::argument_type& __x) const 169*f8a1b7d9SAlexander Kabaev { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } 17000db7afdSDavid E. O'Brien }; 17100db7afdSDavid E. O'Brien 17200db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 17300db7afdSDavid E. O'Brien template <class _Operation1, class _Operation2, class _Operation3> 17400db7afdSDavid E. O'Brien inline binary_compose<_Operation1, _Operation2, _Operation3> 17500db7afdSDavid E. O'Brien compose2(const _Operation1& __fn1, const _Operation2& __fn2, 17600db7afdSDavid E. O'Brien const _Operation3& __fn3) 177*f8a1b7d9SAlexander Kabaev { return binary_compose<_Operation1, _Operation2, _Operation3> 178*f8a1b7d9SAlexander Kabaev (__fn1, __fn2, __fn3); } 17900db7afdSDavid E. O'Brien /** @} */ 18000db7afdSDavid E. O'Brien 18100db7afdSDavid E. O'Brien /** As an extension, SGI provided a functor called @c identity. When a 18200db7afdSDavid E. O'Brien * functor is required but no operations are desired, this can be used as a 18300db7afdSDavid E. O'Brien * pass-through. Its @c operator() returns its argument unchanged. 18400db7afdSDavid E. O'Brien * 18500db7afdSDavid E. O'Brien * @addtogroup SGIextensions 18600db7afdSDavid E. O'Brien */ 187*f8a1b7d9SAlexander Kabaev template <class _Tp> 188*f8a1b7d9SAlexander Kabaev struct identity : public std::_Identity<_Tp> {}; 18900db7afdSDavid E. O'Brien 19000db7afdSDavid E. O'Brien /** @c select1st and @c select2nd are extensions provided by SGI. Their 19100db7afdSDavid E. O'Brien * @c operator()s 19200db7afdSDavid E. O'Brien * take a @c std::pair as an argument, and return either the first member 19300db7afdSDavid E. O'Brien * or the second member, respectively. They can be used (especially with 19400db7afdSDavid E. O'Brien * the composition functors) to "strip" data from a sequence before 19500db7afdSDavid E. O'Brien * performing the remainder of an algorithm. 19600db7afdSDavid E. O'Brien * 19700db7afdSDavid E. O'Brien * @addtogroup SGIextensions 19800db7afdSDavid E. O'Brien * @{ 19900db7afdSDavid E. O'Brien */ 20000db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 201*f8a1b7d9SAlexander Kabaev template <class _Pair> 202*f8a1b7d9SAlexander Kabaev struct select1st : public std::_Select1st<_Pair> {}; 203*f8a1b7d9SAlexander Kabaev 20400db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 205*f8a1b7d9SAlexander Kabaev template <class _Pair> 206*f8a1b7d9SAlexander Kabaev struct select2nd : public std::_Select2nd<_Pair> {}; 20700db7afdSDavid E. O'Brien /** @} */ 20800db7afdSDavid E. O'Brien 20900db7afdSDavid E. O'Brien // extension documented next 21000db7afdSDavid E. O'Brien template <class _Arg1, class _Arg2> 211*f8a1b7d9SAlexander Kabaev struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> 212*f8a1b7d9SAlexander Kabaev { 213*f8a1b7d9SAlexander Kabaev _Arg1 214*f8a1b7d9SAlexander Kabaev operator()(const _Arg1& __x, const _Arg2&) const 215*f8a1b7d9SAlexander Kabaev { return __x; } 21600db7afdSDavid E. O'Brien }; 21700db7afdSDavid E. O'Brien 21800db7afdSDavid E. O'Brien template <class _Arg1, class _Arg2> 219*f8a1b7d9SAlexander Kabaev struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> 220*f8a1b7d9SAlexander Kabaev { 221*f8a1b7d9SAlexander Kabaev _Arg2 222*f8a1b7d9SAlexander Kabaev operator()(const _Arg1&, const _Arg2& __y) const 223*f8a1b7d9SAlexander Kabaev { return __y; } 22400db7afdSDavid E. O'Brien }; 22500db7afdSDavid E. O'Brien 22600db7afdSDavid E. O'Brien /** The @c operator() of the @c project1st functor takes two arbitrary 22700db7afdSDavid E. O'Brien * arguments and returns the first one, while @c project2nd returns the 22800db7afdSDavid E. O'Brien * second one. They are extensions provided by SGI. 22900db7afdSDavid E. O'Brien * 23000db7afdSDavid E. O'Brien * @addtogroup SGIextensions 23100db7afdSDavid E. O'Brien * @{ 23200db7afdSDavid E. O'Brien */ 23300db7afdSDavid E. O'Brien 23400db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 23500db7afdSDavid E. O'Brien template <class _Arg1, class _Arg2> 23600db7afdSDavid E. O'Brien struct project1st : public _Project1st<_Arg1, _Arg2> {}; 23700db7afdSDavid E. O'Brien 23800db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 23900db7afdSDavid E. O'Brien template <class _Arg1, class _Arg2> 24000db7afdSDavid E. O'Brien struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; 24100db7afdSDavid E. O'Brien /** @} */ 24200db7afdSDavid E. O'Brien 24300db7afdSDavid E. O'Brien // extension documented next 24400db7afdSDavid E. O'Brien template <class _Result> 245*f8a1b7d9SAlexander Kabaev struct _Constant_void_fun 246*f8a1b7d9SAlexander Kabaev { 24700db7afdSDavid E. O'Brien typedef _Result result_type; 24800db7afdSDavid E. O'Brien result_type _M_val; 24900db7afdSDavid E. O'Brien 25000db7afdSDavid E. O'Brien _Constant_void_fun(const result_type& __v) : _M_val(__v) {} 251*f8a1b7d9SAlexander Kabaev 252*f8a1b7d9SAlexander Kabaev const result_type& 253*f8a1b7d9SAlexander Kabaev operator()() const 254*f8a1b7d9SAlexander Kabaev { return _M_val; } 25500db7afdSDavid E. O'Brien }; 25600db7afdSDavid E. O'Brien 25700db7afdSDavid E. O'Brien template <class _Result, class _Argument> 258*f8a1b7d9SAlexander Kabaev struct _Constant_unary_fun 259*f8a1b7d9SAlexander Kabaev { 26000db7afdSDavid E. O'Brien typedef _Argument argument_type; 26100db7afdSDavid E. O'Brien typedef _Result result_type; 26200db7afdSDavid E. O'Brien result_type _M_val; 26300db7afdSDavid E. O'Brien 26400db7afdSDavid E. O'Brien _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} 265*f8a1b7d9SAlexander Kabaev 266*f8a1b7d9SAlexander Kabaev const result_type& 267*f8a1b7d9SAlexander Kabaev operator()(const _Argument&) const 268*f8a1b7d9SAlexander Kabaev { return _M_val; } 26900db7afdSDavid E. O'Brien }; 27000db7afdSDavid E. O'Brien 27100db7afdSDavid E. O'Brien template <class _Result, class _Arg1, class _Arg2> 272*f8a1b7d9SAlexander Kabaev struct _Constant_binary_fun 273*f8a1b7d9SAlexander Kabaev { 27400db7afdSDavid E. O'Brien typedef _Arg1 first_argument_type; 27500db7afdSDavid E. O'Brien typedef _Arg2 second_argument_type; 27600db7afdSDavid E. O'Brien typedef _Result result_type; 27700db7afdSDavid E. O'Brien _Result _M_val; 27800db7afdSDavid E. O'Brien 27900db7afdSDavid E. O'Brien _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} 280*f8a1b7d9SAlexander Kabaev 281*f8a1b7d9SAlexander Kabaev const result_type& 282*f8a1b7d9SAlexander Kabaev operator()(const _Arg1&, const _Arg2&) const 283*f8a1b7d9SAlexander Kabaev { return _M_val; } 28400db7afdSDavid E. O'Brien }; 28500db7afdSDavid E. O'Brien 28600db7afdSDavid E. O'Brien /** These three functors are each constructed from a single arbitrary 28700db7afdSDavid E. O'Brien * variable/value. Later, their @c operator()s completely ignore any 28800db7afdSDavid E. O'Brien * arguments passed, and return the stored value. 28900db7afdSDavid E. O'Brien * - @c constant_void_fun's @c operator() takes no arguments 29000db7afdSDavid E. O'Brien * - @c constant_unary_fun's @c operator() takes one argument (ignored) 29100db7afdSDavid E. O'Brien * - @c constant_binary_fun's @c operator() takes two arguments (ignored) 29200db7afdSDavid E. O'Brien * 29300db7afdSDavid E. O'Brien * The helper creator functions @c constant0, @c constant1, and 29400db7afdSDavid E. O'Brien * @c constant2 each take a "result" argument and construct variables of 29500db7afdSDavid E. O'Brien * the appropriate functor type. 29600db7afdSDavid E. O'Brien * 29700db7afdSDavid E. O'Brien * @addtogroup SGIextensions 29800db7afdSDavid E. O'Brien * @{ 29900db7afdSDavid E. O'Brien */ 30000db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 30100db7afdSDavid E. O'Brien template <class _Result> 302*f8a1b7d9SAlexander Kabaev struct constant_void_fun 303*f8a1b7d9SAlexander Kabaev : public _Constant_void_fun<_Result> 304*f8a1b7d9SAlexander Kabaev { 305*f8a1b7d9SAlexander Kabaev constant_void_fun(const _Result& __v) 306*f8a1b7d9SAlexander Kabaev : _Constant_void_fun<_Result>(__v) {} 30700db7afdSDavid E. O'Brien }; 30800db7afdSDavid E. O'Brien 30900db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 310*f8a1b7d9SAlexander Kabaev template <class _Result, class _Argument = _Result> 31100db7afdSDavid E. O'Brien struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> 31200db7afdSDavid E. O'Brien { 31300db7afdSDavid E. O'Brien constant_unary_fun(const _Result& __v) 31400db7afdSDavid E. O'Brien : _Constant_unary_fun<_Result, _Argument>(__v) {} 31500db7afdSDavid E. O'Brien }; 31600db7afdSDavid E. O'Brien 31700db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 318*f8a1b7d9SAlexander Kabaev template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1> 31900db7afdSDavid E. O'Brien struct constant_binary_fun 32000db7afdSDavid E. O'Brien : public _Constant_binary_fun<_Result, _Arg1, _Arg2> 32100db7afdSDavid E. O'Brien { 32200db7afdSDavid E. O'Brien constant_binary_fun(const _Result& __v) 32300db7afdSDavid E. O'Brien : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} 32400db7afdSDavid E. O'Brien }; 32500db7afdSDavid E. O'Brien 32600db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 32700db7afdSDavid E. O'Brien template <class _Result> 328*f8a1b7d9SAlexander Kabaev inline constant_void_fun<_Result> 329*f8a1b7d9SAlexander Kabaev constant0(const _Result& __val) 330*f8a1b7d9SAlexander Kabaev { return constant_void_fun<_Result>(__val); } 33100db7afdSDavid E. O'Brien 33200db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 33300db7afdSDavid E. O'Brien template <class _Result> 334*f8a1b7d9SAlexander Kabaev inline constant_unary_fun<_Result, _Result> 335*f8a1b7d9SAlexander Kabaev constant1(const _Result& __val) 336*f8a1b7d9SAlexander Kabaev { return constant_unary_fun<_Result, _Result>(__val); } 33700db7afdSDavid E. O'Brien 33800db7afdSDavid E. O'Brien /// An \link SGIextensions SGI extension \endlink. 33900db7afdSDavid E. O'Brien template <class _Result> 34000db7afdSDavid E. O'Brien inline constant_binary_fun<_Result,_Result,_Result> 34100db7afdSDavid E. O'Brien constant2(const _Result& __val) 342*f8a1b7d9SAlexander Kabaev { return constant_binary_fun<_Result, _Result, _Result>(__val); } 34300db7afdSDavid E. O'Brien /** @} */ 34400db7afdSDavid E. O'Brien 34500db7afdSDavid E. O'Brien /** The @c subtractive_rng class is documented on 34600db7afdSDavid E. O'Brien * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>. 34700db7afdSDavid E. O'Brien * Note that this code assumes that @c int is 32 bits. 34800db7afdSDavid E. O'Brien * 34900db7afdSDavid E. O'Brien * @ingroup SGIextensions 35000db7afdSDavid E. O'Brien */ 351*f8a1b7d9SAlexander Kabaev class subtractive_rng 352*f8a1b7d9SAlexander Kabaev : public unary_function<unsigned int, unsigned int> 353*f8a1b7d9SAlexander Kabaev { 35400db7afdSDavid E. O'Brien private: 35500db7afdSDavid E. O'Brien unsigned int _M_table[55]; 35600db7afdSDavid E. O'Brien size_t _M_index1; 35700db7afdSDavid E. O'Brien size_t _M_index2; 358*f8a1b7d9SAlexander Kabaev 35900db7afdSDavid E. O'Brien public: 36000db7afdSDavid E. O'Brien /// Returns a number less than the argument. 361*f8a1b7d9SAlexander Kabaev unsigned int 362*f8a1b7d9SAlexander Kabaev operator()(unsigned int __limit) 363*f8a1b7d9SAlexander Kabaev { 36400db7afdSDavid E. O'Brien _M_index1 = (_M_index1 + 1) % 55; 36500db7afdSDavid E. O'Brien _M_index2 = (_M_index2 + 1) % 55; 36600db7afdSDavid E. O'Brien _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; 36700db7afdSDavid E. O'Brien return _M_table[_M_index1] % __limit; 36800db7afdSDavid E. O'Brien } 36900db7afdSDavid E. O'Brien 370*f8a1b7d9SAlexander Kabaev void 371*f8a1b7d9SAlexander Kabaev _M_initialize(unsigned int __seed) 37200db7afdSDavid E. O'Brien { 37300db7afdSDavid E. O'Brien unsigned int __k = 1; 37400db7afdSDavid E. O'Brien _M_table[54] = __seed; 37500db7afdSDavid E. O'Brien size_t __i; 376*f8a1b7d9SAlexander Kabaev for (__i = 0; __i < 54; __i++) 377*f8a1b7d9SAlexander Kabaev { 37800db7afdSDavid E. O'Brien size_t __ii = (21 * (__i + 1) % 55) - 1; 37900db7afdSDavid E. O'Brien _M_table[__ii] = __k; 38000db7afdSDavid E. O'Brien __k = __seed - __k; 38100db7afdSDavid E. O'Brien __seed = _M_table[__ii]; 38200db7afdSDavid E. O'Brien } 383*f8a1b7d9SAlexander Kabaev for (int __loop = 0; __loop < 4; __loop++) 384*f8a1b7d9SAlexander Kabaev { 38500db7afdSDavid E. O'Brien for (__i = 0; __i < 55; __i++) 38600db7afdSDavid E. O'Brien _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; 38700db7afdSDavid E. O'Brien } 38800db7afdSDavid E. O'Brien _M_index1 = 0; 38900db7afdSDavid E. O'Brien _M_index2 = 31; 39000db7afdSDavid E. O'Brien } 39100db7afdSDavid E. O'Brien 39200db7afdSDavid E. O'Brien /// Ctor allowing you to initialize the seed. 393*f8a1b7d9SAlexander Kabaev subtractive_rng(unsigned int __seed) 394*f8a1b7d9SAlexander Kabaev { _M_initialize(__seed); } 395*f8a1b7d9SAlexander Kabaev 39600db7afdSDavid E. O'Brien /// Default ctor; initializes its state with some number you don't see. 397*f8a1b7d9SAlexander Kabaev subtractive_rng() 398*f8a1b7d9SAlexander Kabaev { _M_initialize(161803398u); } 39900db7afdSDavid E. O'Brien }; 40000db7afdSDavid E. O'Brien 40100db7afdSDavid E. O'Brien // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, 40200db7afdSDavid E. O'Brien // provided for backward compatibility, they are no longer part of 40300db7afdSDavid E. O'Brien // the C++ standard. 40400db7afdSDavid E. O'Brien 40500db7afdSDavid E. O'Brien template <class _Ret, class _Tp, class _Arg> 406*f8a1b7d9SAlexander Kabaev inline mem_fun1_t<_Ret, _Tp, _Arg> 407*f8a1b7d9SAlexander Kabaev mem_fun1(_Ret (_Tp::*__f)(_Arg)) 40800db7afdSDavid E. O'Brien { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } 40900db7afdSDavid E. O'Brien 41000db7afdSDavid E. O'Brien template <class _Ret, class _Tp, class _Arg> 411*f8a1b7d9SAlexander Kabaev inline const_mem_fun1_t<_Ret, _Tp, _Arg> 412*f8a1b7d9SAlexander Kabaev mem_fun1(_Ret (_Tp::*__f)(_Arg) const) 41300db7afdSDavid E. O'Brien { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } 41400db7afdSDavid E. O'Brien 41500db7afdSDavid E. O'Brien template <class _Ret, class _Tp, class _Arg> 416*f8a1b7d9SAlexander Kabaev inline mem_fun1_ref_t<_Ret, _Tp, _Arg> 417*f8a1b7d9SAlexander Kabaev mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) 41800db7afdSDavid E. O'Brien { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } 41900db7afdSDavid E. O'Brien 42000db7afdSDavid E. O'Brien template <class _Ret, class _Tp, class _Arg> 42100db7afdSDavid E. O'Brien inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> 42200db7afdSDavid E. O'Brien mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) 42300db7afdSDavid E. O'Brien { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } 424*f8a1b7d9SAlexander Kabaev 425*f8a1b7d9SAlexander Kabaev_GLIBCXX_END_NAMESPACE 42600db7afdSDavid E. O'Brien 427ffeaf689SAlexander Kabaev#endif 42800db7afdSDavid E. O'Brien 429