株式会社エス・スリー・フォー

<stx/functional>

DDJ-J 1998年5月号で紹介したSTL拡張コンポーネント”STX”の改版です。
初版で定義した関数のうち、使用頻度の少ないもの、
既存の関数オブジェクトで簡単に置き換えられるものを除き、新たにいくつか追加しました。

unary_equal_to / eq

template<class T>
class unary_equal_to : std::unary_function<T,bool> {
private:
  T value;
public:
  explicit unary_equal_to(const T& v)
    : value(v) {}
  bool operator()(const T& x) const
    { return x == value; }
};
bool operator()(const T& x) const

x == v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_equal_to<int> f(3);
cout << boolalpha;
cout << f(3) << endl; // true
cout << f(4) << endl; // false
template<class T>
unary_equal_to<T>
eq(const T& value) { 
  return unary_equal_to<T>(value); 
}

unary_equal_to<T>(value)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
int n = count_if(array, array+5, stx::eq(3)); // n = 1

unary_not_equal_to / ne

template<class T>
class unary_not_equal_to : std::unary_function<T,bool> {
  T value;
public:
  explicit unary_not_equal_to(const T& v) : value(v) {}
  bool operator()(const T& x) const
    { return !(x == value); }
};
bool operator()(const T& x) const

!(x == v) の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_not_equal_to<int> f(3);
cout << boolalpha;
cout << f(3) << endl; // false
cout << f(4) << endl; // true
template<class T>
unary_not_equal_to<T>
ne(const T& value) { 
  return unary_not_equal_to<T>(value); 
}

unary_not_equal_to<T>(value)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
int n = count_if(array, array+5, stx::ne(3)); // n = 4

unary_less / lt

template<class T>
class unary_less : std::unary_function<T,bool> {
  T value;
public:
  explicit unary_less(const T& v) : value(v) {}
  bool operator()(const T& x) const
    { return x < value; }
};
bool operator()(const T& x) const

x < v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_less<int> f(3);
cout << boolalpha;
cout << f(2) << endl; // true
cout << f(3) << endl; // false
template<class T>
unary_less<T>
lt(const T& value) { 
  return unary_less<T>(value); 
}

unary_less<T>(value)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
int n = count_if(array, array+5, stx::ne(3)); // n = 2

unary_greater / gt

template<class T>
class unary_greater : std::unary_function<T,bool> {
  T value;
public:
  explicit unary_greater(const T& v) : value(v) {}
  bool operator()(const T& x) const
    { return value < x; }
};
bool operator()(const T& x) const

v < x の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_greater<int> f(3);
cout << boolalpha;
cout << f(3) << endl; // false
cout << f(4) << endl; // true
template<class T>
unary_greater<T>
gt(const T& value) { 
  return unary_greater<T>(value); 
}

unary_greater<T>(value)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
int n = count_if(array, array+5, stx::gt(3)); // n = 2

unary_less_equal / le

template<class T>
class unary_less_equal : std::unary_function<T,bool> {
  T value;
public:
  explicit unary_less_equal(const T& v) : value(v) {}
  bool operator()(const T& x) const
    { return !(value < x); }
};
bool operator()(const T& x) const

!(v < x) の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_less_equal<int> f(3);
cout << boolalpha;
cout << f(3) << endl; // true
cout << f(4) << endl; // false
template<class T>
unary_less_equal<T>
le(const T& value) { 
  return unary_less_equal<T>(value); 
}

unary_less_equal<T>(value)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
int n = count_if(array, array+5, stx::le(3)); // n = 3

unary_greater_equal / ge

template<class T>
class unary_greater_equal : std::unary_function<T,bool> {
  T value;
public:
  explicit unary_greater_equal(const T& v) : value(v) {}
  bool operator()(const T& x) const
    { return !(x < value); }
};
bool operator()(const T& x) const

