Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Boost.Hana: Foldable

Boost , ,

Boost.Hana  1.0.1
Your standard library for metaprogramming
Концепция<Foldable>представляет собой структуры данных, которые могут быть сведены к одному значению.

Вообще говоря, складывание относится к концепции суммирования сложной структуры как единого значения, последовательно применяя двоичную операцию, которая сводит два элемента структуры к одному значению. Складки бывают разных вкусов; левые складки, правые складки, складки с начальным состоянием восстановления и без него, и их монадические варианты. Эта концепция способна выразить все эти варианты складывания.

Другой способ видения<Foldable>— это структуры данных, поддерживающие внутреннюю итерацию с возможностью накопления результата. Под внутренней итерацией мы подразумеваем, чтоуправление цикломнаходится в руке структуры, а не абонента. Следовательно, именно структура решает, когда итерация прекращается, что обычно происходит, когда вся структура потребляется. Поскольку C++ — это язык, который требует<Foldable>Структуры должны быть конечными, иначе нужно было бы бесконечно зацикливаться, чтобы поглотить всю структуру.

Note
While the fact that Foldable only works for finite structures may seem overly restrictive in comparison to the Haskell definition of Foldable, a finer grained separation of the concepts should mitigate the issue. For iterating over possibly infinite data structures, see the Iterable concept. For searching a possibly infinite data structure, see the Searchable concept.

Minimal complete definition

<fold_left>или<unpack>

Тем не менее, обратите внимание, что минимальное полное определение, предоставленное через<unpack>, будет гораздо более эффективным, чем одно, предоставленное через<fold_left>.

Concrete models

<hana::map>,<hana::optional>,<hana::pair>,<hana::set>,<hana::range>,<hana::tuple>

The linearization of a Foldable

Интуитивно для<Foldable>структуры<xs>линеаризация<xs>представляет собой последовательность всех элементов в<xs>, как если бы они были помещены в список:

linearization(xs) = [x1, x2, ..., xn]

Обратите внимание, что всегда можно произвести такую линеаризацию для конечного<Foldable>путем установки

linearization(xs) = fold_left(xs, [], flip(prepend))

Для определения<[]>и<prepend>. Понятие линеаризации полезно для выражения различных свойств<Foldable>структур и используется во всей документации. Также обратите внимание, что<Iterable>s определяютрасширенную версиюэтого, допуская бесконечные структуры.

Compile-time Foldables

<Foldable>— это<Foldable>, общая длина которого известна во время компиляции. Иными словами, это<Foldable>, чей<length>метод возвращает<Constant>неподписанного интегрального типа. При сворачивании времени компиляции<Foldable>сворачивание может быть раскручено, так как на момент компиляции известно конечное число шагов алгоритма.

Кроме того, метод<unpack>доступен только для компиляции времени<Foldable>с. Это связано с тем, что возвраттипа<unpack>зависит от количества объектов в структуре. Способность разрешать тип возврата<unpack>во время компиляции, следовательно, требует, чтобы длина структуры была известна во время компиляции.

В текущей версии библиотеки поддерживается только время компиляции<Foldable>с.Хотя теоретически было бы возможно поддерживать время выполнения<Foldable>, для этого требуется больше исследований.

Provided conversion to Sequences

При наличии метки<S>, которая является<Sequence>, объект, метка которого является моделью концепции<Foldable>, может быть преобразован в объект метки<S>. Другими словами,<Foldable>может быть преобразован в<Sequence><S>, просто взяв линеаризацию<Foldable>и создав последовательность с этим. Более конкретно, учитывая<Foldable><xs>с линеаризацией<[x1, ..., xn]>и<Sequence>тег<S>,<to<S>(xs)>эквивалентен<make<S>(x1, ..., xn)>.

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
static_assert(hana::to<hana::tuple_tag>(hana::just(1)) == hana::make_tuple(1), "");
BOOST_HANA_CONSTANT_CHECK(hana::to<hana::tuple_tag>(hana::nothing) == hana::make_tuple());
hana::to<hana::tuple_tag>(hana::make_range(hana::int_c<3>, hana::int_c<6>))
==
hana::tuple_c<int, 3, 4, 5>
);
}

Free model for builtin arrays

Встроенные массивы, размер которых известен, могут быть сложены, если они были однородными кортежами. Однако обратите внимание, что встроенные массивы не могут быть сделаны больше, чем<Foldable>(например,<Iterable>), потому что они не могут быть пустыми и они также не могут быть возвращены из функций.

Primer on monadic folds

Монадическая складка — складка, в которой последующие вызовы к двоичной функции прикованы к монадическому<chain>оператору соответствующей Монады. Это позволяет сложить структуру в обычном монадическом контексте. Например, для выполнения монадного сгиба с монадой<hana::optional>требуется, чтобы двоичная функция возвращала результат как<hana::optional>, а сгиб прерывался и возвращался<nothing>всякий раз, когда один из этапов накопления терпел неудачу (т.е. возвращался<nothing>). Если же все шаги по сокращению окажутся успешными, то<just>результат будет возвращен. Различные монады, конечно, приведут к различным эффектам.

Variables

constexpr auto boost::hana::count
 Return the number of elements in the structure that compare equal to a given value.Given a Foldable structure xs and a value value, count returns an unsigned integral, or a Constant thereof, representing the number of elements of xs that compare equal to value. For this method to be well-defined, all the elements of the structure must be Comparable with the given value. More...
 
constexpr auto boost::hana::count_if
 Return the number of elements in the structure for which the predicate is satisfied.Specifically, returns an object of an unsigned integral type, or a Constant holding such an object, which represents the number of elements in the structure satisfying the given predicate. More...
 
