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