!(x < v) の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_greater_equal<int> f(3);
cout << boolalpha;
cout << f(2) << endl; // false
cout << f(3) << endl; // true
template<class T>
unary_greater_equal<T>
ge(const T& value) { 
  return unary_greater_equal<T>(value); 
}

unary_greater_equal<T>(value)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
int n = count_if(array, array+5, stx::ge(3)); // n = 3

in_range_cc / range_cc

template<class T>
class in_range_cc : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  in_range_cc(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return !(x < lo) && !(hi < x); }
};
bool operator()(const T& x) const

l <= x <= h ならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::in_range_cc<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "2 3 4 "
template<class T>
in_range_cc<T>
range_cc(const T& lo, const T& hi) { 
  return in_range_cc<T>(lo,hi); 
}

in_range_cc<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::range_cc(2,4)); // "2 3 4 "

in_range_co / range_co

template<class T>
class in_range_co : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  in_range_co(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return !(x < lo) &&  (x < hi); }
};
bool operator()(const T& x) const

l <= x < h ならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::in_range_co<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "2 3 "
template<class T>
inline 
in_range_co<T>
range_co(const T& lo, const T& hi) { 
  return in_range_co<T>(lo,hi); 
}

in_range_co<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::range_co(2,4)); // "2 3 "

in_range_oc / range_oc

template<class T>
class in_range_oc : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  in_range_oc(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return  (lo < x) && !(hi < x); }
};
bool operator()(const T& x) const

l < x <= h ならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::in_range_oc<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "3 4 "
template<class T>
in_range_oc<T>
range_oc(const T& lo, const T& hi) { 
  return in_range_oc<T>(lo,hi); 
}

in_range_co<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::range_oc(2,4)); // "3 4 "

in_range_oo / range_oo

template<class T>
class in_range_oo : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  in_range_oo(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return  (lo < x) &&  (x < hi); }
};
bool operator()(const T& x) const

l < x < h ならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::in_range_oo<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "3 "
template<class T>
in_range_oo<T>
range_oo(const T& lo, const T& hi) { 
  return in_range_oo<T>(lo,hi); 
}

in_range_oo<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::range_oo(2,4)); // "3 "

out_of_range_cc / nrange_cc

template<class T>
class out_of_range_cc : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  out_of_range_cc(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return  (x < lo) ||  (hi < x); }
};
bool operator()(const T& x) const

l <= x <= h でないならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::out_of_range_cc<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "1 5 "
template<class T>
out_of_range_cc<T>
nrange_cc(const T& lo, const T& hi) {
  return out_of_range_cc<T>(lo,hi); 
}

out_of_range_cc<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::nrange_cc(2,4)); // "1 5 "

out_of_range_co / nrange_co

template<class T>
class out_of_range_co : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  out_of_range_co(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return  (x < lo) || !(x < hi); }
};
bool operator()(const T& x) const

l <= x < h でないならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::out_of_range_co<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "1 4 5 "
template<class T>
out_of_range_co<T>
nrange_co(const T& lo, const T& hi) {
  return out_of_range_co<T>(lo,hi); 
}

out_of_range_co<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::nrange_co(2,4)); // "1 4 5 "

out_of_range_oc / nrange_oc

template<class T>
class out_of_range_oc : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  out_of_range_oc(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return !(lo < x) ||  (hi < x); }
};
bool operator()(const T& x) const

l < x <= h でないならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::out_of_range_oc<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "1 2 5 "
template<class T>
out_of_range_oc<T>
nrange_oc(const T& lo, const T& hi) { 
  return out_of_range_oc<T>(lo,hi); 
}

out_of_range_oc<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::nrange_oc(2,4)); // "1 2 5 "

out_of_range_oo / nrange_oo

template<class T>
class out_of_range_oo : std::unary_function<T,bool> {
  T lo;
  T hi;
public:
  out_of_range_oo(const T& l, const T& h) : lo(l), hi(h) {}
  bool operator()(const T& x) const
    { return !(lo < x) || !(x < hi); }
};
bool operator()(const T& x) const