constexpr auto boost::hana::fold = fold_left
 Equivalent to fold_left; provided for convenience.fold is equivalent to fold_left. However, it is not tag-dispatched on its own because it is just an alias to fold_left. Also note that fold can be called with or without an initial state, just like fold_left: More...
 
constexpr auto boost::hana::fold_left
 Left-fold of a structure using a binary operation and an optional initial reduction state.fold_left is a left-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_left applies f as follows. More...
 
constexpr auto boost::hana::fold_right
 Right-fold of a structure using a binary operation and an optional initial reduction state.fold_right is a right-associative fold using a binary operation. Given a structure containing x1, ..., xn, a function f and an optional initial state, fold_right applies f as follows. More...
 
constexpr auto boost::hana::for_each
 Perform an action on each element of a foldable, discarding the result each time.Iteration is done from left to right, i.e. in the same order as when using fold_left. If the structure is not finite, this method will not terminate. More...
 
constexpr auto boost::hana::fuse
 Transform a function taking multiple arguments into a function that can be called with a compile-time Foldable. More...
 
constexpr auto boost::hana::length
 Return the number of elements in a foldable structure.Given a Foldable xs, length(xs) must return an object of an unsigned integral type, or an IntegralConstant holding such an object, which represents the number of elements in the structure. More...
 
constexpr auto boost::hana::maximum
 Return the greatest element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), maximum returns the greatest element of the structure, i.e. an element which is greater than or equal to every other element in the structure, according to the predicate. More...
 
constexpr auto boost::hana::minimum
 Return the least element of a non-empty structure with respect to a predicate, by default less.Given a non-empty structure and an optional binary predicate (less by default), minimum returns the least element of the structure, i.e. an element which is less than or equal to every other element in the structure, according to the predicate. More...
 
template<typename M >
constexpr auto boost::hana::monadic_fold_left
 Monadic left-fold of a structure with a binary operation and an optional initial reduction state. More...
 
template<typename M >
constexpr auto boost::hana::monadic_fold_right
 Monadic right-fold of a structure with a binary operation and an optional initial reduction state. More...
 
constexpr auto boost::hana::product = see documentation
 Compute the product of the numbers of a structure.More generally, product will take any foldable structure containing objects forming a Ring and reduce them using the Ring's binary operation. The initial state for folding is the identity of the Ring's operation. It is sometimes necessary to specify the Ring to use; this is possible by using product<R>. If no Ring is specified, the structure will use the Ring formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,. More...
 
constexpr auto boost::hana::reverse_fold
 Equivalent to reverse_fold in Boost.Fusion and Boost.MPL.This method has the same semantics as reverse_fold in Boost.Fusion and Boost.MPL, with the extension that an initial state is not required. This method is equivalent to fold_right, except that the accumulating function must take its arguments in reverse order, to match the order used in Fusion. In other words,. More...
 
constexpr auto boost::hana::size = hana::length
 Equivalent to length; provided for consistency with the standard library.This method is an alias to length provided for convenience and consistency with the standard library. As an alias, size is not tag-dispatched on its own and length should be customized instead. More...
 
constexpr auto boost::hana::sum = see documentation
 Compute the sum of the numbers of a structure.More generally, sum will take any foldable structure containing objects forming a Monoid and reduce them using the Monoid's binary operation. The initial state for folding is the identity of the Monoid. It is sometimes necessary to specify the Monoid to use; this is possible by using sum<M>. If no Monoid is specified, the structure will use the Monoid formed by the elements it contains (if it knows it), or integral_constant_tag<int> otherwise. Hence,. More...
 
constexpr auto boost::hana::unpack
 Invoke a function with the elements of a Foldable as arguments.Given a function and a foldable structure whose length can be known at compile-time, unpack invokes the function with the contents of that structure. In other words, unpack(xs, f) is equivalent to f(x...), where x... are the elements of the structure. The length of the structure must be known at compile-time, because the version of f's operator() that will be compiled depends on the number of arguments it is called with, which has to be known at compile-time. More...
 

Variable Documentation

constexpr auto boost::hana::count

<#include <boost/hana/fwd/count.hpp>>

Initial value:
= [](auto&& xs, auto&& value) {
return tag-dispatched;
}
constexpr auto value
Return the compile-time value associated to a constant.This function returns the value associated to ...
Definition: value.hpp:54

Возвращает количество элементов в структуре, которые сравниваются с заданным значением. При наличии складной структуры<xs>и значения<value><count>возвращается неподписанный интеграл или его постоянная, представляющая число элементов<xs>, которые сравниваются с<value>. Для того чтобы этот метод был четко определен, все элементы конструкции должны быть сопоставимы с заданным значением.

Parameters
xsСтруктура, элементы которой учитываются.
valueЗначение по сравнению с каждым элементом в структуре. Элементы, которые сравниваются с этим значением, считаются, другие нет.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
constexpr auto ints = hana::tuple_c<int, 1, 2, 3, 2, 2, 4, 2>;
BOOST_HANA_CONSTANT_CHECK(hana::count(ints, hana::int_c<2>) == hana::size_c<4>);
static_assert(hana::count(ints, 2) == 4, "");
constexpr auto types = hana::tuple_t<int, char, long, short, char, double>;
BOOST_HANA_CONSTANT_CHECK(hana::count(types, hana::type_c<char>) == hana::size_c<2>);
}
constexpr auto boost::hana::count_if

<#include <boost/hana/fwd/count_if.hpp>>

Initial value:
= [](auto&& xs, auto&& predicate) {
return tag-dispatched;
}

