示例#1
0
namespace boost { namespace hana {
    //! @ingroup group-functional
    //! Invoke `f` with `x...` as arguments.
    //!
    //!
    //! @param f
    //! A function called as `f(x...)` whose result is the return
    //! value of `apply`.
    //!
    //! @param x...
    //! The arguments to call `f` with. The number of `x...` must match the
    //! arity of `f`.
    //!
    //!
    //! ### Example
    //! @snippet example/functional/apply.cpp main
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto apply = [](auto&& f, auto&& ...x) -> decltype(auto) {
        return forwarded(f)(forwarded(x)...);
    };
#else
    struct _apply {
        template <typename F, typename ...Args>
        constexpr decltype(auto) operator()(F&& f, Args&& ...args) const {
            return detail::std::forward<F>(f)(
                detail::std::forward<Args>(args)...
            );
        }
    };

    constexpr _apply apply{};
#endif
}} // end namespace boost::hana
示例#2
0
void QCopServerPrivate::init()
{
    QCopChannel *appChannel =
        new QCopChannel(QLatin1String("QPE/Application/*"), this);
    connect(appChannel, SIGNAL(connected()), QCopThreadData::instance()->server, SIGNAL(ready()));
    connect(appChannel, SIGNAL(forwarded(QString,QByteArray,QString)),
            this, SLOT(forwarded(QString,QByteArray,QString)));
}
/* if child is forwarded, get the forwarding address */
static ggc_size_t *getCorrectChild(ggc_size_t *child)
{
    if (child == NULL) {
        return NULL;
    }
    else {
        child = (ggc_size_t *)((ggc_size_t)child & ~7);
        if (forwarded(child)) {
            child = forwardingAddress(child);
        }
        return child;
    }
}
示例#4
0
namespace boost { namespace hana {
    //! @ingroup group-datatypes
    //! Stripped down version of `hana::tuple`.
    //!
    //! Whereas `hana::tuple` aims to provide an interface somewhat close to a
    //! `std::tuple`, `basic_tuple` provides the strict minimum required to
    //! implement a closure with maximum compile-time efficiency.
    //!
    //!
    //! Modeled concepts
    //! ----------------
    //! For now, `basic_tuple` only models the `Foldable` concept. More will
    //! be added in the future, and `basic_tuple` will eventually model
    //! everything that `hana::tuple` models.
    template <typename ...Xs>
    struct basic_tuple;

    //! Tag representing `hana::basic_tuple`.
    //! @relates hana::basic_tuple
    struct basic_tuple_tag { };

#ifdef BOOST_HANA_DOXYGEN_INVOKED
    //! Function object for creating a `basic_tuple`.
    //! @relates hana::basic_tuple
    //!
    //! Given zero or more objects `xs...`, `make<basic_tuple_tag>` returns a
    //! new `basic_tuple` containing those objects. The elements are held by
    //! value inside the resulting tuple, and they are hence copied or moved
    //! in. This is analogous to `std::make_tuple` for creating `basic_tuple`s.
    //!
    //!
    //! Example
    //! -------
    //! @include example/basic_tuple/make.cpp
    template <>
    constexpr auto make<basic_tuple_tag> = [](auto&& ...xs) {
        return basic_tuple<std::decay_t<decltype(xs)>...>{forwarded(xs)...};
    };
#endif