l < x < h でないならtrueを返します。 l,h はコンストラクタに与えた値です。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::out_of_range_oo<int> f(2,4);
stx::select_copy_if(array, array+5, out, f); // "1 2 4 5 "
template<class T>
out_of_range_oo<T>
nrange_oo(const T& lo, const T& hi) { 
  return out_of_range_oo<T>(lo,hi); 
}

out_of_range_oo<T>(lo,hi)を返します。

// sample
int array[] = { 1, 2, 3, 4, 5 };
ostream_iterator<int> out(cout," ");
stx::select_copy_if(array, array+5, out, stx::nrange_oo(2,4)); // "1 2 4 5 "

inv_minus

template<class T>
struct inv_minus : std::binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const {
    return y - x;
  }
};
T operator()(const T& x, const T& y) const

y - x の結果を返します。

// sample
stx::inv_minus<int> f(2);
cout << f(3); // "1"

inv_divides

template<class T>
struct inv_divides : std::binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const {
    return y / x;
  }
};
T operator()(const T& x, const T& y) const

y / x の結果を返します。

// sample
stx::inv_divides<int> f;
cout << f(2,6); // "3"

inv_modulus

template<class T>
struct inv_modulus : std::binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const {
    return y % x;
  }
};
T operator()(const T& x, const T& y) const

y % x の結果を返します。

// sample
stx::inv_modulus<int> f;
cout << f(3,5); // "2"

unary_plus / u_plus

template<class T>
class unary_plus : std::unary_function<T,T> {
  T value;
public:
  explicit unary_plus(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x + value; }
};
bool operator()(const T& x) const

x + v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_plus<int> f(2);
cout << f(3); // "5"
template<class T>
unary_plus<T>
u_plus(const T& v) { 
  return unary_plus<T>(v); 
}

unary_plus<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_plus(2)); // "3 4 5 "

unary_minus / u_minus

template<class T>
class unary_minus : std::unary_function<T,T> {
  T value;
public:
  explicit unary_minus(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x - value; }
};
bool operator()(const T& x) const

x - v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_minus<int> f(2);
cout << f(3); // "1"
template<class T>
unary_minus<T>
u_minus(const T& v) { 
  return unary_minus<T>(v); 
}

unary_minus<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_minus(2)); // "-1 0 1 "

unary_inv_minus / u_iminus

template<class T>
class unary_inv_minus : std::unary_function<T,T> {
  T value;
public:
  explicit unary_inv_minus(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return value - x; }
};
bool operator()(const T& x) const

v - x の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_inv_minus<int> f(2);
cout << f(3); // "-1"
template<class T>
unary_inv_minus<T>
u_iminus(const T& v) { 
  return unary_inv_minus<T>(v); 
}

unary_inv_minus<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_iminus(2)); // "1 0 -1 "

unary_multiplies / u_multiplies

template<class T>
class unary_multiplies : std::unary_function<T,T> {
  T value;
public:
  explicit unary_multiplies(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x * value; }
};
bool operator()(const T& x) const

x * v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_multiplies<int> f(2);
cout << f(3); // "6"
template<class T>
unary_multiplies<T>
u_multiplies(const T& v) {
  return unary_multiplies<T>(v); 
}

unary_multiplies<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_multiplies(2)); // "2 4 6 "

unary_divides / u_divides

template<class T>
class unary_divides : std::unary_function<T,T> {
  T value;
public:
  explicit unary_divides(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x / value; }
};
bool operator()(const T& x) const

x / v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_divides<int> f(2);
cout << f(4); // "2"
template<class T>
unary_divides<T>
u_divides(const T& v) {
  return unary_divides<T>(v); 
}

unary_divides<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_multiplies(2)); // "0 1 1 "

unary_inv_divides / u_idivides