Возвращает количество элементов в структуре, для которых удовлетворяется<predicate>. В частности, возвращает объект неподписанного интегрального типа, или<Constant>удерживающий такой объект, который представляет количество элементов в структуре, удовлетворяющей данному<predicate>.

Parameters
xsСтруктура, элементы которой учитываются.
predicateФункция, называемая<predicate(x)>, где<x>является элементом структуры, и возвращающая<Logical>, представляющая, следует ли считать<x>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <type_traits>
namespace hana = boost::hana;
using namespace hana::literals;
auto is_odd = [](auto x) {
return x % 2_c != 0_c;
};
int main() {
constexpr auto ints = hana::tuple_c<int, 1, 2, 3>;
BOOST_HANA_CONSTANT_CHECK(hana::count_if(ints, is_odd) == hana::size_c<2>);
constexpr auto types = hana::tuple_t<int, char, long, short, char, double>;
BOOST_HANA_CONSTANT_CHECK(hana::count_if(types, hana::trait<std::is_floating_point>) == hana::size_c<1>);
BOOST_HANA_CONSTANT_CHECK(hana::count_if(types, hana::equal.to(hana::type_c<char>)) == hana::size_c<2>);
BOOST_HANA_CONSTANT_CHECK(hana::count_if(types, hana::equal.to(hana::type_c<void>)) == hana::size_c<0>);
}
constexpr auto boost::hana::fold = fold_left

<#include <boost/hana/fwd/fold.hpp>>

<fold_left>Для удобства.<fold>является эквивалентом<fold_left>. Однако он не распространяется сам по себе, потому что это просто псевдоним<fold_left>. Также обратите внимание, что<fold>может быть вызван с начальным состоянием или без него, как<fold_left>:

fold(xs, state, f) == fold_left(xs, state, f)
fold(xs, f) == fold_left(xs, f)

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <sstream>
#include <string>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
int main() {
auto f = [=](std::string s, auto element) {
return "f(" + s + ", " + to_string(element) + ")";
};
// with an initial state
hana::fold(hana::make_tuple(2, '3', 4, 5.0), "1", f)
==
"f(f(f(f(1, 2), 3), 4), 5)"
);
// without initial state
hana::fold(hana::make_tuple("1", 2, '3', 4, 5.0), f)
==
"f(f(f(f(1, 2), 3), 4), 5)"
);
}
constexpr auto boost::hana::fold_left

<#include <boost/hana/fwd/fold_left.hpp>>

Initial value:
= [](auto&& xs[, auto&& state], auto&& f) -> decltype(auto) {
return tag-dispatched;
}

Левая часть структуры с использованием двоичной операции и факультативного начального состояния восстановления.<fold_left>представляет собой левоассоциативную складку с использованием двоичной операции. Учитывая структуру, содержащую<x1, ..., xn>, функцию<f>и факультативное начальное состояние,<fold_left>применяется<f>следующим образом.

f(... f(f(f(x1, x2), x3), x4) ..., xn) // without state
f(... f(f(f(f(state, x1), x2), x3), x4) ..., xn) // with state

Когда структура пуста, могут возникнуть две вещи. Если первоначальное состояние было обеспечено, оно возвращается как есть. В противном случае, если используется версия функции без состояния, срабатывает ошибка. Когда конструкция содержит один элемент и используется версия функции без состояния, этот единственный элемент возвращается как есть.

Signature

При наличии<Foldable><F>и факультативного начального состояния метки<S>подписи для<fold_left>являются

\[ \mathtt{fold\_left} : F(T) \times S \times (S \times T \to S) \to S \]

для варианта с начальным состоянием, и

\[ \mathtt{fold\_left} : F(T) \times (T \times T \to T) \to T \]

вариант без начального состояния.

Parameters
xsСтруктура складывается.
stateНачальное значение, используемое для складывания.
fБинарная функция называется<f(state, x)>, где<state>является результатом, накопленным до сих пор, и<x>является элементом в структуре. Для левых складок без начального состояния функция называется<f(x1, x2)>, где<x1>и<x2>являются элементами структуры.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <sstream>
#include <string>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
int main() {
auto f = [=](std::string s, auto element) {
return "f(" + s + ", " + to_string(element) + ")";
};
// with an initial state
hana::fold_left(hana::make_tuple(2, '3', 4, 5.0), "1", f)
==
"f(f(f(f(1, 2), 3), 4), 5)"
);
// without initial state
hana::fold_left(hana::make_tuple("1", 2, '3', 4, 5.0), f)
==
"f(f(f(f(1, 2), 3), 4), 5)"
);
}
constexpr auto boost::hana::fold_right

<#include <boost/hana/fwd/fold_right.hpp>>

Initial value:
= [](auto&& xs[, auto&& state], auto&& f) -> decltype(auto) {
return tag-dispatched;
}

Правое сложение структуры с использованием двоичной операции и факультативного начального состояния восстановления.<fold_right>является правоассоциативной складкой с использованием двоичной операции. Учитывая структуру, содержащую<x1, ..., xn>, функцию<f>и факультативное начальное состояние,<fold_right>применяется<f>следующим образом.

f(x1, f(x2, f(x3, f(x4, ... f(xn-1, xn) ... )))) // without state
f(x1, f(x2, f(x3, f(x4, ... f(xn, state) ... )))) // with state
Note
It is worth noting that the order in which the binary function should expect its arguments is reversed from fold_left.

Когда структура пуста, могут возникнуть две вещи. Если первоначальное состояние было обеспечено, оно возвращается как есть. В противном случае, если используется версия функции без состояния, срабатывает ошибка. Когда конструкция содержит один элемент и используется версия функции без состояния, этот единственный элемент возвращается как есть.

Signature

<Foldable><F>и факультативное начальное состояние метки<S>, подписи для<fold_right>являются