    //! Alias to `make<basic_tuple_tag>`; provided for convenience.
    //! @relates hana::basic_tuple
    //!
    //!
    //! Example
    //! -------
    //! @include example/basic_tuple/make.cpp
    constexpr auto make_basic_tuple = make<basic_tuple_tag>;
}} // end namespace boost::hana
示例#5
0
/* Cheney collector */
static void gc_copy_forward(Ptr *p)
{
    unsigned int tag = TAG(*p);
    if (tag == number_tag || tag == immed_tag || tag == float_tag) { return; }  /* number or immediate or float -> ignore */
    Ptr *obj = OBJ(*p);
    if (obj == 0) { return; }                                                   /* null pointer -> ignore */
    if (forwarded(obj)) {   /* update pointer with forwarding info */
        LOG("U%x", tag);
        *p = UNTAG(*obj) | tag;
    } else {                /* copy and forward object */
        LOG("C%x", tag);
        unsigned int size = object_size(obj);
        memcpy(gc_free, obj, size);
        set_forward(obj, PTR(gc_free));
        *p = PTR(gc_free) | tag;
        gc_free += size;
    }
}
static void pushIfNeedWorklist(ggc_size_t **loc, char needToRemember)
{
    /* save some unnecessary pushes here */
	if (*loc != NULL && (GEN_OF(*loc) != GEN_OF_OLD)) {
        if (GEN_OF(*loc) == GEN_OF_B1TO && !isMarked(*loc)) {
            return;
        }
		if (forwarded(*loc)) {
			ggc_size_t *toRef = forwardingAddress(*loc);
			*loc = toRef;
			if (needToRemember && (GEN_OF(toRef) != GEN_OF_OLD)) {
				setRememberSet((ggc_size_t *)loc);
			}
		}
		else {
			struct GGGGC_Worklist *node = (struct GGGGC_Worklist *)malloc(sizeof(struct GGGGC_Worklist));
		    node->loc = loc;
		    node->needToRemember = needToRemember;
		    node->next = worklist->next;
		    worklist->next = node;
		}
	}
}
    //! @code
    //!     partial(f, x...)(y...) == f(x..., y...)
    //! @endcode
    //!
    //! @note
    //! The arity of `f` must match the total number of arguments passed to
    //! it, i.e. `sizeof...(x) + sizeof...(y)`.
    //!
    //!
    //! Example
    //! -------
    //! @include example/functional/partial.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto partial = [](auto&& f, auto&& ...x) {
        return [perfect-capture](auto&& ...y) -> decltype(auto) {
            return forwarded(f)(forwarded(x)..., forwarded(y)...);
        };
    };