template<class T>
class unary_inv_divides : std::unary_function<T,T> {
  T value;
public:
  explicit unary_inv_divides(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return value / x; }
};
bool operator()(const T& x) const

v / x の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_divides<int> f(4);
cout << f(2); // "2"
template<class T>
unary_inv_divides<T>
u_idivides(const T& v) { 
  return unary_inv_divides<T>(v); 
}

unary_inv_divides<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_idivides(6)); // "6 3 2 "

unary_modulus / u_modulus

template<class T>
class unary_modulus : std::unary_function<T,T> {
  T value;
public:
  explicit unary_modulus(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x % value; }
};
bool operator()(const T& x) const

x % v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_divides<int> f(3);
cout << f(4); // "1"
template<class T>
unary_modulus<T>
u_modulus(const T& v) {
  return unary_modulus<T>(v); 
}

unary_modulus<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_modulus(2)); // "1 0 1 "

unary_inv_modulus / u_imodulus

template<class T>
class unary_inv_modulus : std::unary_function<T,T> {
  T value;
public:
  explicit unary_inv_modulus(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return value % x; }
};
bool operator()(const T& x) const

v % x の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_divides<int> f(3);
cout << f(4); // "3"
template<class T>
unary_inv_modulus<T>
u_imodulus(const T& v) {
  return unary_inv_modulus<T>(v); 
}

unary_inv_modulus<T>(v)を返します。

// sample
int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::u_imodulus(2)); // "1 0 2 "

bitwise_and

template<class T>
struct bitwise_and : std::binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const 
    { return x & y; }
};
T operator()(const T& x, const T& y) const

x & y の結果を返します。

// sample
stx::bitwise_and<int> f;
cout << showbase << hex << f(0x03,0x75); // "0x1"

bitwise_or

template<class T>
struct bitwise_or : std::binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const 
    { return x | y; }
};
T operator()(const T& x, const T& y) const

x | y の結果を返します。

// sample
stx::bitwise_or<int> f;
cout << showbase << hex << f(0x03,0x75); // "0x77"

bitwise_xor

template<class T>
struct bitwise_xor : std::binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const 
    { return x ^ y; }
};
T operator()(const T& x, const T& y) const

x ^ y の結果を返します。

// sample
stx::bitwise_xor<int> f;
cout << showbase << hex << f(0x03,0x75); // "0x76"

bitwise_not

template<class T>
struct bitwise_not : std::unary_function<T,T> {
  T operator()(const T& x) const 
    { return ~x; }
};
T operator()(const T& x, const T& y) const

~x の結果を返します。

// sample
stx::bitwise_not<int> f;
cout << showbase << hex << f(0x03); // "0xfffffffc"

unary_bitwise_and / and_mask

template<class T>
class unary_bitwise_and : std::unary_function<T,T> {
  T value;
public:
  explicit unary_bitwise_and(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x & value; }
};
T operator()(const T& x) const

x & v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_bitwise_and<int> f(0x03);
cout << showbase << hex << f(0x75); // "0x1"
template<class T>
unary_bitwise_and<T>
and_mask(const T& x) { 
  return unary_bitwise_and<T>(x); 
}

unary_bitwise_and<T>(x) を返します。

// sample
int array[] = { 4, 5, 6 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::and_mask(0x03)); // "0 1 2 "

unary_bitwise_or / or_mask

template<class T>
class unary_bitwise_or : std::unary_function<T,T> {
  T value;
public:
  explicit unary_bitwise_or(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x | value; }
};
T operator()(const T& x) const

x | v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_bitwise_or<int> f(0x03);
cout << showbase << hex << f(0x75); // "0x77"
template<class T>
unary_bitwise_or<T>
or_mask(const T& x) {
  return unary_bitwise_or<T>(x); 
}

unary_bitwise_or<T>(x) を返します。

// sample
int array[] = { 4, 5, 6 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::or_mask(0x03)); // "7 7 7 "

unary_bitwise_xor / xor_mask