\[ \mathtt{fold\_right} : F(T) \times S \times (T \times S \to S) \to S \]

для варианта с начальным состоянием, и

\[ \mathtt{fold\_right} : F(T) \times (T \times T \to T) \to T \]

вариант без начального состояния.

Parameters
xsСтруктура складывается.
stateНачальное значение, используемое для складывания.
fБинарная функция называется<f(x, state)>, где<state>является результатом, накопленным до сих пор, и<x>является элементом в структуре. Для правильных складок без начального состояния функция называется<f(x1, x2)>, где<x1>и<x2>являются элементами структуры.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <sstream>
#include <string>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
int main() {
auto f = [=](auto element, std::string s) {
return "f(" + to_string(element) + ", " + s + ")";
};
// with an initial state
hana::fold_right(hana::make_tuple(1, '2', 3.0, 4), "5", f)
==
"f(1, f(2, f(3, f(4, 5))))"
);
// without initial state
hana::fold_right(hana::make_tuple(1, '2', 3.0, 4, "5"), f)
==
"f(1, f(2, f(3, f(4, 5))))"
);
}
constexpr auto boost::hana::for_each

<#include <boost/hana/fwd/for_each.hpp>>

Initial value:
= [](auto&& xs, auto&& f) -> void {
tag-dispatched;
}

Выполняйте действие на каждый элемент складного, каждый раз отбрасывая результат. Итерация выполняется слева направо, то есть в том же порядке, что и при использовании<fold_left>. Если структура не конечна, этот метод не завершится.

Parameters
xsСтруктура должна повторяться.
fФункция, называемая<f(x)>для каждого элемента<x>структуры. 126, что бы это ни было, игнорируется.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <sstream>
namespace hana = boost::hana;
int main() {
std::stringstream ss;
hana::for_each(hana::make_tuple(0, '1', "234", 5.5), [&](auto x) {
ss << x << ' ';
});
BOOST_HANA_RUNTIME_CHECK(ss.str() == "0 1 234 5.5 ");
}
constexpr auto boost::hana::fuse

<#include <boost/hana/fwd/fuse.hpp>>

Initial value:
= [](auto&& f) {
return [perfect-capture](auto&& xs) -> decltype(auto) {
return unpack(forwarded(xs), forwarded(f));
};
}
constexpr auto unpack
Invoke a function with the elements of a Foldable as arguments.Given a function and a foldable struct...
Definition: unpack.hpp:79
constexpr auto capture
Create a function capturing the given variables.
Definition: capture.hpp:45

Преобразовать функцию, принимающую множество аргументов, в функцию, которая может быть вызвана временем компиляции<Foldable>.

Эта функция предусмотрена для удобства как другой способ вызова<unpack>. В частности,<fuse(f)>является функцией, которая

fuse(f)(foldable) == unpack(foldable, f)
== f(x...)

где<x...>— элементы в складной. Эта функция полезна, когда вы хотите создать функцию, которая принимает складную, которая еще не известна.

Note
This function is not tag-dispatched; customize unpack instead.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
auto tie = [](auto& ...vars) {
return hana::fuse([&vars...](auto ...values) {
// Using an initializer list to sequence the assignments.
int dummy[] = {0, ((void)(vars = values), 0)...};
(void)dummy;
});
};
int main() {
int a = 0;
char b = '\0';
double c = 0;
tie(a, b, c)(hana::make_tuple(1, '2', 3.3));
BOOST_HANA_RUNTIME_CHECK(a == 1 && b == '2' && c == 3.3);
}
constexpr auto boost::hana::length

<#include <boost/hana/fwd/length.hpp>>

Initial value:
= [](auto const& xs) {
return tag-dispatched;
}

Верните количество элементов в складную структуру. Учитывая<Foldable><xs>,<length(xs)>должен вернуть объект неподписанного интегрального типа, или<IntegralConstant>удерживающий такой объект, который представляет собой количество элементов в структуре.

Note
Since only compile-time Foldables are supported in the library right now, length must always return an IntegralConstant.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTANT_CHECK(hana::length(hana::make_tuple()) == hana::size_c<0>);
BOOST_HANA_CONSTANT_CHECK(hana::length(hana::make_tuple(1, '2', 3.0)) == hana::size_c<3>);
BOOST_HANA_CONSTANT_CHECK(hana::length(hana::nothing) == hana::size_c<0>);
BOOST_HANA_CONSTANT_CHECK(hana::length(hana::just('x')) == hana::size_c<1>);
}
constexpr auto boost::hana::maximum

<#include <boost/hana/fwd/maximum.hpp>>

Initial value:
= [](auto&& xs[, auto&& predicate]) -> decltype(auto) {
return tag-dispatched;
}

Возвращает наибольший элемент непустой структуры по отношению к<predicate>, по умолчанию<less>.Учитывая непустую структуру и необязательный бинарный предикат<less>по умолчанию,<maximum>возвращает наибольший элемент структуры, то есть элемент, который больше или равен любому другому элементу в структуре, согласно предикату.

Если структура содержит разнородные объекты, то предикат должен возвращать время компиляции<Logical>. Если предикат не предусмотрен, элементы в структуре должны быть упорядоченными, или упорядоченными во времени компиляции, если структура неоднородна.

Signature

Дано Складное<F>, Логическое<Bool>и предикат \(\mathtt{pred} : T \times T \to Bool \),<maximum>имеет следующие подписи. Для варианта с заданным предикатом,

\[ \mathtt{maximum} : F(T) \times (T \times T \to Bool) \to T \]

Для варианта без пользовательского предиката требуется<T>быть упорядоченным. Подпись тогда