#else
    template <typename Indices, typename F, typename ...X>
    struct partial_t;

    struct make_partial_t {
        struct secret { };
        template <typename F, typename ...X>
        constexpr partial_t<
            std::make_index_sequence<sizeof...(X)>,
            typename detail::decay<F>::type,
            typename detail::decay<X>::type...
        >
        operator()(F&& f, X&& ...x) const {
示例#8
0
文件: set.hpp 项目: zhangf911/hana
namespace boost { namespace hana {
    //! @ingroup group-datatypes
    //! Tag representing a basic unordered container requiring `Comparable`
    //! elements.
    //!
    //! Modeled concepts
    //! ----------------
    //! 1. `Comparable`\n
    //! Two sets are equal iff they contain the same elements, regardless of
    //! the order.
    //! @snippet example/set.cpp Comparable
    //!
    //! 2. Foldable\n
    //! Folding a `Set` is equivalent to folding the sequence of its values.
    //! However, note that the values are not required to be in any specific
    //! order, so using the folds provided here with an operation that is not
    //! both commutative and associative will yield non-deterministic behavior.
    //! @snippet example/set.cpp Foldable
    //!
    //! 3. Searchable\n
    //! The elements in a `Set` act as both its keys and its values. Since the
    //! elements of a set are unique, searching for an element will return
    //! either the only element which is equal to the searched value, or
    //! `nothing`. Also note that `operator[]` can be used instead of the
    //! `at_key` function.
    //! @snippet example/set.cpp Searchable
    //!
    //!
    //! Conversion from any `Foldable`
    //! ------------------------------
    //! Any `Foldable` structure can be converted into a `Set` by using
    //! `to<Set>`. The elements of the structure must all be compile-time
    //! `Comparable`. If the structure contains duplicate elements, only
    //! the first occurence will appear in the resulting set. More
    //! specifically, conversion from a `Foldable` is equivalent to
    //! @code
    //!     to<Set>(xs) == fold_left(xs, make<Set>(), insert)
    //! @endcode
    //!
    //! __Example__
    //! @snippet example/set.cpp from_Foldable
    struct Set { };

    //! Function object for creating a `Set`.
    //! @relates Set
    //!
    //! Given zero or more values `xs...`, `make<Set>` returns a `Set`
    //! containing those values. The values must all be compile-time
    //! `Comparable`, and no duplicate values may be provided. To create
    //! a `Set` from a sequence with possible duplicates, use `to<Set>`
    //! instead.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/set.cpp make<Set>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    template <>
    constexpr auto make<Set> = [](auto&& ...xs) {
        return unspecified-type{forwarded(xs)...};
    };
#endif

    template <typename ...Xs>
    struct _set;

    //! Equivalent to `make<Set>`; provided for convenience.
    //! @relates Set
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/set.cpp make_set
    constexpr auto make_set = make<Set>;

    //! Equivalent to `make<Set>`, provided for convenience.
    //! @relates Set
    constexpr auto set = make<Set>;

    //! Insert an element in a `Set`.
    //! @relates Set
    //!
    //! If the set already contains an element that compares equal, then
    //! nothing is done and the set is returned as is.
    //!
    //!
    //! @param set
    //! The set in which to insert a value.
    //!
    //! @param element
    //! The value to insert. It must be compile-time `Comparable`.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/set.cpp insert
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto insert = [](auto&& set, auto&& element) -> decltype(auto) {
        return tag-dispatched;
    };
#endif

    //! Remove an element from a `Set`.
    //! @relates Set
    //!
    //! Returns a new `Set` containing all the elements of the original,
    //! except the one comparing `equal` to the given element. If the set
    //! does not contain such an element, a new set equal to the original
    //! set is returned.
    //!
    //!
    //! @param set
    //! The set in which to remove a value.
    //!
    //! @param element
    //! The value to remove. It must be compile-time `Comparable`.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/set.cpp erase_key
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto erase_key = [](auto&& set, auto&& element) -> decltype(auto) {
        return tag-dispatched;
    };
#endif
}} // end namespace boost::hana
示例#9
0
文件: pair.hpp 项目: zussel/hana
namespace boost { namespace hana {
    //! @ingroup group-datatypes
    //! Generic container for two elements.
    //!
    //! `hana::pair` is conceptually the same as `std::pair`. However,
    //! `hana::pair` automatically compresses the storage of empty types,
    //! and as a result it does not have the `.first` and `.second` members.
    //! Instead, one must use the `hana::first` and `hana::second` free
    //! functions to access the elements of a pair.
    //!
    //!
    //! Modeled concepts
    //! ----------------
    //! 1. `Comparable`\n
    //! Two pairs `(x, y)` and `(x', y')` are equal if and only if both
    //! `x == x'` and `y == y'`.
    //! @include example/pair/comparable.cpp
    //!
    //! 2. `Orderable`\n
    //! Pairs are ordered as-if they were 2-element tuples, using a
    //! lexicographical ordering.
    //! @include example/pair/orderable.cpp
    //!
    //! 3. `Foldable`\n
    //! Folding a pair is equivalent to folding a 2-element tuple. In other
    //! words:
    //! @code
    //!     fold_left(make_pair(x, y), s, f) == f(f(s, x), y)
    //!     fold_right(make_pair(x, y), s, f) == f(x, f(y, s))
    //! @endcode
    //! Example:
    //! @include example/pair/foldable.cpp
    //!
    //! 4. `Product`\n
    //! The model of `Product` is the simplest one possible; the first element
    //! of a pair `(x, y)` is `x`, and its second element is `y`.
    //! @include example/pair/product.cpp
    template <typename First, typename Second>
    struct pair;

    //! Tag representing `hana::pair`.
    //! @relates hana::pair
    struct pair_tag { };

#ifdef BOOST_HANA_DOXYGEN_INVOKED
    //! Creates a `hana::pair` with the given elements.
    //! @relates hana::pair
    //!
    //!
    //! Example
    //! -------
    //! @include example/pair/make.cpp
    template <>
    constexpr auto make<pair_tag> = [](auto&& first, auto&& second)
        -> hana::pair<std::decay_t<decltype(first)>, std::decay_t<decltype(second)>>
    {
        return {forwarded(first), forwarded(second)};
    };
#endif

    //! Alias to `make<pair_tag>`; provided for convenience.
    //! @relates hana::pair
    //!
    //! Example
    //! -------
    //! @include example/pair/make.cpp
    constexpr auto make_pair = make<pair_tag>;
}} // end namespace boost::hana
示例#10
0
namespace boost { namespace hana {
    //! @ingroup group-functional
    //! Invokes a Callable with the given arguments.
    //!
    //! This is equivalent to [std::invoke][1] that will be added in C++17.
    //! However, `apply` is a function object instead of a function, which
    //! makes it possible to pass it to higher-order algorithms.
    //!
    //!
    //! @param f
    //! A [Callable][2] to be invoked with the given arguments.
    //!
    //! @param x...
    //! The arguments to call `f` with. The number of `x...` must match the
    //! arity of `f`.
    //!
    //!
    //! Example
    //! -------
    //! @include example/functional/apply.cpp
    //!
    //! [1]: http://en.cppreference.com/w/cpp/utility/functional/invoke
    //! [2]: http://en.cppreference.com/w/cpp/concept/Callable
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto apply = [](auto&& f, auto&& ...x) -> decltype(auto) {
        return forwarded(f)(forwarded(x)...);
    };
#else
    struct apply_t {
        template <typename F, typename... Args>
        constexpr auto operator()(F&& f, Args&&... args) const ->
            decltype(static_cast<F&&>(f)(static_cast<Args&&>(args)...))
        {
            return static_cast<F&&>(f)(static_cast<Args&&>(args)...);
        }

        template <typename Base, typename T, typename Derived>
        constexpr auto operator()(T Base::*pmd, Derived&& ref) const ->
            decltype(static_cast<Derived&&>(ref).*pmd)
        {
            return static_cast<Derived&&>(ref).*pmd;
        }

        template <typename PMD, typename Pointer>
        constexpr auto operator()(PMD pmd, Pointer&& ptr) const ->
            decltype((*static_cast<Pointer&&>(ptr)).*pmd)
        {
            return (*static_cast<Pointer&&>(ptr)).*pmd;
        }

        template <typename Base, typename T, typename Derived, typename... Args>
        constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const ->
            decltype((static_cast<Derived&&>(ref).*pmf)(static_cast<Args&&>(args)...))
        {
            return (static_cast<Derived&&>(ref).*pmf)(static_cast<Args&&>(args)...);
        }

        template <typename PMF, typename Pointer, typename... Args>
        constexpr auto operator()(PMF pmf, Pointer&& ptr, Args&& ...args) const ->
            decltype(((*static_cast<Pointer&&>(ptr)).*pmf)(static_cast<Args&&>(args)...))
        {
            return ((*static_cast<Pointer&&>(ptr)).*pmf)(static_cast<Args&&>(args)...);
        }
    };

    constexpr apply_t apply{};
#endif
}} // end namespace boost::hana
示例#11
0
文件: pair.hpp 项目: zhangf911/hana
namespace boost { namespace hana {
    //! @ingroup group-datatypes
    //! Tag representing a generic container of two elements.
    //!
    //! A `Pair` is essentially equivalent to a `std::pair`, which can also
    //! be seen as a 2-element tuple. `Pair`s are useful in some contexts
    //! where a tuple would be too much, like returning two elements from a
    //! function.
    //!
    //!
    //! Modeled concepts
    //! ----------------
    //! 1. `Comparable`\n
    //! Two pairs `(x, y)` and `(x', y')` are equal if and only if both
    //! `x == x'` and `y == y'`.
    //! @snippet example/pair.cpp comparable
    //!
    //! 2. `Orderable`\n
    //! Pairs are ordered as-if they were 2-element tuples, using a
    //! lexicographical ordering.
    //! @snippet example/pair.cpp orderable
    //!
    //! 3. `Foldable`\n
    //! Folding a `Pair` is equivalent to folding a 2-element tuple. In other
    //! words:
    //! @code
    //!     fold_left(make_pair(x, y), s, f) == f(f(s, x), y)
    //!     fold_right(make_pair(x, y), s, f) == f(x, f(y, s))
    //! @endcode
    //! Example:
    //! @snippet example/pair.cpp foldable
    //!
    //! 4. `Product`\n
    //! The model of `Product` is the simplest one possible; the first element
    //! of a pair `(x, y)` is `x`, and its second element is `y`.
    //! @snippet example/pair.cpp product
    struct Pair { };

    template <typename First, typename Second>
    struct _pair;

#ifdef BOOST_HANA_DOXYGEN_INVOKED
    //! Creates a `Pair` with the given elements.
    //! @relates Pair
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/pair.cpp make<Pair>
    template <>
    constexpr auto make<Pair> = [](auto&& first, auto&& second)
        -> _pair<std::decay_t<decltype(first)>, std::decay_t<decltype(second)>>
    {
        return {forwarded(first), forwarded(second)};
    };
#endif

    //! Alias to `make<Pair>`; provided for convenience.
    //! @relates Pair
    //!
    //! Example
    //! -------
    //! @snippet example/pair.cpp make_pair
    constexpr auto make_pair = make<Pair>;
}} // end namespace boost::hana
示例#12
0
文件: set.hpp 项目: BeiLuoShiMen/hana
namespace boost { namespace hana {
    //! @ingroup group-datatypes
    //! Basic unordered container requiring compile-time `Comparable` elements.
    //!
    //! A set is an unordered container that can hold heterogeneous objects.
    //! As usual, a set requires (and ensures) that no duplicates are present.
    //!
    //! @note
    //! The actual representation of a `hana::set` is implementation-defined.
    //! In particular, one should not take for granted the order of the
    //! template parameters and the presence of any constructor or assignment
    //! operator. The canonical way of creating a `hana::set` is through
    //! `hana::make_set`.
    //!
    //!
    //! Modeled concepts
    //! ----------------
    //! 1. `Comparable`\n
    //! Two sets are equal iff they contain the same elements, regardless of
    //! the order.
    //! @include example/set/comparable.cpp
    //!
    //! 2. Foldable\n
    //! Folding a set is equivalent to folding the sequence of its values.
    //! However, note that the values are not required to be in any specific
    //! order, so using the folds provided here with an operation that is not
    //! both commutative and associative will yield non-deterministic behavior.
    //! @include example/set/foldable.cpp
    //!
    //! 3. Searchable\n
    //! The elements in a set act as both its keys and its values. Since the
    //! elements of a set are unique, searching for an element will return
    //! either the only element which is equal to the searched value, or
    //! `nothing`. Also note that `operator[]` can be used instead of the
    //! `at_key` function.
    //! @include example/set/searchable.cpp
    //!
    //!
    //! Conversion from any `Foldable`
    //! ------------------------------
    //! Any `Foldable` structure can be converted into a `hana::set` with
    //! `to<set_tag>`. The elements of the structure must all be compile-time
    //! `Comparable`. If the structure contains duplicate elements, only
    //! the first occurence will appear in the resulting set. More
    //! specifically, conversion from a `Foldable` is equivalent to
    //! @code
    //!     to<set_tag>(xs) == fold_left(xs, make_set(), insert)
    //! @endcode
    //!
    //! __Example__
    //! @include example/set/convert.cpp
    template <typename ...Xs>
    struct set;

    //! Tag representing the `hana::set` container.
    //! @relates hana::set
    struct set_tag { };

    //! Function object for creating a `hana::set`.
    //! @relates hana::set
    //!
    //! Given zero or more values `xs...`, `make<set_tag>` returns a `set`
    //! containing those values. The values must all be compile-time
    //! `Comparable`, and no duplicate values may be provided. To create
    //! a `set` from a sequence with possible duplicates, use `to<set_tag>`
    //! instead.
    //!
    //!
    //! Example
    //! -------
    //! @include example/set/make.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    template <>
    constexpr auto make<set_tag> = [](auto&& ...xs) {
        return set<implementation-defined...>{forwarded(xs)...};
    };
#endif

    //! Equivalent to `make<set_tag>`; provided for convenience.
    //! @relates hana::set
    //!
    //!
    //! Example
    //! -------
    //! @include example/set/make.cpp
    constexpr auto make_set = make<set_tag>;

    //! Insert an element in a `hana::set`.
    //! @relates hana::set
    //!
    //! If the set already contains an element that compares equal, then
    //! nothing is done and the set is returned as is.
    //!
    //!
    //! @param set
    //! The set in which to insert a value.
    //!
    //! @param element
    //! The value to insert. It must be compile-time `Comparable`.
    //!
    //!
    //! Example
    //! -------
    //! @include example/set/insert.cpp
    //!
    //!
    //! Benchmarks
    //! ----------
    //! <div class="benchmark-chart"
    //!      style="min-width: 310px; height: 400px; margin: 0 auto"
    //!      data-dataset="benchmark.insert.compile.json">
    //! </div>
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto insert = [](auto&& set, auto&& element) {
        return tag-dispatched;
    };
#endif

    //! Remove an element from a `hana::set`.
    //! @relates hana::set
    //!
    //! Returns a new set containing all the elements of the original,
    //! except the one comparing `equal` to the given element. If the set
    //! does not contain such an element, a new set equal to the original
    //! set is returned.
    //!
    //!
    //! @param set
    //! The set in which to remove a value.
    //!
    //! @param element
    //! The value to remove. It must be compile-time `Comparable`.
    //!
    //!
    //! Example
    //! -------
    //! @include example/set/erase_key.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto erase_key = [](auto&& set, auto&& element) {
        return tag-dispatched;
    };
#endif
}} // end namespace boost::hana
示例#13
0
#ifndef BOOST_HANA_FUNCTIONAL_ID_HPP
#define BOOST_HANA_FUNCTIONAL_ID_HPP

#include <boost/hana/config.hpp>


BOOST_HANA_NAMESPACE_BEGIN
    //! @ingroup group-functional
    //! The identity function -- returns its argument unchanged.
    //!
    //! ### Example
    //! @include example/functional/id.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto id = [](auto&& x) -> decltype(auto) {
        return forwarded(x);
    };