template<class T>
class unary_bitwise_xor : std::unary_function<T,T> {
  T value;
public:
  explicit unary_bitwise_xor(const T& v) : value(v) {}
  T operator()(const T& x) const
    { return x ^ v_; }
};
T operator()(const T& x) const

x ^ v の結果を返します。 v はコンストラクタに与えた値です。

// sample
stx::unary_bitwise_xor<int> f(0x03);
cout << showbase << hex << f(0x75); // "0x76"
template<class T>
unary_bitwise_xor<T>
xor_mask(const T& x) {
  return unary_bitwise_xor<T>(x); 
}

unary_bitwise_xor<T>(x) を返します。

// sample
int array[] = { 4, 5, 6 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::xor_mask(0x03)); // "7 6 5 "

unary_compose / compose1

template<class UnaryFunction1, class UnaryFunction2>
class unary_compose
  : public std::unary_function<UnaryFunction2::argument_type,
                               UnaryFunction1::result_type> {
protected:
  UnaryFunction1 fn1_;
  UnaryFunction2 fn2_;
public:
  unary_compose(const UnaryFunction1& f1, const UnaryFunction2& f2)
    : fn1_(f1), fn2_(f2) {}
  result_type operator()(const argument_type& x) const
    { return fn1_(fn2_(x)); }
};
result_type operator()(const argument_type& x) const

f1(f2(x)) の結果を返します。f1,f2はコンストラクタに与えた関数オブジェクトです。

// sample
template<class T>
struct square : unary_function<T,T> 
{ T operator()(const T& x) const { return x * x; } };

stx::unary_compose< negate<int>,square<int> > 
  f(negate<int>(), square<int>());
cout << f(3); // "-9"
template<class UnaryFunction1, class UnaryFunction2>
unary_compose<UnaryFunction1,UnaryFunction2>
compose1(const UnaryFunction1& fn1, const UnaryFunction2& fn2) {
  return unary_compose<UnaryFunction1,UnaryFunction2>(fn1,fn2); 
}

unary_compose<UnaryFunction1,UnaryFunction2>(fn1,fn2)を返します。

// sample
template<class T>
struct square : unary_function<T,T> 
{ T operator()(const T& x) const { return x * x; } };

int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, stx::compose1(negate<int>(),square<int>()) ); // &-1 -4 -9 &

binary_compose / compose2

template<class BinaryFunction1, class UnaryFunction2, class UnaryFunction3>
class binary_compose
  : public std::unary_function<typename UnaryFunction2::argument_type,
                               typename BinaryFunction1::result_type> {
protected:
  BinaryFunction1 fn1_;
  UnaryFunction2 fn2_;
  UnaryFunction3 fn3_;
public:
  binary_compose(const BinaryFunction1& f1, 
                 const UnaryFunction2& f2, const UnaryFunction3& f3)
    : fn1_(f1), fn2_(f2), fn3_(f3) { }
  result_type operator()(const argument_type& x) const
    { return fn1_(fn2_(x), fn3_(x)); }
};
result_type operator()(const argument_type& x)const

f1(f2(x),f3(x)) の結果を返します。f1,f2はコンストラクタに与えた関数オブジェクトです。

// sample
template<class T>
struct square : unary_function<T,T> 
{ T operator()(const T& x) const { return x * x; } };

stx::binary_compose< plus<int>,square<int>,negate<int> >
  f(plus<int>(),square<int>(),negate<int>()); // f(x) = x*x - x
cout << f(3) << endl; // "6"
template<class BinaryFunction1, class UnaryFunction2, class UnaryFunction3>
binary_compose<BinaryFunction1,UnaryFunction2,UnaryFunction3>
compose2(const BinaryFunction1& f1, 
         const UnaryFunction2& f2, const UnaryFunction3& f3) {
  return binary_compose<BinaryFunction1,UnaryFunction2,UnaryFunction3>(f1,f2,f3);
}