\[ \mathtt{maximum} : F(T) \to T \]

Parameters
xsСтруктура, чтобы найти самый большой элемент.
predicateФункция называется<predicate(x, y)>, где<x>и<y>являются элементами структуры.<predicate>должно быть строгое слабое упорядочивание на элементах структуры и его возвращаемое значение должно быть логическим, или компиляционно-временным логическим, если структура неоднородна.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
// without a predicate
hana::maximum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>) == hana::int_c<9>
);
// with a predicate
auto smallest = hana::maximum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>, [](auto x, auto y) {
return x > y; // order is reversed!
});
BOOST_HANA_CONSTANT_CHECK(smallest == hana::int_c<-4>);
}

Syntactic sugar (maximum.by)

<maximum>можно назвать третьим способом, который обеспечивает хороший синтаксис, особенно при работе с комбинатором<ordering>:

maximum.by(predicate, xs) == maximum(xs, predicate)
maximum.by(predicate) == maximum(-, predicate)

где<maximum(-, predicate)>обозначает частичное применение<maximum>к<predicate>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
static_assert(
hana::maximum.by(hana::ordering(hana::length), hana::make_tuple(
hana::make_tuple(),
hana::make_tuple(1, '2'),
hana::make_tuple(3.3, nullptr, 4)
))
== hana::make_tuple(3.3, nullptr, 4)
, "");
}

Tag dispatching

Как непредикативная версия, так и предикативная версия<maximum>являются методами, распределенными по тегам, и, следовательно, они могут быть настроены независимо. Одна из причин этого заключается в том, что некоторые структуры способны обеспечить гораздо более эффективную реализацию<maximum>при использовании<less>предиката. Ниже приведены различные версии<maximum>:

maximum(xs, pred) -> maximum_pred_impl<tag of xs>::apply(xs, pred)

Также обратите внимание, что<maximum.by>сам по себе не является таг-диспетчером, поскольку это просто синтаксический сахар для вызова соответствующего<maximum>.

constexpr auto boost::hana::minimum

<#include <boost/hana/fwd/minimum.hpp>>

Initial value:
= [](auto&& xs[, auto&& predicate]) -> decltype(auto) {
return tag-dispatched;
}

Возвращает наименьший элемент непустой структуры по отношению к<predicate>, по умолчанию<less>.Учитывая непустую структуру и необязательный бинарный предикат<less>по умолчанию,<minimum>возвращает наименьший элемент структуры, т.е. элемент, который меньше или равен любому другому элементу в структуре, согласно предикату.

Если структура содержит разнородные объекты, то предикат должен возвращать время компиляции<Logical>. Если предикат не предусмотрен, элементы в структуре должны быть упорядоченными, или упорядоченными во времени компиляции, если структура неоднородна.

Signature

<Foldable><F>, логический<Bool>и предикат \(\mathtt{pred} : T \times T \to Bool \),<minimum>имеет следующие подписи. Для варианта с заданным предикатом,

\[ \mathtt{minimum} : F(T) \times (T \times T \to Bool) \to T \]

Для варианта без пользовательского предиката требуется<T>быть упорядоченным. Подпись тогда

\[ \mathtt{minimum} : F(T) \to T \]

Parameters
xsСтруктура для поиска наименьшего элемента.
predicateФункция называется<predicate(x, y)>, где<x>и<y>являются элементами структуры.<predicate>должно быть строгое слабое упорядочивание на элементах структуры и его возвращаемое значение должно быть логическим, или компиляционно-временным логическим, если структура неоднородна.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
// without a predicate
hana::minimum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>) == hana::int_c<-4>
);
// with a predicate
auto largest = hana::minimum(hana::tuple_c<int, -1, 0, 2, -4, 6, 9>, [](auto x, auto y) {
return x > y; // order is reversed!
});
BOOST_HANA_CONSTANT_CHECK(largest == hana::int_c<9>);
}

Syntactic sugar (minimum.by)

<minimum>можно назвать третьим способом, который обеспечивает хороший синтаксис, особенно при работе с комбинатором<ordering>:

minimum.by(predicate, xs) == minimum(xs, predicate)
minimum.by(predicate) == minimum(-, predicate)

где<minimum(-, predicate)>обозначает частичное применение<minimum>к<predicate>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
hana::minimum.by(hana::ordering(hana::length), hana::make_tuple(
hana::make_tuple(),
hana::make_tuple(1, '2'),
hana::make_tuple(3.3, nullptr, 4)
))
== hana::make_tuple()
);
}

Tag dispatching

Как непредикативная версия, так и предикативная версия<minimum>являются методами, распределенными по тегам, и, следовательно, они могут быть настроены независимо. Одна из причин этого заключается в том, что некоторые структуры способны обеспечить гораздо более эффективную реализацию<minimum>при использовании предиката<less>. Вот как отправляются различные версии<minimum>:

minimum(xs, pred) -> minimum_pred_impl<tag of xs>::apply(xs, pred)

Также обратите внимание, что<minimum.by>не маркируется отдельно, поскольку это просто синтаксический сахар для вызова соответствующего<minimum>.

template<typename M >
constexpr auto boost::hana::monadic_fold_left

<#include <boost/hana/fwd/monadic_fold_left.hpp>>

Initial value:
= [](auto&& xs[, auto&& state], auto&& f) -> decltype(auto) {
return tag-dispatched;
}

Монадическое левое сложение структуры с бинарной операцией и факультативным начальным состоянием редукции.

Note
This assumes the reader to be accustomed to non-monadic left-folds as explained by hana::fold_left, and to have read the primer on monadic folds.