#else
    struct id_t {
        template <typename T>
        constexpr T operator()(T&& t) const {
            return static_cast<T&&>(t);
        }
    };

    constexpr id_t id{};
#endif
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_FUNCTIONAL_ID_HPP
示例#14
0
namespace boost { namespace hana {
    //! @ingroup group-datatypes
    //! Represents a value with two possibilities.
    //!
    //! An `Either` contains either a left value or a right value, both of
    //! which may have different data types. An `Either` containing a left
    //! value `a` is represented as `left(a)`, and an `Either` containing a
    //! right value `b` is represented as `right(b)`.
    //!
    //! `Either` can sometimes be used to represent a value which is either
    //! correct or an error; by convention, `left` is used to hold an error
    //! and `right` is used to hold a correct value. A mnemonic is that
    //! _right_ also means _correct_.
    //!
    //!
    //! Modeled concepts
    //! ----------------
    //! 1. `Comparable` (operators provided)\n
    //! Two `Either`s are equal if and only if they both contain left values
    //! or they both contain right values and those values are equal.
    //! @snippet example/either.cpp comparable
    //!
    //! 2. `Orderable` (operators provided)\n
    //! `Either`s are ordered by considering any `left` value as less than any
    //! `right` value, and ordering two `left`s or two `right`s by ordering
    //! their content. In other words,
    //! @code
    //!     left(anything) < right(anything)
    //!     left(x)  < left(y)  if and only if x < y
    //!     right(x) < right(y) if and only if x < y
    //! @endcode
    //! Example:
    //! @snippet example/either.cpp orderable
    //!
    //! 3. `Functor`\n
    //! Since `Either` can contain one of two possible values of different
    //! data types and `transform` accepts a single function, `Either`'s instance
    //! of `Functor` can only map the function over one arbitrarily-defined
    //! side of the `Either`. Hence, mapping a function over an `Either e`
    //! does nothing if `e` contains a left value, and it applies the function
    //! if `e` contains a right value. In other words:
    //! @code
    //!     transform(left(x), f) == left(x)
    //!     transform(right(x), f) == right(f(x))
    //! @endcode
    //! Example:
    //! @snippet example/either.cpp functor
    //!
    //! 4. `Applicative`\n
    //! The instance of `Applicative` for `Either` follows naturally from
    //! the instance of `Functor`. Specifically,
    //! @code
    //!     ap(left(x), anything) == left(x)
    //!     ap(right(x), left(anything)) == right(x)
    //!     ap(right(f), right(x)) == right(f(x))
    //!     lift<Either>(x) == right(x)
    //! @endcode
    //! Example:
    //! @snippet example/either.applicative.cpp main
    //!
    //! 5. `Monad` (operators provided)\n
    //! The instance of `Monad` for `Either` follows naturally from
    //! the instance of `Applicative`. Specifically,
    //! @code
    //!     flatten(right(right(x))) == right(x)
    //!     flatten(anything else) == anything else
    //! @endcode
    //! Example:
    //! @snippet example/either.cpp monad
    //!
    //! 6. `Foldable`\n
    //! For the purpose of being folded, an `Either` is considered empty if
    //! it is a `left`, and it is considered equivalent to a one element list
    //! if it is a `right`.
    //! @snippet example/either.cpp foldable
    //!
    //! 7. `Traversable`\n
    //! Traversing a `left` with an `Applicative A` just lifts the `left` into
    //! the `Applicative`. Traversing a `right` will apply the function to the
    //! value inside the `right`, which effectively lifts the value into the
    //! `Applicative`, and then put back the value inside an `right` with
    //! `transform`. In other words,
    //! @code
    //!     traverse<A>(left(x), f) == lift<A>(left(x))
    //!     traverse<A>(right(y), f) == transform(f(y), right)
    //! @endcode
    //! Example:
    //! @snippet example/either.cpp traversable
    struct Either { };

