[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/gitxyf/cpp.react/master/include/react/algorithm.h [Back]  [Original]

//          Copyright Sebastian Jeckel 2017.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#ifndef REACT_ALGORITHM_H_INCLUDED
#define REACT_ALGORITHM_H_INCLUDED

#pragma once

#include "react/detail/defs.h"

#include 
#include 
#include 

#include "react/api.h"
#include "react/state.h"
#include "react/event.h"

#include "react/detail/algorithm_nodes.h"

/*****************************************/ REACT_BEGIN /*****************************************/

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Holds the most recent event in a state
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Hold(const Group& group, T&& initialValue, const Event& evnt) -> State
{
    using REACT_IMPL::HoldNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(
        group, std::forward(initialValue), SameGroupOrLink(group, evnt));
}

template 
auto Hold(T&& initialValue, const Event& evnt) -> State
    { return Hold(evnt.GetGroup(), std::forward(initialValue), evnt); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Emits value changes of target state.
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Monitor(const Group& group, const State& state) -> Event
{
    using REACT_IMPL::MonitorNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(
        group, SameGroupOrLink(group, state));
}

template 
auto Monitor(const State& state) -> Event
    { return Monitor(state.GetGroup(), state); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Iteratively combines state value with values from event stream (aka Fold)
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Iterate(const Group& group, T&& initialValue, F&& func, const Event& evnt) -> State
{
    using REACT_IMPL::IterateNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    using FuncType = typename std::decay::type;

    return CreateWrappedNode(
        group, std::forward(initialValue), std::forward(func), SameGroupOrLink(group, evnt));
}

template 
auto IterateByRef(const Group& group, T&& initialValue, F&& func, const Event& evnt) -> State
{
    using REACT_IMPL::IterateByRefNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    using FuncType = typename std::decay::type;

    return CreateWrappedNode(
        group, std::forward(initialValue), std::forward(func), SameGroupOrLink(group, evnt));
}

template 
auto Iterate(T&& initialValue, F&& func, const Event& evnt) -> State
    { return Iterate(evnt.GetGroup(), std::forward(initialValue), std::forward(func), evnt); }

template 
auto IterateByRef(T&& initialValue, F&& func, const Event& evnt) -> State
    { return IterateByRef(evnt.GetGroup(), std::forward(initialValue), std::forward(func), evnt); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Iterate - Synced
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Iterate(const Group& group, T&& initialValue, F&& func, const Event& evnt, const State& ... states) -> State
{
    using REACT_IMPL::SyncedIterateNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    using FuncType = typename std::decay::type;

    return CreateWrappedNode(
        group, std::forward(initialValue), std::forward(func), SameGroupOrLink(group, evnt), SameGroupOrLink(group, states) ...);
}

template 
auto IterateByRef(const Group& group, T&& initialValue, F&& func, const Event& evnt, const State& ... states) -> State
{
    using REACT_IMPL::SyncedIterateByRefNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    using FuncType = typename std::decay::type;

    return CreateWrappedNode(
        group, std::forward(initialValue), std::forward(func), SameGroupOrLink(group, evnt), SameGroupOrLink(group, states) ...);
}

template 
auto Iterate(T&& initialValue, F&& func, const Event& evnt, const State& ... states) -> State
    { return Iterate(evnt.GetGroup(), std::forward(initialValue), std::forward(func), evnt, states ...); }

template 
auto IterateByRef(T&& initialValue, F&& func, const Event& evnt, const State& ... states) -> State
    { return IterateByRef(evnt.GetGroup(), std::forward(initialValue), std::forward(func), evnt, states ...); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Snapshot - Sets state value to value of other state when event is received
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Snapshot(const Group& group, const State& state, const Event& evnt) -> State
{
    using REACT_IMPL::SnapshotNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(
        group, SameGroupOrLink(group, state), SameGroupOrLink(group, evnt));
}

template 
auto Snapshot(const State& state, const Event& evnt) -> State
    { return Snapshot(state.GetGroup(), state, evnt); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Pulse - Emits value of target state when event is received
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Pulse(const Group& group, const State& state, const Event& evnt) -> Event
{
    using REACT_IMPL::PulseNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(
        group, SameGroupOrLink(group, state), SameGroupOrLink(group, evnt));
}

template 
auto Pulse(const State& state, const Event& evnt) -> Event
    { return Pulse(state.GetGroup(), state, evnt); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Flatten
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto Flatten(const Group& group, const State& state) -> State
{
    using REACT_IMPL::FlattenStateNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(group, SameGroupOrLink(group, state));
}

template 
auto Flatten(const State& state) -> State
    { return Flatten(state.GetGroup(), state); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// FlattenList
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto FlattenList(const Group& group, const State& list) -> State
{
    using REACT_IMPL::FlattenStateListNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(
        group, SameGroupOrLink(group, list));
}

template 
auto FlattenList(const State& list) -> State
    { return FlattenList(list.GetGroup(), list); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// FlattenMap
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto FlattenMap(const Group& group, const State& map) -> State
{
    using REACT_IMPL::FlattenStateMapNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(
        group, SameGroupOrLink(group, map));
}

template 
auto FlattenMap(const State& map) -> State
    { return FlattenMap(map.GetGroup(), map); }

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Flattened
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
class Flattened : public C
{
public:
    using C::C;

    Flattened(const C& base) :
        C( base )
    { }

    Flattened(const C& base, REACT_IMPL::FlattenedInitTag) :
        C( base ),
        initMode_( true )
    { }

    Flattened(const C& base, REACT_IMPL::FlattenedInitTag, std::vector&& emptyMemberIds) :
        C( base ),
        initMode_( true ),
        memberIds_( std::move(emptyMemberIds) ) // This will be empty, but has pre-allocated storage. It's a tweak.
    { }

    template 
    Ref Flatten(State& signal)
    {
        if (initMode_)
            memberIds_.push_back(GetInternals(signal).GetNodeId());
        
        return GetInternals(signal).Value();
    }

private:
    bool initMode_ = false;
    std::vector memberIds_;

    template 
    friend class impl::FlattenObjectNode;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
/// FlattenObject
///////////////////////////////////////////////////////////////////////////////////////////////////
template 
auto FlattenObject(const Group& group, const State& obj) -> State
{
    using REACT_IMPL::FlattenObjectNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(group, obj);
}

template 
auto FlattenObject(const State& obj) -> State
    { return FlattenObject(obj.GetGroup(), obj); }

template 
auto FlattenObject(const Group& group, const State& obj) -> State
{
    using REACT_IMPL::FlattenObjectNode;
    using REACT_IMPL::SameGroupOrLink;
    using REACT_IMPL::CreateWrappedNode;

    return CreateWrappedNode(group, obj);
}

template 
auto FlattenObject(const State& obj) -> State
    { return FlattenObject(obj.GetGroup(), obj); }

/******************************************/ REACT_END /******************************************/

#endif // REACT_ALGORITHM_H_INCLUDED

Web Proxy Viewer  |  New URL  |  Original Page