<monadic_fold_left<M>>является левоассоциативной монадической складкой. При наличии<Foldable>с линеаризацией<[x1, ..., xn]>, функции<f>и факультативного начального состояния<monadic_fold_left<M>>применяется<f>следующим образом:

// with state
((((f(state, x1) | f(-, x2)) | f(-, x3)) | ...) | f(-, xn))
// without state
((((f(x1, x2) | f(-, x3)) | f(-, x4)) | ...) | f(-, xn))

где<f(-, xk)>обозначает частичное применение<f>к<xk>, а<|>является просто операторской версией монадического<chain>.

Когда структура пуста, может произойти одна из двух вещей. Если первоначальное состояние было обеспечено, оно поднимается к данной Монаде и возвращается как есть. В противном случае, если используется версия функции без состояния, срабатывает ошибка. Когда конструкция содержит один элемент и используется негосударственная версия функции, этот единственный элемент поднимается в данную Монаду и возвращается как есть.

Signature

Учитывая<Monad><M>,<Foldable><F>, начальное состояние тега<S>и функцию \(f : S \times T \to M(S)\), подписи<monadic_fold_left<M>>являются

\[ \mathtt{monadic\_fold\_left}_M : F(T) \times S \times (S \times T \to M(S)) \to M(S) \]

для версии с начальным состоянием и

\[ \mathtt{monadic\_fold\_left}_M : F(T) \times (T \times T \to M(T)) \to M(T) \]

Для версии без начального состояния.

Template Parameters
MМонада представляет собой монадический контекст, в котором происходит складка. Тип возврата<f>должен быть в этой Монаде.
Parameters
xsСтруктура складывается.
stateНачальное значение, используемое для складывания. Если структура пуста, это значение поднимается до<M>Монады, а затем возвращается как есть.
fБинарная функция называется<f(state, x)>, где<state>является результатом, накопленным до сих пор, и<x>является элементом в структуре. Функция должна возвращать свой результат внутри<M>Монады.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <type_traits>
namespace hana = boost::hana;
auto builtin_common_t = hana::sfinae([](auto&& t, auto&& u) -> decltype(hana::type_c<
std::decay_t<decltype(true ? hana::traits::declval(t) : hana::traits::declval(u))>
>) { return {}; });
template <typename ...T>
struct common_type { };
template <typename T, typename U>
struct common_type<T, U>
: std::conditional_t<std::is_same<std::decay_t<T>, T>{} &&
std::is_same<std::decay_t<U>, U>{},
decltype(builtin_common_t(hana::type_c<T>, hana::type_c<U>)),
common_type<std::decay_t<T>, std::decay_t<U>>
>
{ };
template <typename T1, typename ...Tn>
struct common_type<T1, Tn...>
: decltype(hana::monadic_fold_left<hana::optional_tag>(
hana::tuple_t<Tn...>,
hana::type_c<std::decay_t<T1>>,
hana::sfinae(hana::metafunction<common_type>)
))
{ };
template <typename ...Ts>
using common_type_t = typename common_type<Ts...>::type;
static_assert(std::is_same<
common_type_t<char, short, char, short>,
int
>{}, "");
static_assert(std::is_same<
common_type_t<char, double, short, char, short, double>,
double
>{}, "");
static_assert(std::is_same<
common_type_t<char, short, float, short>,
float
>{}, "");
static_assert(
hana::sfinae(hana::metafunction<common_type>)(
hana::type_c<int>, hana::type_c<int>, hana::type_c<int*>
) == hana::nothing
, "");
int main() { }
template<typename M >
constexpr auto boost::hana::monadic_fold_right

<#include <boost/hana/fwd/monadic_fold_right.hpp>>

Initial value:
= [](auto&& xs[, auto&& state], auto&& f) -> decltype(auto) {
return tag-dispatched;
}

Монадическая правая часть структуры с бинарной операцией и факультативным начальным состоянием восстановления.

Note
This assumes the reader to be accustomed to non-monadic right-folds as explained by hana::fold_right, and to have read the primer on monadic folds.

<monadic_fold_right<M>>является правоассоциативной монадической складкой. Учитывая структуру, содержащую<x1, ..., xn>, функцию<f>и факультативное начальное состояние,<monadic_fold_right<M>>применяется<f>следующим образом:

// with state
(f(x1, -) | (f(x2, -) | (f(x3, -) | (... | f(xn, state)))))
// without state
(f(x1, -) | (f(x2, -) | (f(x3, -) | (... | f(xn-1, xn)))))

где<f(xk, -)>означает частичное применение<f>к<xk>, и<|>является только операторской версией монадического<chain>. Стоит отметить, что порядок, в котором двоичная функция должна ожидать своих аргументов, обратный<monadic_fold_left<M>>.

Когда структура пуста, может произойти одна из двух вещей. Если первоначальное состояние было обеспечено, оно поднимается к данной Монаде и возвращается как есть. В противном случае, если используется версия функции без состояния, срабатывает ошибка. Когда конструкция содержит один элемент и используется негосударственная версия функции, этот единственный элемент поднимается в данную Монаду и возвращается как есть.

Signature

Учитывая<Monad><M>,<Foldable><F>, начальное состояние тега<S>и функцию \(f : T \times S \to M(S)\), подписи<monadic_fold_right<M>>являются

\[ \mathtt{monadic\_fold\_right}_M : F(T) \times S \times (T \times S \to M(S)) \to M(S) \]

для версии с начальным состоянием и

\[ \mathtt{monadic\_fold\_right}_M : F(T) \times (T \times T \to M(T)) \to M(T) \]

Для версии без начального состояния.