    //! Create an `Either` containing the given left value.
    //! @relates Either
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/either.cpp left
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto left = [](auto&& x) {
        return unspecified-type;
    };
#else
    template <typename X, typename = operators::adl>
    struct _left;

    constexpr detail::create<_left> left{};
#endif

    //! Create an `Either` containing the given right value.
    //! @relates Either
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/either.cpp right
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto right = [](auto&& x) {
        return unspecified-type;
    };
#else
    template <typename X, typename = operators::adl>
    struct _right;

    constexpr detail::create<_right> right{};
#endif

    //! Apply one of two functions to the value inside an `Either`.
    //! @relates Either
    //!
    //! Specifically, `either` is such that
    //! @code
    //!     either(f, g, left(x)) == f(x)
    //!     either(f, g, right(x)) == g(x)
    //! @endcode
    //!
    //!
    //! @param f
    //! The function applied to the left value if `e` contains a left value.
    //!
    //! @param g
    //! The function applied to the right value if `e` contains a right value.
    //!
    //! @param e
    //! The `Either` value to analyze.
    //!
    //!
    //! Example
    //! -------
    //! @snippet example/either.cpp either
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto either = [](auto&& f, auto&& g, auto&& e) -> decltype(auto) {
        if (e is a left(x))
            return forwarded(f)(forwarded(x));
        else if (e is a right(y))
            return forwarded(g)(forwarded(y));
    };
#else
    struct _either {
        template <typename F, typename G, typename E>
        constexpr decltype(auto) operator()(F&& f, G&& g, E&& e) const {
            return detail::std::forward<E>(e).go(
                detail::std::forward<F>(f),
                detail::std::forward<G>(g)
            );
        }
    };

