<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 "