Template Parameters
MМонада представляет собой монадический контекст, в котором происходит складка. Тип возврата<f>должен быть в этой Монаде.
Parameters
xsСтруктура складывается.
stateНачальное значение, используемое для складывания. Если структура пуста, это значение поднимается до<M>Монады, а затем возвращается как есть.
fБинарная функция называется<f(x, state)>, где<state>является результатом, накопленным до сих пор, и<x>является элементом в структуре. Функция должна возвращать свой результат внутри Монады<M>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTEXPR_LAMBDA auto safe_div = [](auto x, auto y) {
return hana::eval_if(y == hana::int_c<0>,
hana::make_lazy(hana::nothing),
[=](auto _) {
return hana::just(_(x) / y);
}
);
};
// with an initial state
hana::monadic_fold_right<hana::optional_tag>(
hana::tuple_c<int, 1000, 8, 4>, hana::int_c<2>, safe_div
)
==
hana::just(hana::int_c<1000> / (hana::int_c<8> / (hana::int_c<4> / hana::int_c<2>)))
);
hana::monadic_fold_right<hana::optional_tag>(
hana::tuple_c<int, 1000, 8, 4>, hana::int_c<0>, safe_div
)
==
hana::nothing
);
// without an initial state
hana::monadic_fold_right<hana::optional_tag>(
hana::tuple_c<int, 1000, 8, 4, 2>, safe_div
)
==
hana::just(hana::int_c<1000> / (hana::int_c<8> / (hana::int_c<4> / hana::int_c<2>)))
);
hana::monadic_fold_right<hana::optional_tag>(
hana::tuple_c<int, 1000, 8, 4, 0>, safe_div
)
==
hana::nothing
);
}
constexpr auto boost::hana::product = see documentation

<#include <boost/hana/fwd/product.hpp>>

Вычислить произведение чисел структуры. В более общем плане<product>будет принимать любую складную структуру, содержащую объекты, образующие кольцо, и уменьшать их с помощью двоичной операции кольца. Начальное состояние складывания — это тождество операции Кольца. Иногда необходимо указать Кольцо для использования; это возможно с помощью<product<R>>. Если Кольцо не указано, в структуре будет использоваться Кольцо, образованное элементами, которые оно содержит (если оно знает это), или<integral_constant_tag<int>>. Следовательно.

product<R>(xs) = fold_left(xs, one<R or inferred Ring>(), mult)
product<> = product<integral_constant_tag<int>>

Для чисел это будет просто вычислять произведение чисел в структуре<xs>.

Note
The elements of the structure are not actually required to be in the same Ring, but it must be possible to perform mult on any two adjacent elements of the structure, which requires each pair of adjacent element to at least have a common Ring embedding. The meaning of "adjacent" as used here is that two elements of the structure x and y are adjacent if and only if they are adjacent in the linearization of that structure, as documented by the Iterable concept.
See the documentation for sum to understand why the Ring must sometimes be specified explicitly.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
hana::product<>(hana::make_range(hana::int_c<1>, hana::int_c<6>)) == hana::int_c<1 * 2 * 3 * 4 * 5>
);
hana::product<>(hana::make_tuple(1, hana::int_c<3>, hana::long_c<-5>, 9)) == 1 * 3 * -5 * 9
);
hana::product<unsigned long>(hana::make_tuple(2ul, 3ul)) == 6ul
);
}
constexpr auto boost::hana::reverse_fold

<#include <boost/hana/fwd/reverse_fold.hpp>>

Initial value:
= [](auto&& xs[, auto&& state], auto&& f) -> decltype(auto) {
return fold_right(forwarded(xs), forwarded(state), flip(forwarded(f)));
}
constexpr auto fold_right
Right-fold of a structure using a binary operation and an optional initial reduction state...
Definition: fold_right.hpp:73
constexpr auto flip
Invoke a function with its two first arguments reversed.
Definition: flip.hpp:31

<reverse_fold>в Boost.Fusion и Boost. MPL. Этот метод имеет ту же семантику, что и<reverse_fold>. Фьюжн и буст. MPL, с расширением, что начальное состояние не требуется. Этот метод эквивалентен<fold_right>, за исключением того, что функция накопления должна принимать свои аргументы в обратном порядке, чтобы соответствовать порядку, используемому в Fusion. Другими словами,

reverse_fold(sequence, state, f) == fold_right(sequence, state, flip(f))
reverse_fold(sequence, f) == fold_right(sequence, flip(f))
Note
This method is a convenience alias to fold_right. As an alias, reverse_fold is not tag-dispatched on its own and fold_right should be customized instead.

Signature

<Foldable><F>и факультативное начальное состояние метки<S>, подписи для<reverse_fold>являются

\[ \mathtt{reverse\_fold} : F(T) \times S \times (S \times T \to S) \to S \]

для варианта с начальным состоянием, и

\[ \mathtt{reverse\_fold} : F(T) \times (T \times T \to T) \to T \]

вариант без начального состояния.

Parameters
xsСтруктура складывается.
stateНачальное значение, используемое для складывания.
fБинарная функция называется<f(state, x)>, где<state>является результатом, накопленным до сих пор, и<x>является элементом в структуре. Для обратных складок без начального состояния функция называется<f(x1, x2)>, где<x1>и<x2>являются элементами структуры.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <sstream>
#include <string>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
int main() {
auto f = [=](std::string s, auto element) {
return "f(" + s + ", " + to_string(element) + ")";
};
// With an initial state
hana::reverse_fold(hana::make_tuple(1, '2', 3.0, 4), "5", f)
==
"f(f(f(f(5, 4), 3), 2), 1)"
);
// Without an initial state
hana::reverse_fold(hana::make_tuple(1, '2', 3.0, 4, "5"), f)
==
"f(f(f(f(5, 4), 3), 2), 1)"
);
}
constexpr auto boost::hana::size = hana::length