    constexpr _either either{};
#endif
}} // end namespace boost::hana
示例#15
0
文件: set.hpp 项目: jinby/hana
    //! @relates hana::set
    //!
    //! Given zero or more values `xs...`, `make<set_tag>` returns a `set`
    //! containing those values. The values must all be compile-time
    //! `Comparable`, and no duplicate values may be provided. To create
    //! a `set` from a sequence with possible duplicates, use `to<set_tag>`
    //! instead.
    //!
    //!
    //! Example
    //! -------
    //! @include example/set/make.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    template <>
    constexpr auto make<set_tag> = [](auto&& ...xs) {
        return set<implementation-defined...>{forwarded(xs)...};
    };
#endif

    //! Equivalent to `make<set_tag>`; provided for convenience.
    //! @relates hana::set
    //!
    //!
    //! Example
    //! -------
    //! @include example/set/make.cpp
    constexpr auto make_set = make<set_tag>;

    //! Insert an element in a `hana::set`.
    //! @relates hana::set
    //!
    //!     capture(vars...)(f)(args...) == f(vars..., args...)
    //! @endcode
    //!
    //! @note
    //! The arity of `f` must match the total number of arguments passed to
    //! it, i.e. `sizeof...(vars) + sizeof...(args)`.
    //!
    //!
    //! Example
    //! -------
    //! @include example/functional/capture.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto capture = [](auto&& ...variables) {
        return [perfect-capture](auto&& f) {
            return [perfect-capture](auto&& ...args) -> decltype(auto) {
                return forwarded(f)(forwarded(variables)..., forwarded(args)...);
            };
        };
    };
