home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 January / PCWorld_2000-01_cd.bin / Software / Servis / Devc / _SETUP.4 / Group3 / stl_function.h < prev    next >
C/C++ Source or Header  |  1998-03-08  |  19KB  |  629 lines

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  */
  26.  
  27. /* NOTE: This is an internal header file, included by other STL headers.
  28.  *   You should not attempt to use it directly.
  29.  */
  30.  
  31. #ifndef __SGI_STL_INTERNAL_FUNCTION_H
  32. #define __SGI_STL_INTERNAL_FUNCTION_H
  33.  
  34. __STL_BEGIN_NAMESPACE
  35.  
  36. template <class Arg, class Result>
  37. struct unary_function {
  38.     typedef Arg argument_type;
  39.     typedef Result result_type;
  40. };
  41.  
  42. template <class Arg1, class Arg2, class Result>
  43. struct binary_function {
  44.     typedef Arg1 first_argument_type;
  45.     typedef Arg2 second_argument_type;
  46.     typedef Result result_type;
  47. };      
  48.  
  49. template <class T>
  50. struct plus : public binary_function<T, T, T> {
  51.     T operator()(const T& x, const T& y) const { return x + y; }
  52. };
  53.  
  54. template <class T>
  55. struct minus : public binary_function<T, T, T> {
  56.     T operator()(const T& x, const T& y) const { return x - y; }
  57. };
  58.  
  59. template <class T>
  60. struct multiplies : public binary_function<T, T, T> {
  61.     T operator()(const T& x, const T& y) const { return x * y; }
  62. };
  63.  
  64. template <class T>
  65. struct divides : public binary_function<T, T, T> {
  66.     T operator()(const T& x, const T& y) const { return x / y; }
  67. };
  68.  
  69. template <class T> inline T identity_element(plus<T>) { return T(0); }
  70.  
  71. template <class T> inline T identity_element(multiplies<T>) { return T(1); }
  72.  
  73. template <class T>
  74. struct modulus : public binary_function<T, T, T> {
  75.     T operator()(const T& x, const T& y) const { return x % y; }
  76. };
  77.  
  78. template <class T>
  79. struct negate : public unary_function<T, T> {
  80.     T operator()(const T& x) const { return -x; }
  81. };
  82.  
  83. template <class T>
  84. struct equal_to : public binary_function<T, T, bool> {
  85.     bool operator()(const T& x, const T& y) const { return x == y; }
  86. };
  87.  
  88. template <class T>
  89. struct not_equal_to : public binary_function<T, T, bool> {
  90.     bool operator()(const T& x, const T& y) const { return x != y; }
  91. };
  92.  
  93. template <class T>
  94. struct greater : public binary_function<T, T, bool> {
  95.     bool operator()(const T& x, const T& y) const { return x > y; }
  96. };
  97.  
  98. template <class T>
  99. struct less : public binary_function<T, T, bool> {
  100.     bool operator()(const T& x, const T& y) const { return x < y; }
  101. };
  102.  
  103. template <class T>
  104. struct greater_equal : public binary_function<T, T, bool> {
  105.     bool operator()(const T& x, const T& y) const { return x >= y; }
  106. };
  107.  
  108. template <class T>
  109. struct less_equal : public binary_function<T, T, bool> {
  110.     bool operator()(const T& x, const T& y) const { return x <= y; }
  111. };
  112.  
  113. template <class T>
  114. struct logical_and : public binary_function<T, T, bool> {
  115.     bool operator()(const T& x, const T& y) const { return x && y; }
  116. };
  117.  
  118. template <class T>
  119. struct logical_or : public binary_function<T, T, bool> {
  120.     bool operator()(const T& x, const T& y) const { return x || y; }
  121. };
  122.  
  123. template <class T>
  124. struct logical_not : public unary_function<T, bool> {
  125.     bool operator()(const T& x) const { return !x; }
  126. };
  127.  
  128. template <class Predicate>
  129. class unary_negate
  130.   : public unary_function<typename Predicate::argument_type, bool> {
  131. protected:
  132.   Predicate pred;
  133. public:
  134.   explicit unary_negate(const Predicate& x) : pred(x) {}
  135.   bool operator()(const typename Predicate::argument_type& x) const {
  136.     return !pred(x);
  137.   }
  138. };
  139.  
  140. template <class Predicate>
  141. inline unary_negate<Predicate> not1(const Predicate& pred) {
  142.   return unary_negate<Predicate>(pred);
  143. }
  144.  
  145. template <class Predicate> 
  146. class binary_negate 
  147.   : public binary_function<typename Predicate::first_argument_type,
  148.                            typename Predicate::second_argument_type,
  149.                            bool> {
  150. protected:
  151.   Predicate pred;
  152. public:
  153.   explicit binary_negate(const Predicate& x) : pred(x) {}
  154.   bool operator()(const typename Predicate::first_argument_type& x, 
  155.                   const typename Predicate::second_argument_type& y) const {
  156.     return !pred(x, y); 
  157.   }
  158. };
  159.  
  160. template <class Predicate>
  161. inline binary_negate<Predicate> not2(const Predicate& pred) {
  162.   return binary_negate<Predicate>(pred);
  163. }
  164.  
  165. template <class Operation> 
  166. class binder1st
  167.   : public unary_function<typename Operation::second_argument_type,
  168.                           typename Operation::result_type> {
  169. protected:
  170.   Operation op;
  171.   typename Operation::first_argument_type value;
  172. public:
  173.   binder1st(const Operation& x,
  174.             const typename Operation::first_argument_type& y)
  175.       : op(x), value(y) {}
  176.   typename Operation::result_type
  177.   operator()(const typename Operation::second_argument_type& x) const {
  178.     return op(value, x); 
  179.   }
  180. };
  181.  
  182. template <class Operation, class T>
  183. inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
  184.   typedef typename Operation::first_argument_type arg1_type;
  185.   return binder1st<Operation>(op, arg1_type(x));
  186. }
  187.  
  188. template <class Operation> 
  189. class binder2nd
  190.   : public unary_function<typename Operation::first_argument_type,
  191.                           typename Operation::result_type> {
  192. protected:
  193.   Operation op;
  194.   typename Operation::second_argument_type value;
  195. public:
  196.   binder2nd(const Operation& x,
  197.             const typename Operation::second_argument_type& y) 
  198.       : op(x), value(y) {}
  199.   typename Operation::result_type
  200.   operator()(const typename Operation::first_argument_type& x) const {
  201.     return op(x, value); 
  202.   }
  203. };
  204.  
  205. template <class Operation, class T>
  206. inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
  207.   typedef typename Operation::second_argument_type arg2_type;
  208.   return binder2nd<Operation>(op, arg2_type(x));
  209. }
  210.  
  211. template <class Operation1, class Operation2>
  212. class unary_compose : public unary_function<typename Operation2::argument_type,
  213.                                             typename Operation1::result_type> {
  214. protected:
  215.   Operation1 op1;
  216.   Operation2 op2;
  217. public:
  218.   unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
  219.   typename Operation1::result_type
  220.   operator()(const typename Operation2::argument_type& x) const {
  221.     return op1(op2(x));
  222.   }
  223. };
  224.  
  225. template <class Operation1, class Operation2>
  226. inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1, 
  227.                                                       const Operation2& op2) {
  228.   return unary_compose<Operation1, Operation2>(op1, op2);
  229. }
  230.  
  231. template <class Operation1, class Operation2, class Operation3>
  232. class binary_compose
  233.   : public unary_function<typename Operation2::argument_type,
  234.                           typename Operation1::result_type> {
  235. protected:
  236.   Operation1 op1;
  237.   Operation2 op2;
  238.   Operation3 op3;
  239. public:
  240.   binary_compose(const Operation1& x, const Operation2& y, 
  241.                  const Operation3& z) : op1(x), op2(y), op3(z) { }
  242.   typename Operation1::result_type
  243.   operator()(const typename Operation2::argument_type& x) const {
  244.     return op1(op2(x), op3(x));
  245.   }
  246. };
  247.  
  248. template <class Operation1, class Operation2, class Operation3>
  249. inline binary_compose<Operation1, Operation2, Operation3> 
  250. compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
  251.   return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
  252. }
  253.  
  254. template <class Arg, class Result>
  255. class pointer_to_unary_function : public unary_function<Arg, Result> {
  256. protected:
  257.   Result (*ptr)(Arg);
  258. public:
  259.   pointer_to_unary_function() {}
  260.   explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
  261.   Result operator()(Arg x) const { return ptr(x); }
  262. };
  263.  
  264. template <class Arg, class Result>
  265. inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
  266.   return pointer_to_unary_function<Arg, Result>(x);
  267. }
  268.  
  269. template <class Arg1, class Arg2, class Result>
  270. class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
  271. protected:
  272.     Result (*ptr)(Arg1, Arg2);
  273. public:
  274.     pointer_to_binary_function() {}
  275.     explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
  276.     Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
  277. };
  278.  
  279. template <class Arg1, class Arg2, class Result>
  280. inline pointer_to_binary_function<Arg1, Arg2, Result> 
  281. ptr_fun(Result (*x)(Arg1, Arg2)) {
  282.   return pointer_to_binary_function<Arg1, Arg2, Result>(x);
  283. }
  284.  
  285. template <class T>
  286. struct identity : public unary_function<T, T> {
  287.   const T& operator()(const T& x) const { return x; }
  288. };
  289.  
  290. template <class Pair>
  291. struct select1st : public unary_function<Pair, typename Pair::first_type> {
  292.   const typename Pair::first_type& operator()(const Pair& x) const
  293.   {
  294.     return x.first;
  295.   }
  296. };
  297.  
  298. template <class Pair>
  299. struct select2nd : public unary_function<Pair, typename Pair::second_type> {
  300.   const typename Pair::second_type& operator()(const Pair& x) const
  301.   {
  302.     return x.second;
  303.   }
  304. };
  305.  
  306. template <class Arg1, class Arg2>
  307. struct project1st : public binary_function<Arg1, Arg2, Arg1> {
  308.   Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
  309. };
  310.  
  311. template <class Arg1, class Arg2>
  312. struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
  313.   Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
  314. };
  315.  
  316. template <class Result>
  317. struct constant_void_fun
  318. {
  319.   typedef Result result_type;
  320.   result_type val;
  321.   constant_void_fun(const result_type& v) : val(v) {}
  322.   const result_type& operator()() const { return val; }
  323. };  
  324.  
  325. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
  326. template <class Result, class Argument = Result>
  327. #else
  328. template <class Result, class Argument>
  329. #endif
  330. struct constant_unary_fun : public unary_function<Argument, Result> {
  331.   Result val;
  332.   constant_unary_fun(const Result& v) : val(v) {}
  333.   const Result& operator()(const Argument&) const { return val; }
  334. };
  335.  
  336. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
  337. template <class Result, class Arg1 = Result, class Arg2 = Arg1>
  338. #else
  339. template <class Result, class Arg1, class Arg2>
  340. #endif
  341. struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
  342.   Result val;
  343.   constant_binary_fun(const Result& v) : val(v) {}
  344.   const Result& operator()(const Arg1&, const Arg2&) const {
  345.     return val;
  346.   }
  347. };
  348.  
  349. template <class Result>
  350. inline constant_void_fun<Result> constant0(const Result& val)
  351. {
  352.   return constant_void_fun<Result>(val);
  353. }
  354.  
  355. template <class Result>
  356. inline constant_unary_fun<Result,Result> constant1(const Result& val)
  357. {
  358.   return constant_unary_fun<Result,Result>(val);
  359. }
  360.  
  361. template <class Result>
  362. inline constant_binary_fun<Result,Result,Result> constant2(const Result& val)
  363. {
  364.   return constant_binary_fun<Result,Result,Result>(val);
  365. }
  366.  
  367. // Note: this code assumes that int is 32 bits.
  368. class subtractive_rng : public unary_function<unsigned int, unsigned int> {
  369. private:
  370.   unsigned int table[55];
  371.   size_t index1;
  372.   size_t index2;
  373. public:
  374.   unsigned int operator()(unsigned int limit) {
  375.     index1 = (index1 + 1) % 55;
  376.     index2 = (index2 + 1) % 55;
  377.     table[index1] = table[index1] - table[index2];
  378.     return table[index1] % limit;
  379.   }
  380.  
  381.   void initialize(unsigned int seed)
  382.   {
  383.     unsigned int k = 1;
  384.     table[54] = seed;
  385.     size_t i;
  386.     for (i = 0; i < 54; i++) {
  387.         size_t ii = (21 * (i + 1) % 55) - 1;
  388.         table[ii] = k;
  389.         k = seed - k;
  390.         seed = table[ii];
  391.     }
  392.     for (int loop = 0; loop < 4; loop++) {
  393.         for (i = 0; i < 55; i++)
  394.             table[i] = table[i] - table[(1 + i + 30) % 55];
  395.     }
  396.     index1 = 0;
  397.     index2 = 31;
  398.   }
  399.  
  400.   subtractive_rng(unsigned int seed) { initialize(seed); }
  401.   subtractive_rng() { initialize(161803398u); }
  402. };
  403.  
  404.  
  405. // Adaptor function objects: pointers to member functions.
  406.  
  407. // There are a total of 16 = 2^4 function objects in this family.
  408. //  (1) Member functions taking no arguments vs member functions taking
  409. //       one argument.
  410. //  (2) Call through pointer vs call through reference.
  411. //  (3) Member function with void return type vs member function with
  412. //      non-void return type.
  413. //  (4) Const vs non-const member function.
  414.  
  415. // Note that choice (4) is not present in the 8/97 draft C++ standard, 
  416. //  which only allows these adaptors to be used with non-const functions.
  417. //  This is likely to be recified before the standard becomes final.
  418. // Note also that choice (3) is nothing more than a workaround: according
  419. //  to the draft, compilers should handle void and non-void the same way.
  420. //  This feature is not yet widely implemented, though.  You can only use
  421. //  member functions returning void if your compiler supports partial
  422. //  specialization.
  423.  
  424. // All of this complexity is in the function objects themselves.  You can
  425. //  ignore it by using the helper function mem_fun, mem_fun_ref,
  426. //  mem_fun1, and mem_fun1_ref, which create whichever type of adaptor
  427. //  is appropriate.
  428.  
  429.  
  430. template <class S, class T>
  431. class mem_fun_t : public unary_function<T*, S> {
  432. public:
  433.   explicit mem_fun_t(S (T::*pf)()) : f(pf) {}
  434.   S operator()(T* p) const { return (p->*f)(); }
  435. private:
  436.   S (T::*f)();
  437. };
  438.  
  439. template <class S, class T>
  440. class const_mem_fun_t : public unary_function<const T*, S> {
  441. public:
  442.   explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {}
  443.   S operator()(const T* p) const { return (p->*f)(); }
  444. private:
  445.   S (T::*f)() const;
  446. };
  447.  
  448.  
  449. template <class S, class T>
  450. class mem_fun_ref_t : public unary_function<T, S> {
  451. public:
  452.   explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {}
  453.   S operator()(T& r) const { return (r.*f)(); }
  454. private:
  455.   S (T::*f)();
  456. };
  457.  
  458. template <class S, class T>
  459. class const_mem_fun_ref_t : public unary_function<T, S> {
  460. public:
  461.   explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {}
  462.   S operator()(const T& r) const { return (r.*f)(); }
  463. private:
  464.   S (T::*f)() const;
  465. };
  466.  
  467. template <class S, class T, class A>
  468. class mem_fun1_t : public binary_function<T*, A, S> {
  469. public:
  470.   explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {}
  471.   S operator()(T* p, A x) const { return (p->*f)(x); }
  472. private:
  473.   S (T::*f)(A);
  474. };
  475.  
  476. template <class S, class T, class A>
  477. class const_mem_fun1_t : public binary_function<const T*, A, S> {
  478. public:
  479.   explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {}
  480.   S operator()(const T* p, A x) const { return (p->*f)(x); }
  481. private:
  482.   S (T::*f)(A) const;
  483. };
  484.  
  485. template <class S, class T, class A>
  486. class mem_fun1_ref_t : public binary_function<T, A, S> {
  487. public:
  488.   explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {}
  489.   S operator()(T& r, A x) const { return (r.*f)(x); }
  490. private:
  491.   S (T::*f)(A);
  492. };
  493.  
  494. template <class S, class T, class A>
  495. class const_mem_fun1_ref_t : public binary_function<T, A, S> {
  496. public:
  497.   explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {}
  498.   S operator()(const T& r, A x) const { return (r.*f)(x); }
  499. private:
  500.   S (T::*f)(A) const;
  501. };
  502.  
  503. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  504.  
  505. template <class T>
  506. class mem_fun_t<void, T> : public unary_function<T*, void> {
  507. public:
  508.   explicit mem_fun_t(void (T::*pf)()) : f(pf) {}
  509.   void operator()(T* p) const { (p->*f)(); }
  510. private:
  511.   void (T::*f)();
  512. };
  513.  
  514. template <class T>
  515. class const_mem_fun_t<void, T> : public unary_function<const T*, void> {
  516. public:
  517.   explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {}
  518.   void operator()(const T* p) const { (p->*f)(); }
  519. private:
  520.   void (T::*f)() const;
  521. };
  522.  
  523. template <class T>
  524. class mem_fun_ref_t<void, T> : public unary_function<T, void> {
  525. public:
  526.   explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {}
  527.   void operator()(T& r) const { (r.*f)(); }
  528. private:
  529.   void (T::*f)();
  530. };
  531.  
  532. template <class T>
  533. class const_mem_fun_ref_t<void, T> : public unary_function<T, void> {
  534. public:
  535.   explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {}
  536.   void operator()(const T& r) const { (r.*f)(); }
  537. private:
  538.   void (T::*f)() const;
  539. };
  540.  
  541. template <class T, class A>
  542. class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> {
  543. public:
  544.   explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {}
  545.   void operator()(T* p, A x) const { (p->*f)(x); }
  546. private:
  547.   void (T::*f)(A);
  548. };
  549.  
  550. template <class T, class A>
  551. class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> {
  552. public:
  553.   explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {}
  554.   void operator()(const T* p, A x) const { (p->*f)(x); }
  555. private:
  556.   void (T::*f)(A) const;
  557. };
  558.  
  559. template <class T, class A>
  560. class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
  561. public:
  562.   explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {}
  563.   void operator()(T& r, A x) const { (r.*f)(x); }
  564. private:
  565.   void (T::*f)(A);
  566. };
  567.  
  568. template <class T, class A>
  569. class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
  570. public:
  571.   explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {}
  572.   void operator()(const T& r, A x) const { (r.*f)(x); }
  573. private:
  574.   void (T::*f)(A) const;
  575. };
  576.  
  577. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  578.  
  579. // Mem_fun adaptor helper functions.  There are only four:
  580. //  mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref.
  581.  
  582. template <class S, class T>
  583. inline mem_fun_t<S,T> mem_fun(S (T::*f)()) { 
  584.   return mem_fun_t<S,T>(f);
  585. }
  586.  
  587. template <class S, class T>
  588. inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) {
  589.   return const_mem_fun_t<S,T>(f);
  590. }
  591.  
  592. template <class S, class T>
  593. inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) { 
  594.   return mem_fun_ref_t<S,T>(f);
  595. }
  596.  
  597. template <class S, class T>
  598. inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) {
  599.   return const_mem_fun_ref_t<S,T>(f);
  600. }
  601.  
  602. template <class S, class T, class A>
  603. inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) { 
  604.   return mem_fun1_t<S,T,A>(f);
  605. }
  606.  
  607. template <class S, class T, class A>
  608. inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) {
  609.   return const_mem_fun1_t<S,T,A>(f);
  610. }
  611.  
  612. template <class S, class T, class A>
  613. inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) { 
  614.   return mem_fun1_ref_t<S,T,A>(f);
  615. }
  616.  
  617. template <class S, class T, class A>
  618. inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) {
  619.   return const_mem_fun1_ref_t<S,T,A>(f);
  620. }
  621.  
  622. __STL_END_NAMESPACE
  623.  
  624. #endif /* __SGI_STL_INTERNAL_FUNCTION_H */
  625.  
  626. // Local Variables:
  627. // mode:C++
  628. // End:
  629.