<#include <boost/hana/fwd/size.hpp>>

Эквивалент<length>; предусмотрен для согласования со стандартной библиотекой. Этот метод является псевдонимом<length>, предназначенным для удобства и согласованности со стандартной библиотекой. В качестве псевдонима<size>не отправляется тег сам по себе и<length>должен быть настроен вместо этого.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTANT_CHECK(hana::size(hana::make_tuple()) == hana::size_c<0>);
BOOST_HANA_CONSTANT_CHECK(hana::size(hana::make_tuple(1, '2', 3.0)) == hana::size_c<3>);
BOOST_HANA_CONSTANT_CHECK(hana::size(hana::nothing) == hana::size_c<0>);
BOOST_HANA_CONSTANT_CHECK(hana::size(hana::just('x')) == hana::size_c<1>);
}
constexpr auto boost::hana::sum = see documentation

<#include <boost/hana/fwd/sum.hpp>>

Вычислите сумму чисел структуры. В более общем плане<sum>берет любую складную структуру, содержащую объекты, образующие Моноид, и уменьшает их с помощью двоичной операции Моноида. Начальным состоянием для складывания является идентичность Моноида. Иногда необходимо указать Моноид для использования; это возможно с помощью<sum<M>>. Если Моноид не указан, в структуре будет использоваться Моноид, образованный элементами, которые он содержит (если он знает это), или<integral_constant_tag<int>>иначе. Следовательно.

sum<M>(xs) = fold_left(xs, zero<M or inferred Monoid>(), plus)
sum<> = sum<integral_constant_tag<int>>

Для чисел это будет просто вычислять сумму чисел в структуре<xs>.

Note
The elements of the structure are not actually required to be in the same Monoid, but it must be possible to perform plus on any two adjacent elements of the structure, which requires each pair of adjacent element to at least have a common Monoid embedding. The meaning of "adjacent" as used here is that two elements of the structure x and y are adjacent if and only if they are adjacent in the linearization of that structure, as documented by the Iterable concept.

Why must we sometimes specify the Monoid by using sum<M>?

Это связано с тем, что метки последовательности, такие как<tuple_tag>, не параметризированы (по дизайну). Следовательно, мы не знаем, какие объекты находятся в последовательности, поэтому мы не можем знать значение<0>, какой тип должен быть возвращен, когда последовательность пуста. Поэтому тип<0>для возврата в пустом случае должен быть указан явно. Другие складные структуры, такие как<hana::range>s, будут игнорировать предложенный Моноид, потому что они знают метки объектов, которые они содержат. Это непоследовательное поведение является ограничением существующего дизайна с непараметризированными тегами, но пока у нас нет хорошего решения.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::sum<>(hana::make_range(hana::int_c<1>, hana::int_c<6>)) == hana::int_c<15>);
static_assert(hana::sum<>(hana::make_tuple(1, hana::int_c<3>, hana::long_c<-5>, 9)) == 8, "");
static_assert(hana::sum<unsigned long>(hana::make_tuple(1ul, 3ul)) == 4ul, "");
int main() { }
constexpr auto boost::hana::unpack

<#include <boost/hana/fwd/unpack.hpp>>

Initial value:
= [](auto&& xs, auto&& f) -> decltype(auto) {
return tag-dispatched;
}

Вызовите функцию с элементами Foldable в качестве аргументов. Учитывая функцию и складную структуру, длина которой может быть известна во время компиляции,<unpack>вызывает функцию с содержанием этой структуры. Другими словами,<unpack(xs, f)>эквивалентно<f(x...)>, где<x...>являются элементами структуры. Длина структуры должна быть известна во время компиляции, потому что версия<f>'s<operator()>, которая будет компилироваться, зависит от количества аргументов, с которыми она называется, которые должны быть известны во время компиляции.

Чтобы создать функцию, которая принимает складные, а не вариадные аргументы, см.<fuse>.

Parameters
xsСтруктура расширяется до функции.
fФункция, которая вызывается как<f(x...)>, где<x...>являются элементами структуры, если они были линеаризованы с<to<tuple_tag>>.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
namespace hana = boost::hana;
int main() {
BOOST_HANA_CONSTEXPR_LAMBDA auto add = [](auto x, auto y, auto z) {
return x + y + z;
};
BOOST_HANA_CONSTEXPR_CHECK(hana::unpack(hana::make_tuple(1, 2, 3), add) == 6);
}

Rationale: unpack's name and parameter order

Было предложено несколько раз, чтобы<unpack>было названо<apply>вместо этого, и чтобы порядок параметров был отменен, чтобы соответствовать тому изпредложенного std::apply функции. Однако название<apply>уже используется для обозначения нормального функционального приложения, использование которого согласуется с библиотекой Boost MPL и с остальным миром, особенно с сообществом функционального программирования. Кроме того, автор этой библиотеки считает, что предложенное<std::apply>имеет как неудачное имя, так и неудачный порядок параметров. Действительно, принятие функции в качестве первого аргумента означает, что использование<std::apply>с функцией лямбды выглядит так:

std::apply([](auto ...args) {
use(args...);
}, tuple);

Это, несомненно, уродливо из-за отставания<, tuple)>на последней линии. С другой стороны, принятие функции в качестве второго аргумента позволяет писать.

hana::unpack(tuple, [](auto ...args) {
use(args...);
});

который выглядит намного приятнее. Из-за этих наблюдений автор этой библиотеки считает оправданным использовать<unpack>вместо<apply>и использовать порядок нормальных параметров.

Статья Boost.Hana: Foldable раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-07-05 06:38:23/0.013057947158813/0