#else
    namespace detail {
        template <typename F, typename Closure, std::size_t ...i>
        constexpr auto apply_capture(F&& f, Closure&& closure, std::index_sequence<i...>) {
            return hana::partial(static_cast<F&&>(f),
                hana::get_impl<i>(static_cast<Closure&&>(closure).storage_)...
            );
        }
    }

    template <typename ...X>
    struct capture_t;
示例#17
0
文件: return.cpp 项目: himura/p-stade
void egg_test()
{
    namespace egg = boost::egg;
    namespace lambda = boost::lambda;

    ::my_fun_t my_fun;

    {
        BOOST_CHECK( 3 ==
            ::foo( egg::X_return< int >()(my_fun) )
        );
    }
    {
        BOOST_CHECK( 3 ==
            egg::X_return< boost::use_default >()(&my_fun1)(3)
        );
    }

#if 0
    {
        BOOST_CHECK( 3 ==
            3  ::foo( my_fun|forwarded(boost::type<int>()) )
        );
    }
#endif
    { // make lambda perfect!
        BOOST_CHECK( 3 ==
            egg::X_return<>()(
                lambda::bind( egg::X_return< int >()(my_fun), lambda::_1, lambda::_2 )
            )(1, 2)
        );
    }

    ::my_fun0_t my_fun0;
    {
        boost::egg::result_of_<
            boost::egg::result_of_<egg::X_return< int >(my_fun0_t)>::type()
        >::type result = egg::X_return< int >()(my_fun0)();
        BOOST_CHECK( result == 10 );
    }

    {
        BOOST_CHECK( 3 ==
            egg::return_< int >(&my_fun1)(3)
        );
    }
    {
        BOOST_CHECK( 3 ==
            egg::X_return<>()(&my_fun1)(3)
        );
    }

    {
        // (lambda::_1 + lambda::_2)(1, 2); // error
        BOOST_CHECK( 3 == 
            egg::return_< int >(lambda::_1 + lambda::_2)(1, 2)
        );
        BOOST_CHECK( 3 == 
            egg::X_return<>()(lambda::_1 + lambda::_2)(1, 2)
        );
    }

    {
        egg::result_of_return< my_fun_t, int >::type perf = BOOST_EGG_RETURN({});
        BOOST_CHECK( perf(1,3) == 4);
    }
}