binary_compose<BinaryFunction1,UnaryFunction2,UnaryFunction3>(f1,f2,f3)を返します。

// sample
template<class T>
struct square : unary_function<T,T> 
{ T operator()(const T& x) const { return x * x; } };

int array[] = { 1, 2, 3 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, 
          stx::compose2(plus<int>(),square<int>(),negate<int>()) ); // "0 2 6 "

unary_tern / tern1

template<class Predicate, class Function1, class Function2>
class unary_tern : public std::unary_function<Predicate::argument_type, Function1::result_type> {
  Predicate pr_;
  Function1 f1_;
  Function2 f2_;
public:
  explicit unary_tern(const Predicate& pr, const Function1& f1, const Function2& f2)
    : pr_(pr), f1_(f1), f2_(f2) {}
  result_type operator()(const argument_type& x) const
    { return pr_(x) ? f1_(x) : f2_(x); }
};
result_type operator()(const argument_type& x)

pr(x) が 真なら f1(x) を、 偽なら f2(x) を返します。 pr, f1, f2 はコンストラクタに与えた関数オブジェクトです。

// sample
template<class T>
struct square : unary_function<T,T> 
{ T operator()(const T& x) const { return x * x; } };

stx::unary_tern< stx::unary_less<int>, negate<int>, square<int> >
  f(stx::unary_less<int>(0), negate<int>(), square<int>());
cout << f(-2) << endl; // "2"
cout << f(2) << endl; // "4"
template<class Predicate, class Function1, class Function2>
unary_tern<Predicate,Function1,Function2>
tern1(const Predicate& pr, const Function1& f1, const Function2& f2) { 
  return unary_tern<Predicate,Function1,Function2>(pr,f1,f2); 
}

unary_tern<Predicate,Function1,Function2>(pr,f1,f2) を返します。

// sample
template<class T>
struct square : unary_function<T,T> 
{ T operator()(const T& x) const { return x * x; } };

int array[] = { -2, 0, 2 };
ostream_iterator<int> out(cout," ");
transform(array, array+3, out, 
          stx::tern1(stx::unary_less<int>(0), negate<int>(), square<int>()) ); // "2 0 4 "

binary_tern / tern2

template<class Predicate, class Function1, class Function2>
class binary_tern : public std::binary_function<Predicate::first_argument_type, 
                                Predicate::second_argument_type,
                                Function1::result_type> {
  Predicate pr_;
  Function1 f1_;
  Function2 f2_;
public:
  explicit binary_tern(const Predicate& pr, const Function1& f1, const Function2& f2)
    : pr_(pr), f1_(f1), f2_(f2) {}
  result_type operator()(const first_argument_type& x, const second_argument_type& y) const
    { return pr_(x,y) ? f1_(x,y) : f2_(x,y); }
};
result_type operator()(const first_argument_type& x,
const second_argument_type& y) const

pr(x,y) が 真なら f1(x,y) を、 偽なら f2(x,y) を返します。 pr, f1, f2 はコンストラクタに与えた関数オブジェクトです。

// sample
stx::binary_tern< less<int>, stx::inv_minus<int>, minus<int> >
  f(less<int>(), stx::inv_minus<int>(), minus<int>());
cout << f(1,3) << endl; // "2"
cout << f(3,1) << endl; // "2"
template<class Predicate, class Function1, class Function2>
binary_tern<Predicate,Function1,Function2>
tern2(const Predicate& pr, const Function1& f1, const Function2& f2) {
  return binary_tern<Predicate,Function1,Function2>(pr,f1,f2); 
}

binary_tern<Predicate,Function1,Function2>(pr,f1,f2) を返します。

// sample
int array1[] = { 1, 2, 3 };
int array2[] = { 3, 2, 1 };
ostream_iterator<int> out(cout," ");
transform(array1, array1+3, array2, out, 
          stx::tern2(less<int>(), stx::inv_minus<int>(), minus<int>()) ); // "2 0 2 "