<commit_before>#include "rdb_protocol/env.hpp"
#include "rdb_protocol/pb_utils.hpp"
#include "rdb_protocol/term_walker.hpp"

#pragma GCC diagnostic ignored "-Wshadow"

namespace ql {

bool env_t::add_optarg(const std::string &key, const Term &val) {
    if (optargs.count(key)) return true;
    env_wrapper_t<Term> *ewt = add_ptr(new env_wrapper_t<Term>());
    Term *arg = &ewt->t;
    N2(FUNC, N0(MAKE_ARRAY), *arg = val);
    term_walker_t(arg, &val.GetExtension(ql2::extension::backtrace));
    optargs[key] = wire_func_t(*arg, 0);
    return false;
}
void env_t::init_optargs(const std::map<std::string, wire_func_t> &_optargs) {
    r_sanity_check(optargs.size() == 0);
    optargs = _optargs;
}
val_t *env_t::get_optarg(const std::string &key){
    if (!optargs.count(key)) return 0;
    return optargs[key].compile(this)->call();
}
const std::map<std::string, wire_func_t> &env_t::get_all_optargs() {
    return optargs;
}

static const int min_normal_gensym = -1000000;
int env_t::gensym(bool allow_implicit) {
    r_sanity_check(0 > next_gensym_val && next_gensym_val >= min_normal_gensym);
    int gensym = next_gensym_val--;
    if (!allow_implicit) {
        gensym += min_normal_gensym;
        r_sanity_check(gensym < min_normal_gensym);
    }
    return gensym;
}

bool env_t::var_allows_implicit(int varnum) {
    return varnum >= min_normal_gensym;
}

void env_t::push_implicit(const datum_t **val) {
    implicit_var.push(val);
}
const datum_t **env_t::top_implicit(const rcheckable_t *caller) {
    rcheck_target(caller, !implicit_var.empty(),
                  "r.row is not defined in this context.");
    rcheck_target(caller, implicit_var.size() == 1,
                  "Cannot use r.row in nested queries.  Use functions instead.");
    return implicit_var.top();
}
void env_t::pop_implicit() {
    r_sanity_check(implicit_var.size() > 0);
    implicit_var.pop();
}

size_t env_t::num_checkpoints() {
    return bags.size()-1;
}
bool env_t::some_bag_has(const ptr_baggable_t *p) {
    for (size_t i = 0; i < bags.size(); ++i) if (bags[i]->has(p)) return true;
    return false;
}
void env_t::checkpoint() {
    bags.push_back(new ptr_bag_t());
}

void env_t::merge_checkpoint() {
    r_sanity_check(bags.size() >= 2);
    bags[bags.size()-2]->add(bags[bags.size()-1]);
    bags.pop_back();
}
void env_t::discard_checkpoint() {
    r_sanity_check(bags.size() >= 2);
    delete bags[bags.size()-1];
    bags.pop_back();
}

bool env_t::gc_callback_trampoline(const datum_t *el, env_t *env) {
    return env->gc_callback(el);
}
bool env_t::gc_callback(const datum_t *el) {
    if (old_bag->has(el)) {
        old_bag->yield_to(new_bag, el);
        return true;
    }
    r_sanity_check(some_bag_has(el));
    return false;
}
void env_t::gc(const datum_t *root) {
    old_bag = current_bag();
    scoped_ptr_t<ptr_bag_t> _new_bag(new ptr_bag_t);
    new_bag = _new_bag.get();
    // debugf("GC {\n");
    // debugf("  old_bag: %s\n", old_bag->print_debug().c_str());
    // debugf("  new_bag: %s\n", new_bag->print_debug().c_str());
    root->iter(gc_callback_trampoline, this);
    // debugf(" --- \n");
    // debugf("  old_bag: %s\n", old_bag->print_debug().c_str());
    // debugf("  new_bag: %s\n", new_bag->print_debug().c_str());
    // debugf("}\n");
    *current_bag_ptr() = _new_bag.release();
    delete old_bag;
}

ptr_bag_t *env_t::current_bag() { return *current_bag_ptr(); }
ptr_bag_t **env_t::current_bag_ptr() {
    r_sanity_check(bags.size() > 0);
    return &bags[bags.size()-1];
}

void env_t::push_var(int var, const datum_t **val) {
    // debugf("%p VAR push %d -> %p\n", this, var, val);
    vars[var].push(val);
}
const datum_t **env_t::top_var(int var, const rcheckable_t *caller) {
    // if (vars[var].empty()) debugf("%p VAR top %d -> FAILED\n", this, var);
    rcheck_target(caller, !vars[var].empty(),
                  strprintf("Unrecognized variabled %d", var));
    // debugf("%p VAR top %d -> %p\n", this, var, vars[var].top());
    return vars[var].top();
}
void env_t::pop_var(int var) {
    // debugf("%p VAR pop %d (%p)\n", this, var, vars[var].top());
    vars[var].pop();
}
void env_t::dump_scope(std::map<int64_t, const datum_t **> *out) {
    for (std::map<int64_t, std::stack<const datum_t **> >::iterator
             it = vars.begin(); it != vars.end(); ++it) {
        if (it->second.size() == 0) continue;
        r_sanity_check(it->second.top());
        (*out)[it->first] = it->second.top();
    }
}
void env_t::push_scope(std::map<int64_t, Datum> *in) {
    scope_stack.push(std::vector<std::pair<int, const datum_t *> >());

    for (std::map<int64_t, Datum>::iterator it = in->begin(); it != in->end(); ++it) {
        const datum_t *d = add_ptr(new datum_t(&it->second, this));
        scope_stack.top().push_back(std::make_pair(it->first, d));
    }

    for (size_t i = 0; i < scope_stack.top().size(); ++i) {
        // debugf("%p -> %p\n",
        //        &scope_stack.top()[i].second,
        //        scope_stack.top()[i].second);
        push_var(scope_stack.top()[i].first, &scope_stack.top()[i].second);
    }
}
void env_t::pop_scope() {
    r_sanity_check(scope_stack.size() > 0);
    for (size_t i = 0; i < scope_stack.top().size(); ++i) {
        pop_var(scope_stack.top()[i].first);
    }
    // DO NOT pop the vector off the scope stack.  You might invalidate a
    // pointer too early.
}

env_checkpoint_t::env_checkpoint_t(env_t *_env, void (env_t::*_f)())
    : env(_env) , f(_f) {
    env->checkpoint();
}
env_checkpoint_t::~env_checkpoint_t() { (env->*f)(); }
void env_checkpoint_t::reset(void (env_t::*_f)()) {
    f = _f;
}
void env_checkpoint_t::gc(const datum_t *root) {
    env->gc(root);
}

// We GC more frequently (~ every 16 data) in debug mode to help with testing.
#ifndef NDEBUG
const int env_gc_checkpoint_t::DEFAULT_GEN1_CUTOFF =
    sizeof(datum_t) * ptr_bag_t::mem_estimate_multiplier * 16));
#else
const int env_gc_checkpoint_t::DEFAULT_GEN1_CUTOFF = (8 * 1024 * 1024);
#endif // NDEBUG
const int env_gc_checkpoint_t::DEFAULT_GEN2_SIZE_MULTIPLIER = 8;

env_gc_checkpoint_t::env_gc_checkpoint_t(env_t *_env, size_t _gen1, size_t _gen2)
    : finalized(false), env(_env), gen1(_gen1), gen2(_gen2) {
    r_sanity_check(env);
    if (!gen1) gen1 = DEFAULT_GEN1_CUTOFF;
    if (!gen2) gen2 = DEFAULT_GEN2_SIZE_MULTIPLIER * gen1;
    env->checkpoint(); // gen2
    env->checkpoint(); // gen1
}
env_gc_checkpoint_t::~env_gc_checkpoint_t() {
    // We might not be finalized if e.g. an exception was thrown.
    if (!finalized) {
        env->merge_checkpoint();
        env->merge_checkpoint();
    }
}
const datum_t *env_gc_checkpoint_t::maybe_gc(const datum_t *root) {
    if (env->current_bag()->mem_estimate() > gen1) {
        env->gc(root);
        env->merge_checkpoint();
        if (env->current_bag()->mem_estimate() > gen2) {
            env->gc(root);
            if (env->current_bag()->mem_estimate() > (gen2 * 2 / 3)) gen2 *= 4;
        }
        env->checkpoint();
    }
    return root;
}
const datum_t *env_gc_checkpoint_t::finalize(const datum_t *root) {
    r_sanity_check(!finalized);
    finalized = true;
    if (root) env->gc(root);
    env->merge_checkpoint();
    if (root) env->gc(root);
    env->merge_checkpoint();
    return root;
}

void env_t::join_and_wait_to_propagate(
    const cluster_semilattice_metadata_t &metadata_to_join)
    THROWS_ONLY(interrupted_exc_t) {
    cluster_semilattice_metadata_t sl_metadata;
    {
        on_thread_t switcher(semilattice_metadata->home_thread());
        semilattice_metadata->join(metadata_to_join);
        sl_metadata = semilattice_metadata->get();
    }

    boost::function<bool (const cow_ptr_t<ns_metadata_t> s)> p = boost::bind(
        &is_joined<cow_ptr_t<ns_metadata_t > >,
        _1,
        sl_metadata.rdb_namespaces
    );

    {
        on_thread_t switcher(namespaces_semilattice_metadata->home_thread());
        namespaces_semilattice_metadata->run_until_satisfied(p,
                                                             interruptor);
        databases_semilattice_metadata->run_until_satisfied(
            boost::bind(&is_joined<databases_semilattice_metadata_t>,
                        _1,
                        sl_metadata.databases),
            interruptor);
    }
}

env_t::env_t(
    extproc::pool_group_t *_pool_group,
    namespace_repo_t<rdb_protocol_t> *_ns_repo,

    clone_ptr_t<watchable_t<cow_ptr_t<ns_metadata_t> > >
    _namespaces_semilattice_metadata,

    clone_ptr_t<watchable_t<databases_semilattice_metadata_t> >
    _databases_semilattice_metadata,
    boost::shared_ptr<semilattice_readwrite_view_t<cluster_semilattice_metadata_t> >
    _semilattice_metadata,
    directory_read_manager_t<cluster_directory_metadata_t> *_directory_read_manager,
    boost::shared_ptr<js::runner_t> _js_runner,
    signal_t *_interruptor,
    uuid_u _this_machine,
    const std::map<std::string, wire_func_t> &_optargs)
  : optargs(_optargs),
    next_gensym_val(-2),
    implicit_depth(0),
    pool(_pool_group->get()),
    ns_repo(_ns_repo),
    namespaces_semilattice_metadata(_namespaces_semilattice_metadata),
    databases_semilattice_metadata(_databases_semilattice_metadata),
    semilattice_metadata(_semilattice_metadata),
    directory_read_manager(_directory_read_manager),
    js_runner(_js_runner),
    interruptor(_interruptor),
    this_machine(_this_machine) {

    guarantee(js_runner);
    bags.push_back(new ptr_bag_t());

}

env_t::~env_t() {
    guarantee(bags.size() == 1);
    delete bags[0];
}

} // namespace ql
<commit_msg>fixed stupid syntax error<commit_after>#include "rdb_protocol/env.hpp"
#include "rdb_protocol/pb_utils.hpp"
#include "rdb_protocol/term_walker.hpp"

#pragma GCC diagnostic ignored "-Wshadow"

namespace ql {

bool env_t::add_optarg(const std::string &key, const Term &val) {
    if (optargs.count(key)) return true;
    env_wrapper_t<Term> *ewt = add_ptr(new env_wrapper_t<Term>());
    Term *arg = &ewt->t;
    N2(FUNC, N0(MAKE_ARRAY), *arg = val);
    term_walker_t(arg, &val.GetExtension(ql2::extension::backtrace));
    optargs[key] = wire_func_t(*arg, 0);
    return false;
}
void env_t::init_optargs(const std::map<std::string, wire_func_t> &_optargs) {
    r_sanity_check(optargs.size() == 0);
    optargs = _optargs;
}
val_t *env_t::get_optarg(const std::string &key){
    if (!optargs.count(key)) return 0;
    return optargs[key].compile(this)->call();
}
const std::map<std::string, wire_func_t> &env_t::get_all_optargs() {
    return optargs;
}

static const int min_normal_gensym = -1000000;
int env_t::gensym(bool allow_implicit) {
    r_sanity_check(0 > next_gensym_val && next_gensym_val >= min_normal_gensym);
    int gensym = next_gensym_val--;
    if (!allow_implicit) {
        gensym += min_normal_gensym;
        r_sanity_check(gensym < min_normal_gensym);
    }
    return gensym;
}

bool env_t::var_allows_implicit(int varnum) {
    return varnum >= min_normal_gensym;
}

void env_t::push_implicit(const datum_t **val) {
    implicit_var.push(val);
}
const datum_t **env_t::top_implicit(const rcheckable_t *caller) {
    rcheck_target(caller, !implicit_var.empty(),
                  "r.row is not defined in this context.");
    rcheck_target(caller, implicit_var.size() == 1,
                  "Cannot use r.row in nested queries.  Use functions instead.");
    return implicit_var.top();
}
void env_t::pop_implicit() {
    r_sanity_check(implicit_var.size() > 0);
    implicit_var.pop();
}

size_t env_t::num_checkpoints() {
    return bags.size()-1;
}
bool env_t::some_bag_has(const ptr_baggable_t *p) {
    for (size_t i = 0; i < bags.size(); ++i) if (bags[i]->has(p)) return true;
    return false;
}
void env_t::checkpoint() {
    bags.push_back(new ptr_bag_t());
}

void env_t::merge_checkpoint() {
    r_sanity_check(bags.size() >= 2);
    bags[bags.size()-2]->add(bags[bags.size()-1]);
    bags.pop_back();
}
void env_t::discard_checkpoint() {
    r_sanity_check(bags.size() >= 2);
    delete bags[bags.size()-1];
    bags.pop_back();
}

bool env_t::gc_callback_trampoline(const datum_t *el, env_t *env) {
    return env->gc_callback(el);
}
bool env_t::gc_callback(const datum_t *el) {
    if (old_bag->has(el)) {
        old_bag->yield_to(new_bag, el);
        return true;
    }
    r_sanity_check(some_bag_has(el));
    return false;
}
void env_t::gc(const datum_t *root) {
    old_bag = current_bag();
    scoped_ptr_t<ptr_bag_t> _new_bag(new ptr_bag_t);
    new_bag = _new_bag.get();
    // debugf("GC {\n");
    // debugf("  old_bag: %s\n", old_bag->print_debug().c_str());
    // debugf("  new_bag: %s\n", new_bag->print_debug().c_str());
    root->iter(gc_callback_trampoline, this);
    // debugf(" --- \n");
    // debugf("  old_bag: %s\n", old_bag->print_debug().c_str());
    // debugf("  new_bag: %s\n", new_bag->print_debug().c_str());
    // debugf("}\n");
    *current_bag_ptr() = _new_bag.release();
    delete old_bag;
}

ptr_bag_t *env_t::current_bag() { return *current_bag_ptr(); }
ptr_bag_t **env_t::current_bag_ptr() {
    r_sanity_check(bags.size() > 0);
    return &bags[bags.size()-1];
}

void env_t::push_var(int var, const datum_t **val) {
    // debugf("%p VAR push %d -> %p\n", this, var, val);
    vars[var].push(val);
}
const datum_t **env_t::top_var(int var, const rcheckable_t *caller) {
    // if (vars[var].empty()) debugf("%p VAR top %d -> FAILED\n", this, var);
    rcheck_target(caller, !vars[var].empty(),
                  strprintf("Unrecognized variabled %d", var));
    // debugf("%p VAR top %d -> %p\n", this, var, vars[var].top());
    return vars[var].top();
}
void env_t::pop_var(int var) {
    // debugf("%p VAR pop %d (%p)\n", this, var, vars[var].top());
    vars[var].pop();
}
void env_t::dump_scope(std::map<int64_t, const datum_t **> *out) {
    for (std::map<int64_t, std::stack<const datum_t **> >::iterator
             it = vars.begin(); it != vars.end(); ++it) {
        if (it->second.size() == 0) continue;
        r_sanity_check(it->second.top());
        (*out)[it->first] = it->second.top();
    }
}
void env_t::push_scope(std::map<int64_t, Datum> *in) {
    scope_stack.push(std::vector<std::pair<int, const datum_t *> >());

    for (std::map<int64_t, Datum>::iterator it = in->begin(); it != in->end(); ++it) {
        const datum_t *d = add_ptr(new datum_t(&it->second, this));
        scope_stack.top().push_back(std::make_pair(it->first, d));
    }

    for (size_t i = 0; i < scope_stack.top().size(); ++i) {
        // debugf("%p -> %p\n",
        //        &scope_stack.top()[i].second,
        //        scope_stack.top()[i].second);
        push_var(scope_stack.top()[i].first, &scope_stack.top()[i].second);
    }
}
void env_t::pop_scope() {
    r_sanity_check(scope_stack.size() > 0);
    for (size_t i = 0; i < scope_stack.top().size(); ++i) {
        pop_var(scope_stack.top()[i].first);
    }
    // DO NOT pop the vector off the scope stack.  You might invalidate a
    // pointer too early.
}

env_checkpoint_t::env_checkpoint_t(env_t *_env, void (env_t::*_f)())
    : env(_env) , f(_f) {
    env->checkpoint();
}
env_checkpoint_t::~env_checkpoint_t() { (env->*f)(); }
void env_checkpoint_t::reset(void (env_t::*_f)()) {
    f = _f;
}
void env_checkpoint_t::gc(const datum_t *root) {
    env->gc(root);
}

// We GC more frequently (~ every 16 data) in debug mode to help with testing.
#ifndef NDEBUG
const int env_gc_checkpoint_t::DEFAULT_GEN1_CUTOFF =
    sizeof(datum_t) * ptr_bag_t::mem_estimate_multiplier * 16;
#else
const int env_gc_checkpoint_t::DEFAULT_GEN1_CUTOFF = (8 * 1024 * 1024);
#endif // NDEBUG
const int env_gc_checkpoint_t::DEFAULT_GEN2_SIZE_MULTIPLIER = 8;

env_gc_checkpoint_t::env_gc_checkpoint_t(env_t *_env, size_t _gen1, size_t _gen2)
    : finalized(false), env(_env), gen1(_gen1), gen2(_gen2) {
    r_sanity_check(env);
    if (!gen1) gen1 = DEFAULT_GEN1_CUTOFF;
    if (!gen2) gen2 = DEFAULT_GEN2_SIZE_MULTIPLIER * gen1;
    env->checkpoint(); // gen2
    env->checkpoint(); // gen1
}
env_gc_checkpoint_t::~env_gc_checkpoint_t() {
    // We might not be finalized if e.g. an exception was thrown.
    if (!finalized) {
        env->merge_checkpoint();
        env->merge_checkpoint();
    }
}
const datum_t *env_gc_checkpoint_t::maybe_gc(const datum_t *root) {
    if (env->current_bag()->mem_estimate() > gen1) {
        env->gc(root);
        env->merge_checkpoint();
        if (env->current_bag()->mem_estimate() > gen2) {
            env->gc(root);
            if (env->current_bag()->mem_estimate() > (gen2 * 2 / 3)) gen2 *= 4;
        }
        env->checkpoint();
    }
    return root;
}
const datum_t *env_gc_checkpoint_t::finalize(const datum_t *root) {
    r_sanity_check(!finalized);
    finalized = true;
    if (root) env->gc(root);
    env->merge_checkpoint();
    if (root) env->gc(root);
    env->merge_checkpoint();
    return root;
}

void env_t::join_and_wait_to_propagate(
    const cluster_semilattice_metadata_t &metadata_to_join)
    THROWS_ONLY(interrupted_exc_t) {
    cluster_semilattice_metadata_t sl_metadata;
    {
        on_thread_t switcher(semilattice_metadata->home_thread());
        semilattice_metadata->join(metadata_to_join);
        sl_metadata = semilattice_metadata->get();
    }

    boost::function<bool (const cow_ptr_t<ns_metadata_t> s)> p = boost::bind(
        &is_joined<cow_ptr_t<ns_metadata_t > >,
        _1,
        sl_metadata.rdb_namespaces
    );

    {
        on_thread_t switcher(namespaces_semilattice_metadata->home_thread());
        namespaces_semilattice_metadata->run_until_satisfied(p,
                                                             interruptor);
        databases_semilattice_metadata->run_until_satisfied(
            boost::bind(&is_joined<databases_semilattice_metadata_t>,
                        _1,
                        sl_metadata.databases),
            interruptor);
    }
}

env_t::env_t(
    extproc::pool_group_t *_pool_group,
    namespace_repo_t<rdb_protocol_t> *_ns_repo,

    clone_ptr_t<watchable_t<cow_ptr_t<ns_metadata_t> > >
    _namespaces_semilattice_metadata,

    clone_ptr_t<watchable_t<databases_semilattice_metadata_t> >
    _databases_semilattice_metadata,
    boost::shared_ptr<semilattice_readwrite_view_t<cluster_semilattice_metadata_t> >
    _semilattice_metadata,
    directory_read_manager_t<cluster_directory_metadata_t> *_directory_read_manager,
    boost::shared_ptr<js::runner_t> _js_runner,
    signal_t *_interruptor,
    uuid_u _this_machine,
    const std::map<std::string, wire_func_t> &_optargs)
  : optargs(_optargs),
    next_gensym_val(-2),
    implicit_depth(0),
    pool(_pool_group->get()),
    ns_repo(_ns_repo),
    namespaces_semilattice_metadata(_namespaces_semilattice_metadata),
    databases_semilattice_metadata(_databases_semilattice_metadata),
    semilattice_metadata(_semilattice_metadata),
    directory_read_manager(_directory_read_manager),
    js_runner(_js_runner),
    interruptor(_interruptor),
    this_machine(_this_machine) {

    guarantee(js_runner);
    bags.push_back(new ptr_bag_t());

}

env_t::~env_t() {
    guarantee(bags.size() == 1);
    delete bags[0];
}

} // namespace ql
<|endoftext|>


<commit_before>
#pragma once

#include <data_model.hpp>

#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <map>
#include <sstream>
#include <boost/tuple/tuple.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/graphviz.hpp>

namespace verilog
{
  namespace bdd {

    enum class NegP {
      Positive, Negative
    };

    enum class Type {
      Zero, One, Input
    };

    struct Node {
      std::string input_name;
      Type t;
    };

    typedef boost::adjacency_list<
      boost::setS,
      boost::vecS,
      boost::bidirectionalS,
      Node, NegP> GD;

    typedef unsigned int hashcode;

    struct BDD {
      GD graph;

      /**
       * The node representing the sinks of the BDD
       */
      int zero,
          one,
          /**
           * The node representing the source of the bdd
           */
          source;

      std::map<hashcode, std::vector<int> > bdd_heap;

      BDD(const std::string name) {
        zero = boost::add_vertex(graph);
        one  = boost::add_vertex(graph);
        source = add_vertex(name);

        add_edge(source, one, NegP::Positive);
        add_edge(source, zero, NegP::Positive);

        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * Creates a copy of a,
       * merges all nodes of b into the copy.
       * calls the conjunction_internal function for the copy.
       */
      BDD operator&(const BDD & b) {

        typedef std::map<GD::vertex_descriptor, GD::vertex_descriptor> node_map_t;
        node_map_t node_map;
        boost::associative_property_map<node_map_t> mapper(node_map);

        BDD c = *this;
        copy_graph(b.graph, c.graph, boost::orig_to_copy(mapper));

        int old_zero = node_map[b.zero];
        int old_one  = node_map[b.one];

        // copies the old one edges into the new graph
        c.merge_input_edges(c.one, old_one);
        boost::clear_vertex(old_one, c.graph);
        boost::remove_vertex(old_one, c.graph);

        // copies the old zero edges into the new graph
        c.merge_input_edges(c.zero, old_zero);
        boost::clear_vertex(old_zero, c.graph);
        boost::remove_vertex(old_zero, c.graph);

        c.source = c.conjunction_internal(c.source, node_map[c.source]);
        return c;

      }

      private:
      /**
       * Internal function that checks for all the cases
       * Accepts the nodes that must be conjoined
       * and returns the new source.
       */
      int conjunction_internal(int a, int b) {
        // TODO
        return 0;
      }

      int add_vertex(const std::string name) {
        int v = boost::add_vertex(graph);
        graph[v].input_name = name;
        graph[v].t          = Type::Input;
        return v;
      }

      void add_edge(int a, int b, NegP p) {
        boost::add_edge(a, b, p, graph);
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - changes zero and one
       */
      public:
      void reverse() {
        int aux = one;
        one = zero;
        zero = aux;

        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * merges the input edges of the node b into node a.
       */
      void merge_input_edges(int a, int b) {
        GD::in_edge_iterator e, end;
        for (boost::tie(e, end) = in_edges(b, graph); e != end; ++e) {
            int s = boost::source(*e, graph);
            add_edge(s, a, graph[*e]);
        }
      }

      std::map<int, std::vector<int> > find_layers() {
        // TODO
      }

      // Criar um hash o mais unico possivel para um bdd
      hashcode hash(int v) {
        // TODO
      }

      // Compares BDDs
      friend bool operator<(const BDD & bdd1, const BDD & bdd2) {
        // TODO
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - minimizes the BDD
       */
      void minimize() {
        // TODO
      }

      friend bool operator==(const BDD & bdd1, const BDD & bdd2) {
        return
          (bdd1.source == bdd2.source) &&
          (bdd1.one == bdd2.one) &&
          (bdd1.zero == bdd2.zero);
        // TODO &&
        //  (bdd1.graph == bdd2.graph);
      }
      friend bool operator!=(const BDD & bdd1, const BDD & bdd2) {
        return
          (bdd1.source != bdd2.source) &&
          (bdd1.one != bdd2.one) &&
          (bdd1.zero != bdd2.zero);
        // TODO&&
        //  (bdd1.graph != bdd2.graph);
      }

      public:
      int size() {
        int i = 0;
        GD::vertex_iterator n, e;
        for(boost::tie(n, e) = boost::vertices(graph);
            n != e; ++n) ++i;
        return i;
      }

      friend std::ostream& operator<<(std::ostream &o, const BDD & b) {

        o << "digraph G {\n" ;
        GD::vertex_iterator v, vend;
        for(boost::tie(v, vend) = boost::vertices(b.graph);
            v != vend; ++v) {
          switch(b.graph[*v].t) {
            case(Type::Input) : {
                o << *v << " [label=\""
                  << b.graph[*v].input_name
                  << "\", ";
                if (*v == b.source)
                  o << "shape=doublecircle];\n";
                else
                  o << "shape=circle];\n";
              break;
            }
            case(Type::One) : {
                o << *v << " [label=\"1\", shape=box]; \n";
              break;
            }
            case(Type::Zero) : {
                o << *v << " [label=\"0\", shape=box]; \n";
              break;
            }
          }
        }

        GD::edge_iterator e, eend;
        for(boost::tie(e, eend) = boost::edges(b.graph);
            e != eend; ++e) {
          int s = boost::source(*e, b.graph);
          int d = boost::target(*e, b.graph);

          o << s << "->" << d;
          switch(b.graph[*e]) {
            case(NegP::Positive): {
              o << " [style=solid];\n";
              break;
            }
            case(NegP::Negative): {
              o << " [style=dashed];\n";
              break;
            }
          }
        }

        o << "}\n" ;
        return o;
      }
    };
  }
}

<commit_msg>graphviz<commit_after>
#pragma once

#include <data_model.hpp>

#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <map>
#include <sstream>
#include <boost/tuple/tuple.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/graphviz.hpp>

namespace verilog
{
  namespace bdd {

    enum class NegP {
      Positive, Negative
    };

    enum class Type {
      Zero, One, Input
    };

    struct Node {
      std::string input_name;
      Type t;
    };

    typedef boost::adjacency_list<
      boost::setS,
      boost::vecS,
      boost::bidirectionalS,
      Node, NegP> GD;

    typedef unsigned int hashcode;

    struct BDD {
      GD graph;

      /**
       * The node representing the sinks of the BDD
       */
      int zero,
          one,
          /**
           * The node representing the source of the bdd
           */
          source;

      std::map<hashcode, std::vector<int> > bdd_heap;

      BDD(const std::string name) {
        zero = boost::add_vertex(graph);
        one  = boost::add_vertex(graph);
        source = add_vertex(name);

        add_edge(source, one, NegP::Positive);
        add_edge(source, zero, NegP::Negative);

        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * Creates a copy of a,
       * merges all nodes of b into the copy.
       * calls the conjunction_internal function for the copy.
       */
      BDD operator&(const BDD & b) {

        typedef std::map<GD::vertex_descriptor, GD::vertex_descriptor> node_map_t;
        node_map_t node_map;
        boost::associative_property_map<node_map_t> mapper(node_map);

        BDD c = *this;
        copy_graph(b.graph, c.graph, boost::orig_to_copy(mapper));

        int old_zero = node_map[b.zero];
        int old_one  = node_map[b.one];

        // copies the old one edges into the new graph
        c.merge_input_edges(c.one, old_one);
        boost::clear_vertex(old_one, c.graph);
        boost::remove_vertex(old_one, c.graph);

        // copies the old zero edges into the new graph
        c.merge_input_edges(c.zero, old_zero);
        boost::clear_vertex(old_zero, c.graph);
        boost::remove_vertex(old_zero, c.graph);

        c.source = c.conjunction_internal(c.source, node_map[c.source]);
        return c;

      }

      private:
      /**
       * Internal function that checks for all the cases
       * Accepts the nodes that must be conjoined
       * and returns the new source.
       */
      int conjunction_internal(int a, int b) {
        // TODO
        return 0;
      }

      int add_vertex(const std::string name) {
        int v = boost::add_vertex(graph);
        graph[v].input_name = name;
        graph[v].t          = Type::Input;
        return v;
      }

      void add_edge(int a, int b, NegP p) {
        boost::add_edge(a, b, p, graph);
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - changes zero and one
       */
      public:
      void reverse() {
        int aux = one;
        one = zero;
        zero = aux;

        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * merges the input edges of the node b into node a.
       */
      void merge_input_edges(int a, int b) {
        GD::in_edge_iterator e, end;
        for (boost::tie(e, end) = in_edges(b, graph); e != end; ++e) {
            int s = boost::source(*e, graph);
            add_edge(s, a, graph[*e]);
        }
      }

      std::map<int, std::vector<int> > find_layers() {
        // TODO
      }

      // Criar um hash o mais unico possivel para um bdd
      hashcode hash(int v) {
        // TODO
      }

      // Compares BDDs
      friend bool operator<(const BDD & bdd1, const BDD & bdd2) {
        // TODO
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - minimizes the BDD
       */
      void minimize() {
        // TODO
      }

      friend bool operator==(const BDD & bdd1, const BDD & bdd2) {
        return
          (bdd1.source == bdd2.source) &&
          (bdd1.one == bdd2.one) &&
          (bdd1.zero == bdd2.zero);
        // TODO &&
        //  (bdd1.graph == bdd2.graph);
      }
      friend bool operator!=(const BDD & bdd1, const BDD & bdd2) {
        return
          (bdd1.source != bdd2.source) &&
          (bdd1.one != bdd2.one) &&
          (bdd1.zero != bdd2.zero);
        // TODO&&
        //  (bdd1.graph != bdd2.graph);
      }

      public:
      int size() {
        int i = 0;
        GD::vertex_iterator n, e;
        for(boost::tie(n, e) = boost::vertices(graph);
            n != e; ++n) ++i;
        return i;
      }

      friend std::ostream& operator<<(std::ostream &o, const BDD & b) {

        o << "digraph G {\n" ;
        GD::vertex_iterator v, vend;
        for(boost::tie(v, vend) = boost::vertices(b.graph);
            v != vend; ++v) {
          switch(b.graph[*v].t) {
            case(Type::Input) : {
                o << *v << " [label=\""
                  << b.graph[*v].input_name
                  << "\", ";
                if (*v == b.source)
                  o << "shape=doublecircle];\n";
                else
                  o << "shape=circle];\n";
              break;
            }
            case(Type::One) : {
                o << *v << " [label=\"1\", shape=box]; \n";
              break;
            }
            case(Type::Zero) : {
                o << *v << " [label=\"0\", shape=box]; \n";
              break;
            }
          }
        }

        GD::edge_iterator e, eend;
        for(boost::tie(e, eend) = boost::edges(b.graph);
            e != eend; ++e) {
          int s = boost::source(*e, b.graph);
          int d = boost::target(*e, b.graph);

          o << s << "->" << d;
          switch(b.graph[*e]) {
            case(NegP::Positive): {
              o << " [style=solid];\n";
              break;
            }
            case(NegP::Negative): {
              o << " [style=dashed];\n";
              break;
            }
          }
        }

        o << "}\n" ;
        return o;
      }
    };
  }
}

<|endoftext|>


<commit_before>/*
Copyright 2014-2015 Adam Grandquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#ifndef REQL_REQL_CONNECTION_HPP_
#define REQL_REQL_CONNECTION_HPP_

#include "./reql/btree.hpp"
#include "./reql/types.hpp"

#include <memory>

namespace _ReQL {

static const char *DEFAULT_ADDR = "localhost";
static const char *DEFAULT_PORT = "30030";

template <class result_t, class str_t>
class Conn_t {
public:
  Conn_t() {}

  Conn_t(str_t &addr, str_t &port, str_t &auth) : p_cursors(addr, port, auth) {}

  void _connect() {
    return _connect(str_t(DEFAULT_ADDR));
  }

  void _connect(const str_t &addr) {
    return _connect(addr, str_t(DEFAULT_PORT), str_t(""));
  }

  void _connect(const str_t &addr, const str_t &port, const str_t &auth) {
    p_cursors.reset(new BTree_t<result_t, str_t>(addr, port, auth));
  }

  Conn_t(const Conn_t &other) : p_cursors(other.p_cursors) {}

  Conn_t(Conn_t &&other) : p_cursors(std::move(other.p_cursors)) {}

  Conn_t &operator =(const Conn_t &other) {
    if (this != &other) {
      p_cursors = other.p_cursors;
    }
    return *this;
  }

  Conn_t &operator =(Conn_t &&other) {
    if (this != &other) {
      p_cursors = std::move(other.p_cursors);
    }
    return *this;
  }

  bool isOpen() const {
    return p_cursors->isOpen();
  }

  template <class query_t, class func_t>
  void run(const query_t &query, func_t func) {
    p_cursors->run(query, func);
  }

  template <class kwargs_t, class query_t, class func_t>
  void run(const query_t &query, const kwargs_t &kwargs, func_t func) {
    p_cursors->run(query, kwargs, func);
  }

  template <class kwargs_t, class query_t>
  void noReply(const query_t &query, const kwargs_t &kwargs) {
    p_cursors->noReply(query, kwargs);
  }

  void noReplyWait() {
    p_cursors->noReplyWait();
  }

  void stop(ReQL_Token token) {
    p_cursors->stop(token);
  }

private:
  std::shared_ptr<BTree_t<result_t, str_t> > p_cursors;
};

}  // namespace _ReQL

#endif  // REQL_REQL_CONNECTION_HPP_
<commit_msg>Fix default port.<commit_after>/*
Copyright 2014-2015 Adam Grandquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#ifndef REQL_REQL_CONNECTION_HPP_
#define REQL_REQL_CONNECTION_HPP_

#include "./reql/btree.hpp"
#include "./reql/types.hpp"

#include <memory>

namespace _ReQL {

static const char *DEFAULT_ADDR = "localhost";
static const char *DEFAULT_PORT = "28015";

template <class result_t, class str_t>
class Conn_t {
public:
  Conn_t() {}

  Conn_t(str_t &addr, str_t &port, str_t &auth) : p_cursors(addr, port, auth) {}

  void _connect() {
    return _connect(str_t(DEFAULT_ADDR));
  }

  void _connect(const str_t &addr) {
    return _connect(addr, str_t(DEFAULT_PORT), str_t(""));
  }

  void _connect(const str_t &addr, const str_t &port, const str_t &auth) {
    p_cursors.reset(new BTree_t<result_t, str_t>(addr, port, auth));
  }

  Conn_t(const Conn_t &other) : p_cursors(other.p_cursors) {}

  Conn_t(Conn_t &&other) : p_cursors(std::move(other.p_cursors)) {}

  Conn_t &operator =(const Conn_t &other) {
    if (this != &other) {
      p_cursors = other.p_cursors;
    }
    return *this;
  }

  Conn_t &operator =(Conn_t &&other) {
    if (this != &other) {
      p_cursors = std::move(other.p_cursors);
    }
    return *this;
  }

  bool isOpen() const {
    return p_cursors->isOpen();
  }

  template <class query_t, class func_t>
  void run(const query_t &query, func_t func) {
    p_cursors->run(query, func);
  }

  template <class kwargs_t, class query_t, class func_t>
  void run(const query_t &query, const kwargs_t &kwargs, func_t func) {
    p_cursors->run(query, kwargs, func);
  }

  template <class kwargs_t, class query_t>
  void noReply(const query_t &query, const kwargs_t &kwargs) {
    p_cursors->noReply(query, kwargs);
  }

  void noReplyWait() {
    p_cursors->noReplyWait();
  }

  void stop(ReQL_Token token) {
    p_cursors->stop(token);
  }

private:
  std::shared_ptr<BTree_t<result_t, str_t> > p_cursors;
};

}  // namespace _ReQL

#endif  // REQL_REQL_CONNECTION_HPP_
<|endoftext|>


<commit_before>/*
Copyright 2014-2015 Adam Grandquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#ifndef REQL_REQL_CONNECTION_HPP_
#define REQL_REQL_CONNECTION_HPP_

#include "./reql/decode.hpp"
#include "./reql/protocol.hpp"
#include "./reql/query.hpp"

#include <condition_variable>
#include <cstdint>
#include <functional>
#include <future>
#include <forward_list>
#include <iterator>
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>

namespace _ReQL {

template <class result_t>
class Cursor_t : public std::iterator<std::input_iterator_tag, result_t> {
public:
  Cursor_t &begin() noexcept {
    return *this;
  }

  Cursor_t &cbegin() noexcept {
    return *this;
  }

  const Cursor_t &end() const {
    return *p_end;
  }

  const Cursor_t &cend() const {
    return *p_end;
  }

  Cursor_t &operator ++() {
    std::unique_lock<std::mutex> lock(p_mutex);
    return *this;
  }

  const result_t &operator *() const;

  const result_t &operator ->() const;

  bool operator ==(const Cursor_t &other) const { return p_token == other.p_token; }

  bool operator !=(const Cursor_t &other) const { return p_token != other.p_token; }

  Cursor_t(std::uint64_t token) : p_token(token) {
    std::promise<result_t> first;
    p_future = first.get_future();
    first.set_value(result_t());
  }

  enum Response_e {
    CLIENT_ERROR = 16,
    COMPILE_ERROR = 17,
    RUNTIME_ERROR = 18,
    SERVER_INFO = 5,
    SUCCESS_ATOM = 1,
    SUCCESS_PARTIAL = 3,
    SUCCESS_SEQUENCE = 2,
    WAIT_COMPLETE = 4
  };

  void set_value(const std::string &json) {
    std::thread([this, json] {
      Decoder_t<result_t> decoder;
      decoder.decode(json.c_str(), json.c_str() + json.size());
      switch (decoder.r_type()) {
        case SERVER_INFO:
        case SUCCESS_ATOM: {
          set_value(decoder.get()[0]);
          break;
        }
        case SUCCESS_PARTIAL:
        case SUCCESS_SEQUENCE: {
          for (auto &&elem : decoder.get()) {
            set_value(elem);
          }
          break;
        }
        case WAIT_COMPLETE: {
          set_value(result_t());
          break;
        }
        case CLIENT_ERROR:
        case COMPILE_ERROR:
        case RUNTIME_ERROR: {
          set_value(result_t(decoder.get()));
          break;
        }
        default: {
        }
      }
    }).detach();
  }

  void set_value(result_t result) {
    p_future.wait();
    std::promise<result_t> next;
    std::future<result_t> future = next.get_future();
    std::swap(next, p_next);
    std::swap(future, p_future);
    next.set_value(result);
  }

  std::condition_variable p_cond;
  //const Cursor_t p_end;
  std::future<result_t> p_future;
  std::mutex p_mutex;
  std::promise<result_t> p_next;
  const std::uint64_t p_token;
};

static const char *DEFAULT_ADDR = "localhost";
static const char *DEFAULT_PORT = "28015";

template <class auth_e, class handshake_e, class result_t, class socket_e>
class Conn_t {
public:
  void connect() {
    return connect(std::string(DEFAULT_ADDR));
  }

  void connect(const std::string &addr) {
    return connect(addr, std::string(DEFAULT_PORT), std::string(""));
  }

  void connect(const std::string &addr, const std::string &port) {
    return connect(addr, port, std::string(""));
  }

  void connect(const std::string &addr, const std::string &port, const std::string &auth) {
    p_protocol.connect(addr, port, auth, [this](const std::string &json, const std::uint64_t token) {
      std::lock_guard<std::mutex> lock(p_mutex);
      p_root[token]->set_value(json);
    });
  }

  bool isOpen() const {
    return p_protocol.connected();
  }

  void close() {
    p_protocol.disconnect();
  }

  template <class query_t>
  auto run(const query_t &query) {
    return create(p_protocol << make_query(query));
  }

  template <class kwargs_t, class query_t>
  auto run(const query_t &query, const kwargs_t &kwargs) {
    return create(p_protocol << make_query(query, kwargs));
  }

  template <class kwargs_t, class query_t>
  void noReply(const query_t &query, const kwargs_t &kwargs) {
    p_protocol << make_query(query, kwargs);
  }

  void noReplyWait() {
    (p_protocol << make_query((REQL_NOREPLY_WAIT)))([](const result_t &) {});
  }

  void stop(const std::uint64_t token) {
    p_protocol.stop(token);
  }

private:
  auto create(const std::uint64_t token) {
    Cursor_t<result_t> cursor(token);
    std::lock_guard<std::mutex> lock(p_mutex);
    std::make_shared<Cursor_t<result_t> >(token);
    p_root.insert({token, Cursor_t<result_t>(token)});
    return p_root[token];
  }

  std::mutex p_mutex;
  Protocol_t<auth_e, handshake_e, socket_e> p_protocol;
  std::map<std::uint64_t, std::shared_ptr<Cursor_t<result_t> > > p_root;
};

}  // namespace _ReQL

#endif  // REQL_REQL_CONNECTION_HPP_
<commit_msg>Fix cursor construction.<commit_after>/*
Copyright 2014-2015 Adam Grandquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
/**
 * @author Adam Grandquist
 * @copyright Apache
 */

#ifndef REQL_REQL_CONNECTION_HPP_
#define REQL_REQL_CONNECTION_HPP_

#include "./reql/decode.hpp"
#include "./reql/protocol.hpp"
#include "./reql/query.hpp"

#include <condition_variable>
#include <cstdint>
#include <functional>
#include <future>
#include <forward_list>
#include <iterator>
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>

namespace _ReQL {

template <class result_t>
class Cursor_t : public std::iterator<std::input_iterator_tag, result_t> {
public:
  Cursor_t &begin() noexcept {
    return *this;
  }

  Cursor_t &cbegin() noexcept {
    return *this;
  }

  const Cursor_t &end() const {
    return *p_end;
  }

  const Cursor_t &cend() const {
    return *p_end;
  }

  Cursor_t &operator ++() {
    std::unique_lock<std::mutex> lock(p_mutex);
    return *this;
  }

  const result_t &operator *() const;

  const result_t &operator ->() const;

  bool operator ==(const Cursor_t &other) const { return p_token == other.p_token; }

  bool operator !=(const Cursor_t &other) const { return p_token != other.p_token; }

  Cursor_t(std::uint64_t token) : p_token(token) {
    std::promise<result_t> first;
    p_future = first.get_future();
    first.set_value(result_t());
  }

  enum Response_e {
    CLIENT_ERROR = 16,
    COMPILE_ERROR = 17,
    RUNTIME_ERROR = 18,
    SERVER_INFO = 5,
    SUCCESS_ATOM = 1,
    SUCCESS_PARTIAL = 3,
    SUCCESS_SEQUENCE = 2,
    WAIT_COMPLETE = 4
  };

  void set_value(const std::string &json) {
    std::thread([this, json] {
      Decoder_t<result_t> decoder;
      decoder.decode(json.c_str(), json.c_str() + json.size());
      switch (decoder.r_type()) {
        case SERVER_INFO:
        case SUCCESS_ATOM: {
          set_value(decoder.get()[0]);
          break;
        }
        case SUCCESS_PARTIAL:
        case SUCCESS_SEQUENCE: {
          for (auto &&elem : decoder.get()) {
            set_value(elem);
          }
          break;
        }
        case WAIT_COMPLETE: {
          set_value(result_t());
          break;
        }
        case CLIENT_ERROR:
        case COMPILE_ERROR:
        case RUNTIME_ERROR: {
          set_value(result_t(decoder.get()));
          break;
        }
        default: {
        }
      }
    }).detach();
  }

  void set_value(result_t result) {
    p_future.wait();
    std::promise<result_t> next;
    std::future<result_t> future = next.get_future();
    std::swap(next, p_next);
    std::swap(future, p_future);
    next.set_value(result);
  }

  std::condition_variable p_cond;
  //const Cursor_t p_end;
  std::future<result_t> p_future;
  std::mutex p_mutex;
  std::promise<result_t> p_next;
  const std::uint64_t p_token;
};

static const char *DEFAULT_ADDR = "localhost";
static const char *DEFAULT_PORT = "28015";

template <class auth_e, class handshake_e, class result_t, class socket_e>
class Conn_t {
public:
  void connect() {
    return connect(std::string(DEFAULT_ADDR));
  }

  void connect(const std::string &addr) {
    return connect(addr, std::string(DEFAULT_PORT), std::string(""));
  }

  void connect(const std::string &addr, const std::string &port) {
    return connect(addr, port, std::string(""));
  }

  void connect(const std::string &addr, const std::string &port, const std::string &auth) {
    p_protocol.connect(addr, port, auth, [this](const std::string &json, const std::uint64_t token) {
      std::lock_guard<std::mutex> lock(p_mutex);
      p_root[token]->set_value(json);
    });
  }

  bool isOpen() const {
    return p_protocol.connected();
  }

  void close() {
    p_protocol.disconnect();
  }

  template <class query_t>
  auto run(const query_t &query) {
    return create(p_protocol << make_query(query));
  }

  template <class kwargs_t, class query_t>
  auto run(const query_t &query, const kwargs_t &kwargs) {
    return create(p_protocol << make_query(query, kwargs));
  }

  template <class kwargs_t, class query_t>
  void noReply(const query_t &query, const kwargs_t &kwargs) {
    p_protocol << make_query(query, kwargs);
  }

  void noReplyWait() {
    (p_protocol << make_query((REQL_NOREPLY_WAIT)))([](const result_t &) {});
  }

  void stop(const std::uint64_t token) {
    p_protocol.stop(token);
  }

private:
  auto create(const std::uint64_t token) {
    std::lock_guard<std::mutex> lock(p_mutex);
    p_root.insert({token, std::make_shared<Cursor_t<result_t> >(token)});
    return p_root[token];
  }

  std::mutex p_mutex;
  Protocol_t<auth_e, handshake_e, socket_e> p_protocol;
  std::map<std::uint64_t, std::shared_ptr<Cursor_t<result_t> > > p_root;
};

}  // namespace _ReQL

#endif  // REQL_REQL_CONNECTION_HPP_
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// 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 LTAC_JUMP_H
#define LTAC_JUMP_H

#include <vector>
#include <memory>

#include <boost/optional.hpp>

#include "ltac/forward.hpp"

namespace eddic {

class Function;

namespace ltac {

enum struct JumpType : unsigned int {
    ALWAYS,

    CALL,

    //Egality
    NE,
    E,

    //signed comparisons
    GE,
    G,
    LE,
    L,

    //unsigned comparisons
    B,
    BE,
    A,
    AE,

    P,      //Parity
    Z,      //Zero
    NZ      //Not zero
};

struct Jump {
    std::string label;
    JumpType type;
    eddic::Function* target_function; //Only if a call

    std::vector<ltac::PseudoRegister> uses;
    std::vector<ltac::PseudoFloatRegister> float_uses;

    std::vector<ltac::PseudoRegister> kills;
    std::vector<ltac::PseudoFloatRegister> float_kills;

    std::vector<ltac::Register> hard_uses;
    std::vector<ltac::FloatRegister> hard_float_uses;

    std::vector<ltac::Register> hard_kills;
    std::vector<ltac::FloatRegister> hard_float_kills;

    Jump();
    Jump(const std::string& label, JumpType type);
};

} //end of ltac

} //end of eddic

#endif
<commit_msg>Clean includes<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// 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 LTAC_JUMP_H
#define LTAC_JUMP_H

#include <vector>

#include "ltac/forward.hpp"

namespace eddic {

class Function;

namespace ltac {

enum struct JumpType : unsigned int {
    ALWAYS,

    CALL,

    //Egality
    NE,
    E,

    //signed comparisons
    GE,
    G,
    LE,
    L,

    //unsigned comparisons
    B,
    BE,
    A,
    AE,

    P,      //Parity
    Z,      //Zero
    NZ      //Not zero
};

struct Jump {
    std::string label;
    JumpType type;
    eddic::Function* target_function; //Only if a call

    std::vector<ltac::PseudoRegister> uses;
    std::vector<ltac::PseudoFloatRegister> float_uses;

    std::vector<ltac::PseudoRegister> kills;
    std::vector<ltac::PseudoFloatRegister> float_kills;

    std::vector<ltac::Register> hard_uses;
    std::vector<ltac::FloatRegister> hard_float_uses;

    std::vector<ltac::Register> hard_kills;
    std::vector<ltac::FloatRegister> hard_float_kills;

    Jump();
    Jump(const std::string& label, JumpType type);
};

} //end of ltac

} //end of eddic

#endif
<|endoftext|>


<commit_before>#ifndef OBJ_HPP
#define OBJ_HPP

#include <vector>
#include <memory>
#include <GL/gl3w.h>

namespace Model {
	/*! An enumeration of supported types */
	typedef enum {
		e_el_c=0,  ///< \ref element_t
		e_el_f,    ///< \ref face_t
		e_el_g,    ///< \ref group_t
		e_el_l,    ///< \ref line_t
		e_el_m,    ///< \ref mtllib_t
		e_el_o,    ///< \ref object_t
		e_el_s,    ///< \ref smooth_t
		e_el_u,    ///< \ref usemtl_t
		e_el_v,    ///< \ref vertex_t
		e_el_vn,   ///< \ref vertex_norm_t
		e_el_vp,   ///< \ref vertex_param_t
		e_el_total ///< The total number of supported types
	} e_el;

	/// The abstract base of each obj element
	template<e_el type>
	struct element_t {
		static constexpr const char *prefix = "";
		virtual ~element_t(void) {}
	};

	/// A comment, used only for storage
	template<> struct element_t<e_el_c> {
		static constexpr const char *prefix = "#";
	};

	/// A set of vertices with or without texture coordinates
	template<> struct element_t<e_el_f> {
		static constexpr const char *prefix = "f";
	};

	/// A collection of faces, lines, and vertices
	template<> struct element_t<e_el_g> {
		static constexpr const char *prefix = "g";
	};

	/// A pair of vertex indices
	template<> struct element_t<e_el_l> {
		static constexpr const char *prefix = "l";
	};

	/// A material library file
	template<> struct element_t<e_el_m> {
		static constexpr const char *prefix = "mtllib";
	};

	/// An object; see \ref group_t
	template<> struct element_t<e_el_o> {
		static constexpr const char *prefix = "o";
	};

	/// Smooth shading option
	template<> struct element_t<e_el_s> {
		static constexpr const char *prefix = "s";
	};

	/// A reference to a loaded material
	template<> struct element_t<e_el_u> {
		static constexpr const char *prefix = "usemtl";
	};

	/// A single point, containing at least x, y, z coordinates
	template<> struct element_t<e_el_v> {
		static constexpr const char *prefix = "v";
	};

	/// A normal vector; coordinates x, y, z
	template<> struct element_t<e_el_vn> {
		static constexpr const char *prefix = "vn";
	};

	/// A single point in parameter space; coordinates u[, v [,w]]
	template<> struct element_t<e_el_vp> {
		static constexpr const char *prefix = "vp";
	};

	inline std::ostream& operator<<(std::ostream& lhs, e_el const& rhs) {
		return lhs << std::string(rhs == e_el_c ? element_t<e_el_c>::prefix
				: rhs == e_el_f ? element_t<e_el_f>::prefix
				: rhs == e_el_g ? element_t<e_el_g>::prefix
				: rhs == e_el_l ? element_t<e_el_l>::prefix
				: rhs == e_el_m ? element_t<e_el_m>::prefix
				: rhs == e_el_o ? element_t<e_el_o>::prefix
				: rhs == e_el_s ? element_t<e_el_s>::prefix
				: rhs == e_el_u ? element_t<e_el_u>::prefix
				: rhs == e_el_v ? element_t<e_el_v>::prefix
				: rhs == e_el_vn ? element_t<e_el_vn>::prefix
				: element_t<e_el_vp>::prefix);
	}

	/// A wavefront object container/parser
	struct obj_t {
		/*! The enumeration and count of possible states */
		typedef enum {
			e_ok=0,        ///< Parsing status is OK
			e_err_io,      ///< An IO exception has occurred
			e_err_unknown, ///< An unknown exception has occurred
			e_err_total    ///< The total number of statuses
		} e_status;

		static constexpr const unsigned int
			mask_has_floats = (1<<e_el_v) | (1<<e_el_vn) | (1<<e_el_vp),
			mask_has_ints = (1<<e_el_f) | (1<<e_el_l),
			mask_has_strings = (1<<e_el_c) | (1<<e_el_g)
				| (1<<e_el_m) | (1<<e_el_o) | (1<<e_el_u);

		/** Loads an obj file with the given path into a vector of elements
		 * @param fname The path to the obj file
		 * @param elements The destination, a vector of elements
		 * @return e_status_ok (0) if and only if the load was successful
		 */
		static e_status load(const char *fname, obj_t &elements);
		static e_el parse_type(std::string word);
		e_status parse(std::string line, const char *delim = " ");

		std::vector<std::string> strings;
		std::vector<GLint> ints;
		std::vector<GLfloat> floats;
		std::vector<GLuint> nStrings, nInts, nFloats;
		std::vector<e_el> types;
	};

}

#endif
<commit_msg>Added handling for zero-data types<commit_after>#ifndef OBJ_HPP
#define OBJ_HPP

#include <vector>
#include <memory>
#include <GL/gl3w.h>

namespace Model {
	/*! An enumeration of supported types */
	typedef enum {
		e_el_c=0,  ///< \ref element_t
		e_el_f,    ///< \ref face_t
		e_el_g,    ///< \ref group_t
		e_el_l,    ///< \ref line_t
		e_el_m,    ///< \ref mtllib_t
		e_el_o,    ///< \ref object_t
		e_el_s,    ///< \ref smooth_t
		e_el_u,    ///< \ref usemtl_t
		e_el_v,    ///< \ref vertex_t
		e_el_vn,   ///< \ref vertex_norm_t
		e_el_vp,   ///< \ref vertex_param_t
		e_el_total ///< The total number of supported types
	} e_el;

	/// The abstract base of each obj element
	template<e_el type>
	struct element_t {
		static constexpr const char *prefix = "";
		virtual ~element_t(void) {}
	};

	/// A comment, used only for storage
	template<> struct element_t<e_el_c> {
		static constexpr const char *prefix = "#";
	};

	/// A set of vertices with or without texture coordinates
	template<> struct element_t<e_el_f> {
		static constexpr const char *prefix = "f";
	};

	/// A collection of faces, lines, and vertices
	template<> struct element_t<e_el_g> {
		static constexpr const char *prefix = "g";
	};

	/// A pair of vertex indices
	template<> struct element_t<e_el_l> {
		static constexpr const char *prefix = "l";
	};

	/// A material library file
	template<> struct element_t<e_el_m> {
		static constexpr const char *prefix = "mtllib";
	};

	/// An object; see \ref group_t
	template<> struct element_t<e_el_o> {
		static constexpr const char *prefix = "o";
	};

	/// Smooth shading option
	template<> struct element_t<e_el_s> {
		static constexpr const char *prefix = "s";
	};

	/// A reference to a loaded material
	template<> struct element_t<e_el_u> {
		static constexpr const char *prefix = "usemtl";
	};

	/// A single point, containing at least x, y, z coordinates
	template<> struct element_t<e_el_v> {
		static constexpr const char *prefix = "v";
	};

	/// A normal vector; coordinates x, y, z
	template<> struct element_t<e_el_vn> {
		static constexpr const char *prefix = "vn";
	};

	/// A single point in parameter space; coordinates u[, v [,w]]
	template<> struct element_t<e_el_vp> {
		static constexpr const char *prefix = "vp";
	};

	inline std::ostream& operator<<(std::ostream& lhs, e_el const& rhs) {
		return lhs << std::string(rhs == e_el_c ? element_t<e_el_c>::prefix
				: rhs == e_el_f ? element_t<e_el_f>::prefix
				: rhs == e_el_g ? element_t<e_el_g>::prefix
				: rhs == e_el_l ? element_t<e_el_l>::prefix
				: rhs == e_el_m ? element_t<e_el_m>::prefix
				: rhs == e_el_o ? element_t<e_el_o>::prefix
				: rhs == e_el_s ? element_t<e_el_s>::prefix
				: rhs == e_el_u ? element_t<e_el_u>::prefix
				: rhs == e_el_v ? element_t<e_el_v>::prefix
				: rhs == e_el_vn ? element_t<e_el_vn>::prefix
				: element_t<e_el_vp>::prefix);
	}

	/// A wavefront object container/parser
	struct obj_t {
		/*! The enumeration and count of possible states */
		typedef enum {
			e_ok=0,        ///< Parsing status is OK
			e_err_io,      ///< An IO exception has occurred
			e_err_unknown, ///< An unknown exception has occurred
			e_err_total    ///< The total number of statuses
		} e_status;

		static constexpr const unsigned int
			mask_has_floats = (1<<e_el_v) | (1<<e_el_vn) | (1<<e_el_vp),
			mask_has_ints = (1<<e_el_f) | (1<<e_el_l),
			mask_has_strings = (1<<e_el_c) | (1<<e_el_g)
				| (1<<e_el_m) | (1<<e_el_o) | (1<<e_el_s) | (1<<e_el_u);

		/** Loads an obj file with the given path into a vector of elements
		 * @param fname The path to the obj file
		 * @param elements The destination, a vector of elements
		 * @return e_status_ok (0) if and only if the load was successful
		 */
		static e_status load(const char *fname, obj_t &elements);
		static e_el parse_type(std::string word);
		e_status parse(std::string line, const char *delim = " ");

		std::vector<std::string> strings;
		std::vector<GLint> ints;
		std::vector<GLfloat> floats;
		std::vector<GLuint> nStrings, nInts, nFloats;
		std::vector<e_el> types;
	};

}

#endif
<|endoftext|>


<commit_before>#ifndef OCCA_TOOLS_HEADER
#define OCCA_TOOLS_HEADER

#include <iostream>
// cry

namespace occa {
  class kernelInfo;

  std::string fnv(const std::string &filename);

  std::string readFile(const std::string &filename);

  std::string binaryIsCached(const std::string &filename,
                             const std::string &salt);

  std::string createIntermediateSource(const std::string &filename,
                                       const std::string &cachedBinary,
                                       const kernelInfo &info);
};

#endif
<commit_msg>Added missing header (clang++ auto-adds stuff)<commit_after>#ifndef OCCA_TOOLS_HEADER
#define OCCA_TOOLS_HEADER

#include <iostream>
#include <stdlib.h>

namespace occa {
  class kernelInfo;

  std::string fnv(const std::string &filename);

  std::string readFile(const std::string &filename);

  std::string binaryIsCached(const std::string &filename,
                             const std::string &salt);

  std::string createIntermediateSource(const std::string &filename,
                                       const std::string &cachedBinary,
                                       const kernelInfo &info);
};

#endif
<|endoftext|>


<commit_before>#include "shared_handlers.h"
#include "can/canwrite.h"
#include "util/log.h"

#define OCCUPANCY_STATUS_GENERIC_NAME "occupancy_status"

float rotationsSinceRestart = 0;
float rollingOdometerSinceRestart = 0;
float totalOdometerAtRestart = 0;
float fuelConsumedSinceRestartLiters = 0;

namespace can = openxc::can;

using openxc::can::read::booleanHandler;
using openxc::can::read::stateHandler;
using openxc::can::read::sendEventedBooleanMessage;
using openxc::can::read::sendEventedFloatMessage;
using openxc::can::read::sendEventedStringMessage;
using openxc::can::read::sendNumericalMessage;
using openxc::can::read::preTranslate;
using openxc::can::read::postTranslate;
using openxc::can::write::booleanWriter;
using openxc::can::write::sendSignal;
using openxc::can::lookupSignal;

const float openxc::signals::handlers::LITERS_PER_GALLON = 3.78541178;
const float openxc::signals::handlers::LITERS_PER_UL = .000001;
const float openxc::signals::handlers::KM_PER_MILE = 1.609344;
const float openxc::signals::handlers::KM_PER_M = .001;
const char* openxc::signals::handlers::DOOR_STATUS_GENERIC_NAME = "door_status";
const char* openxc::signals::handlers::BUTTON_EVENT_GENERIC_NAME = "button_event";
const char* openxc::signals::handlers::TIRE_PRESSURE_GENERIC_NAME = "tire_pressure";

#ifndef __PIC32__
const float openxc::signals::handlers::PI = 3.14159265;
#endif

void openxc::signals::handlers::sendDoorStatus(const char* doorId, uint64_t data, CanSignal* signal,
        CanSignal* signals, int signalCount, Pipeline* pipeline) {
    if(signal == NULL) {
        debug("Specific door signal for ID %s is NULL, vehicle may not support",
                doorId);
        return;
    }

    float rawAjarStatus = can::read::decodeSignal(signal, data);
    bool send = true;
    bool ajarStatus = booleanHandler(NULL, signals, signalCount, rawAjarStatus,
            &send);

    if(send && (signal->sendSame || !signal->received ||
                rawAjarStatus != signal->lastValue)) {
        signal->received = true;
        sendEventedBooleanMessage(DOOR_STATUS_GENERIC_NAME, doorId, ajarStatus,
                pipeline);
    }
    signal->lastValue = rawAjarStatus;
}

void openxc::signals::handlers::handleDoorStatusMessage(int messageId, uint64_t data, CanSignal* signals,
        int signalCount, Pipeline* pipeline) {
    sendDoorStatus("driver", data,
            lookupSignal("driver_door", signals, signalCount),
            signals, signalCount, pipeline);
    sendDoorStatus("passenger", data,
            lookupSignal("passenger_door", signals, signalCount),
            signals, signalCount, pipeline);
    sendDoorStatus("rear_right", data,
            lookupSignal("rear_right_door", signals, signalCount),
            signals, signalCount, pipeline);
    sendDoorStatus("rear_left", data,
            lookupSignal("rear_left_door", signals, signalCount),
            signals, signalCount, pipeline);
}

void openxc::signals::handlers::sendTirePressure(const char* tireId, uint64_t data, CanSignal* signal,
        CanSignal* signals, int signalCount, Pipeline* pipeline) {
    if(signal == NULL) {
        debug("Specific tire signal for ID %s is NULL, vehicle may not support",
                tireId);
        return;
    }

    bool send = true;
    // TODO use preTranslate for sendDoorStatus, too
    float pressure = preTranslate(signal, data, &send);
    if(send) {
        sendEventedFloatMessage(TIRE_PRESSURE_GENERIC_NAME, tireId, pressure,
                pipeline);
    }
    postTranslate(signal, pressure);
}

void openxc::signals::handlers::handleTirePressureMessage(int messageId, uint64_t data, CanSignal* signals,
        int signalCount, Pipeline* pipeline) {
    sendTirePressure("front_left", data,
            lookupSignal("tire_pressure_front_left", signals, signalCount),
            signals, signalCount, pipeline);
    sendTirePressure("front_right", data,
            lookupSignal("tire_pressure_front_right", signals, signalCount),
            signals, signalCount, pipeline);
    sendTirePressure("rear_right", data,
            lookupSignal("tire_pressure_rear_right", signals, signalCount),
            signals, signalCount, pipeline);
    sendTirePressure("rear_left", data,
            lookupSignal("tire_pressure_rear_left", signals, signalCount),
            signals, signalCount, pipeline);
}

float firstReceivedOdometerValue(CanSignal* signals, int signalCount) {
    if(totalOdometerAtRestart == 0) {
        CanSignal* odometerSignal = lookupSignal("total_odometer", signals,
                signalCount);
        if(odometerSignal != NULL && odometerSignal->received) {
            totalOdometerAtRestart = odometerSignal->lastValue;
        }
    }
    return totalOdometerAtRestart;
}

float handleRollingOdometer(CanSignal* signal, CanSignal* signals,
       int signalCount, float value, bool* send, float factor) {
    if(value < signal->lastValue) {
        rollingOdometerSinceRestart += signal->maxValue - signal->lastValue
            + value;
    } else {
        rollingOdometerSinceRestart += value - signal->lastValue;
    }

    return firstReceivedOdometerValue(signals, signalCount) +
        (factor * rollingOdometerSinceRestart);
}

float openxc::signals::handlers::handleRollingOdometerKilometers(CanSignal* signal, CanSignal* signals,
       int signalCount, float value, bool* send) {
    return handleRollingOdometer(signal, signals, signalCount, value, send, 1);
}

float openxc::signals::handlers::handleRollingOdometerMiles(CanSignal* signal, CanSignal* signals,
       int signalCount, float value, bool* send) {
    return handleRollingOdometer(signal, signals, signalCount, value, send,
            KM_PER_MILE);
}

float openxc::signals::handlers::handleRollingOdometerMeters(CanSignal* signal, CanSignal* signals,
       int signalCount, float value, bool* send) {
    return handleRollingOdometer(signal, signals, signalCount, value, send,
            KM_PER_M);
}

bool openxc::signals::handlers::handleStrictBoolean(CanSignal* signal, CanSignal* signals, int signalCount,
        float value, bool* send) {
    if(value != 0) {
        return true;
    }
    return false;
}

float openxc::signals::handlers::handleFuelFlow(CanSignal* signal, CanSignal* signals, int signalCount,
        float value, bool* send, float multiplier) {
    if(value < signal->lastValue) {
        value = signal->maxValue - signal->lastValue + value;
    } else {
        value = value - signal->lastValue;
    }
    fuelConsumedSinceRestartLiters += multiplier * value;
    return fuelConsumedSinceRestartLiters;
}

float openxc::signals::handlers::handleFuelFlowGallons(CanSignal* signal, CanSignal* signals,
        int signalCount, float value, bool* send) {
    return handleFuelFlow(signal, signals, signalCount, value, send,
            LITERS_PER_GALLON);
}

float openxc::signals::handlers::handleFuelFlowMicroliters(CanSignal* signal, CanSignal* signals,
        int signalCount, float value, bool* send) {
    return handleFuelFlow(signal, signals, signalCount, value, send,
            LITERS_PER_UL);
}

float openxc::signals::handlers::handleInverted(CanSignal* signal, CanSignal* signals, int signalCount,
        float value, bool* send) {
    return value * -1;
}

void openxc::signals::handlers::handleGpsMessage(int messageId, uint64_t data, CanSignal* signals,
        int signalCount, Pipeline* pipeline) {
    float latitudeDegrees = can::read::decodeSignal(
            lookupSignal("latitude_degrees", signals, signalCount), data);
    float latitudeMinutes = can::read::decodeSignal(
            lookupSignal("latitude_minutes", signals, signalCount), data);
    float latitudeMinuteFraction = can::read::decodeSignal(
            lookupSignal("latitude_minute_fraction", signals, signalCount),
            data);
    float longitudeDegrees = can::read::decodeSignal(
            lookupSignal("longitude_degrees", signals, signalCount), data);
    float longitudeMinutes = can::read::decodeSignal(
            lookupSignal("longitude_minutes", signals, signalCount), data);
    float longitudeMinuteFraction = can::read::decodeSignal(
            lookupSignal("longitude_minute_fraction", signals, signalCount),
            data);

    latitudeMinutes = (latitudeMinutes + latitudeMinuteFraction) / 60.0;
    if(latitudeDegrees < 0) {
        latitudeMinutes *= -1;
    }
    latitudeDegrees += latitudeMinutes;

    longitudeMinutes = (longitudeMinutes + longitudeMinuteFraction) / 60.0;
    if(longitudeDegrees < 0) {
        longitudeMinutes *= -1;
    }
    longitudeDegrees += longitudeMinutes;

    sendNumericalMessage("latitude", latitudeDegrees, pipeline);
    sendNumericalMessage("longitude", longitudeDegrees, pipeline);
}

bool openxc::signals::handlers::handleExteriorLightSwitch(CanSignal* signal, CanSignal* signals,
            int signalCount, float value, bool* send) {
    return value == 2 || value == 3;
}

float openxc::signals::handlers::handleUnsignedSteeringWheelAngle(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    CanSignal* steeringAngleSign = lookupSignal("steering_wheel_angle_sign",
            signals, signalCount);

    if(steeringAngleSign == NULL) {
        debug("Unable to find stering wheel angle sign signal");
        *send = false;
    } else {
        if(steeringAngleSign->lastValue == 0) {
            // left turn
            value *= -1;
        }
    }
    return value;
}

float openxc::signals::handlers::handleMultisizeWheelRotationCount(CanSignal* signal, CanSignal* signals,
        int signalCount, float value, bool* send, float wheelRadius) {
    if(value < signal->lastValue) {
        rotationsSinceRestart += signal->maxValue - signal->lastValue + value;
    } else {
        rotationsSinceRestart += value - signal->lastValue;
    }
    return firstReceivedOdometerValue(signals, signalCount) + (2 * PI *
            wheelRadius * rotationsSinceRestart);
}

void openxc::signals::handlers::handleButtonEventMessage(int messageId, uint64_t data,
        CanSignal* signals, int signalCount, Pipeline* pipeline) {
    CanSignal* buttonTypeSignal = lookupSignal("button_type", signals,
            signalCount);
    CanSignal* buttonStateSignal = lookupSignal("button_state", signals,
            signalCount);

    if(buttonTypeSignal == NULL || buttonStateSignal == NULL) {
        debug("Unable to find button type and state signals");
        return;
    }

    float rawButtonType = can::read::decodeSignal(buttonTypeSignal, data);
    float rawButtonState = can::read::decodeSignal(buttonStateSignal, data);

    bool send = true;
    const char* buttonType = stateHandler(buttonTypeSignal, signals,
            signalCount, rawButtonType, &send);
    if(!send || buttonType == NULL) {
        debug("Unable to find button type corresponding to %f",
                rawButtonType);
        return;
    }

    const char* buttonState = stateHandler(buttonStateSignal, signals,
            signalCount, rawButtonState, &send);
    if(!send || buttonState == NULL) {
        debug("Unable to find button state corresponding to %f",
                rawButtonState);
        return;
    }

    sendEventedStringMessage(BUTTON_EVENT_GENERIC_NAME, buttonType,
            buttonState, pipeline);
}

bool openxc::signals::handlers::handleTurnSignalCommand(const char* name, cJSON* value, cJSON* event,
        CanSignal* signals, int signalCount) {
    const char* direction = value->valuestring;
    CanSignal* signal = NULL;
    if(!strcmp("left", direction)) {
        signal = lookupSignal("turn_signal_left", signals, signalCount);
    } else if(!strcmp("right", direction)) {
        signal = lookupSignal("turn_signal_right", signals, signalCount);
    }

    if(signal != NULL) {
        return can::write::sendSignal(signal, cJSON_CreateBool(true), booleanWriter,
                signals, signalCount, true);
    } else {
        debug("Unable to find signal for %s turn signal", direction);
    }
    return false;
}

void sendOccupancyStatus(const char* seatId, uint64_t data,
        CanSignal* lowerSignal, CanSignal* upperSignal,
        CanSignal* signals, int signalCount, Pipeline* pipeline) {
    if(lowerSignal == NULL || upperSignal == NULL) {
        debug("Upper or lower occupancy signal for seat ID %s is NULL, "
                "vehicle may not support", seatId);
        return;
    }

    float rawLowerStatus = can::read::decodeSignal(lowerSignal, data);
    float rawUpperStatus = can::read::decodeSignal(upperSignal, data);

    bool send = true;
    bool lowerStatus = booleanHandler(NULL, signals, signalCount,
            rawLowerStatus, &send);
    bool upperStatus = booleanHandler(NULL, signals, signalCount,
            rawUpperStatus, &send);
    if(lowerStatus) {
        if(upperStatus) {
            sendEventedStringMessage(OCCUPANCY_STATUS_GENERIC_NAME, seatId,
                    "adult", pipeline);
        } else {
            sendEventedStringMessage(OCCUPANCY_STATUS_GENERIC_NAME, seatId,
                    "child", pipeline);
        }
    } else {
        sendEventedStringMessage(OCCUPANCY_STATUS_GENERIC_NAME, seatId,
                "empty", pipeline);
    }
}

void openxc::signals::handlers::handleOccupancyMessage(int messageId, uint64_t data, CanSignal* signals,
        int signalCount, Pipeline* pipeline) {
    sendOccupancyStatus("driver", data,
            lookupSignal("driver_occupancy_lower", signals, signalCount),
            lookupSignal("driver_occupancy_upper", signals, signalCount),
            signals, signalCount, pipeline);
    sendOccupancyStatus("passenger", data,
            lookupSignal("passenger_occupancy_lower", signals, signalCount),
            lookupSignal("passenger_occupancy_upper", signals, signalCount),
            signals, signalCount, pipeline);
}
<commit_msg>Wrap lines at 80 chars.<commit_after>#include "shared_handlers.h"
#include "can/canwrite.h"
#include "util/log.h"

#define OCCUPANCY_STATUS_GENERIC_NAME "occupancy_status"

float rotationsSinceRestart = 0;
float rollingOdometerSinceRestart = 0;
float totalOdometerAtRestart = 0;
float fuelConsumedSinceRestartLiters = 0;

namespace can = openxc::can;

using openxc::can::read::booleanHandler;
using openxc::can::read::stateHandler;
using openxc::can::read::sendEventedBooleanMessage;
using openxc::can::read::sendEventedFloatMessage;
using openxc::can::read::sendEventedStringMessage;
using openxc::can::read::sendNumericalMessage;
using openxc::can::read::preTranslate;
using openxc::can::read::postTranslate;
using openxc::can::write::booleanWriter;
using openxc::can::write::sendSignal;
using openxc::can::lookupSignal;

const float openxc::signals::handlers::LITERS_PER_GALLON = 3.78541178;
const float openxc::signals::handlers::LITERS_PER_UL = .000001;
const float openxc::signals::handlers::KM_PER_MILE = 1.609344;
const float openxc::signals::handlers::KM_PER_M = .001;
const char* openxc::signals::handlers::DOOR_STATUS_GENERIC_NAME = "door_status";
const char* openxc::signals::handlers::BUTTON_EVENT_GENERIC_NAME = "button_event";
const char* openxc::signals::handlers::TIRE_PRESSURE_GENERIC_NAME = "tire_pressure";

#ifndef __PIC32__
const float openxc::signals::handlers::PI = 3.14159265;
#endif

void openxc::signals::handlers::sendDoorStatus(const char* doorId,
        uint64_t data, CanSignal* signal, CanSignal* signals, int signalCount,
        Pipeline* pipeline) {
    if(signal == NULL) {
        debug("Specific door signal for ID %s is NULL, vehicle may not support",
                doorId);
        return;
    }

    float rawAjarStatus = can::read::decodeSignal(signal, data);
    bool send = true;
    bool ajarStatus = booleanHandler(NULL, signals, signalCount, rawAjarStatus,
            &send);

    if(send && (signal->sendSame || !signal->received ||
                rawAjarStatus != signal->lastValue)) {
        signal->received = true;
        sendEventedBooleanMessage(DOOR_STATUS_GENERIC_NAME, doorId, ajarStatus,
                pipeline);
    }
    signal->lastValue = rawAjarStatus;
}

void openxc::signals::handlers::handleDoorStatusMessage(int messageId,
        uint64_t data, CanSignal* signals, int signalCount,
        Pipeline* pipeline) {
    sendDoorStatus("driver", data,
            lookupSignal("driver_door", signals, signalCount),
            signals, signalCount, pipeline);
    sendDoorStatus("passenger", data,
            lookupSignal("passenger_door", signals, signalCount),
            signals, signalCount, pipeline);
    sendDoorStatus("rear_right", data,
            lookupSignal("rear_right_door", signals, signalCount),
            signals, signalCount, pipeline);
    sendDoorStatus("rear_left", data,
            lookupSignal("rear_left_door", signals, signalCount),
            signals, signalCount, pipeline);
}

void openxc::signals::handlers::sendTirePressure(const char* tireId,
        uint64_t data, CanSignal* signal, CanSignal* signals,
        int signalCount, Pipeline* pipeline) {
    if(signal == NULL) {
        debug("Specific tire signal for ID %s is NULL, vehicle may not support",
                tireId);
        return;
    }

    bool send = true;
    // TODO use preTranslate for sendDoorStatus, too
    float pressure = preTranslate(signal, data, &send);
    if(send) {
        sendEventedFloatMessage(TIRE_PRESSURE_GENERIC_NAME, tireId, pressure,
                pipeline);
    }
    postTranslate(signal, pressure);
}

void openxc::signals::handlers::handleTirePressureMessage(int messageId,
        uint64_t data, CanSignal* signals, int signalCount,
        Pipeline* pipeline) {
    sendTirePressure("front_left", data,
            lookupSignal("tire_pressure_front_left", signals, signalCount),
            signals, signalCount, pipeline);
    sendTirePressure("front_right", data,
            lookupSignal("tire_pressure_front_right", signals, signalCount),
            signals, signalCount, pipeline);
    sendTirePressure("rear_right", data,
            lookupSignal("tire_pressure_rear_right", signals, signalCount),
            signals, signalCount, pipeline);
    sendTirePressure("rear_left", data,
            lookupSignal("tire_pressure_rear_left", signals, signalCount),
            signals, signalCount, pipeline);
}

float firstReceivedOdometerValue(CanSignal* signals, int signalCount) {
    if(totalOdometerAtRestart == 0) {
        CanSignal* odometerSignal = lookupSignal("total_odometer", signals,
                signalCount);
        if(odometerSignal != NULL && odometerSignal->received) {
            totalOdometerAtRestart = odometerSignal->lastValue;
        }
    }
    return totalOdometerAtRestart;
}

float handleRollingOdometer(CanSignal* signal, CanSignal* signals,
       int signalCount, float value, bool* send, float factor) {
    if(value < signal->lastValue) {
        rollingOdometerSinceRestart += signal->maxValue - signal->lastValue
            + value;
    } else {
        rollingOdometerSinceRestart += value - signal->lastValue;
    }

    return firstReceivedOdometerValue(signals, signalCount) +
        (factor * rollingOdometerSinceRestart);
}

float openxc::signals::handlers::handleRollingOdometerKilometers(
        CanSignal* signal, CanSignal* signals, int signalCount, float value,
        bool* send) {
    return handleRollingOdometer(signal, signals, signalCount, value, send, 1);
}

float openxc::signals::handlers::handleRollingOdometerMiles(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    return handleRollingOdometer(signal, signals, signalCount, value, send,
            KM_PER_MILE);
}

float openxc::signals::handlers::handleRollingOdometerMeters(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    return handleRollingOdometer(signal, signals, signalCount, value, send,
            KM_PER_M);
}

bool openxc::signals::handlers::handleStrictBoolean(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    if(value != 0) {
        return true;
    }
    return false;
}

float openxc::signals::handlers::handleFuelFlow(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send,
        float multiplier) {
    if(value < signal->lastValue) {
        value = signal->maxValue - signal->lastValue + value;
    } else {
        value = value - signal->lastValue;
    }
    fuelConsumedSinceRestartLiters += multiplier * value;
    return fuelConsumedSinceRestartLiters;
}

float openxc::signals::handlers::handleFuelFlowGallons(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    return handleFuelFlow(signal, signals, signalCount, value, send,
            LITERS_PER_GALLON);
}

float openxc::signals::handlers::handleFuelFlowMicroliters(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    return handleFuelFlow(signal, signals, signalCount, value, send,
            LITERS_PER_UL);
}

float openxc::signals::handlers::handleInverted(CanSignal* signal, CanSignal*
        signals, int signalCount, float value, bool* send) {
    return value * -1;
}

void openxc::signals::handlers::handleGpsMessage(int messageId, uint64_t data,
        CanSignal* signals, int signalCount, Pipeline* pipeline) {
    float latitudeDegrees = can::read::decodeSignal(
            lookupSignal("latitude_degrees", signals, signalCount), data);
    float latitudeMinutes = can::read::decodeSignal(
            lookupSignal("latitude_minutes", signals, signalCount), data);
    float latitudeMinuteFraction = can::read::decodeSignal(
            lookupSignal("latitude_minute_fraction", signals, signalCount),
            data);
    float longitudeDegrees = can::read::decodeSignal(
            lookupSignal("longitude_degrees", signals, signalCount), data);
    float longitudeMinutes = can::read::decodeSignal(
            lookupSignal("longitude_minutes", signals, signalCount), data);
    float longitudeMinuteFraction = can::read::decodeSignal(
            lookupSignal("longitude_minute_fraction", signals, signalCount),
            data);

    latitudeMinutes = (latitudeMinutes + latitudeMinuteFraction) / 60.0;
    if(latitudeDegrees < 0) {
        latitudeMinutes *= -1;
    }
    latitudeDegrees += latitudeMinutes;

    longitudeMinutes = (longitudeMinutes + longitudeMinuteFraction) / 60.0;
    if(longitudeDegrees < 0) {
        longitudeMinutes *= -1;
    }
    longitudeDegrees += longitudeMinutes;

    sendNumericalMessage("latitude", latitudeDegrees, pipeline);
    sendNumericalMessage("longitude", longitudeDegrees, pipeline);
}

bool openxc::signals::handlers::handleExteriorLightSwitch(CanSignal* signal,
        CanSignal* signals, int signalCount, float value, bool* send) {
    return value == 2 || value == 3;
}

float openxc::signals::handlers::handleUnsignedSteeringWheelAngle(CanSignal*
        signal, CanSignal* signals, int signalCount, float value, bool* send) {
    CanSignal* steeringAngleSign = lookupSignal("steering_wheel_angle_sign",
            signals, signalCount);

    if(steeringAngleSign == NULL) {
        debug("Unable to find stering wheel angle sign signal");
        *send = false;
    } else {
        if(steeringAngleSign->lastValue == 0) {
            // left turn
            value *= -1;
        }
    }
    return value;
}

float openxc::signals::handlers::handleMultisizeWheelRotationCount(
        CanSignal* signal, CanSignal* signals, int signalCount, float value,
        bool* send, float wheelRadius) {
    if(value < signal->lastValue) {
        rotationsSinceRestart += signal->maxValue - signal->lastValue + value;
    } else {
        rotationsSinceRestart += value - signal->lastValue;
    }
    return firstReceivedOdometerValue(signals, signalCount) + (2 * PI *
            wheelRadius * rotationsSinceRestart);
}

void openxc::signals::handlers::handleButtonEventMessage(int messageId,
        uint64_t data, CanSignal* signals, int signalCount,
        Pipeline* pipeline) {
    CanSignal* buttonTypeSignal = lookupSignal("button_type", signals,
            signalCount);
    CanSignal* buttonStateSignal = lookupSignal("button_state", signals,
            signalCount);

    if(buttonTypeSignal == NULL || buttonStateSignal == NULL) {
        debug("Unable to find button type and state signals");
        return;
    }

    float rawButtonType = can::read::decodeSignal(buttonTypeSignal, data);
    float rawButtonState = can::read::decodeSignal(buttonStateSignal, data);

    bool send = true;
    const char* buttonType = stateHandler(buttonTypeSignal, signals,
            signalCount, rawButtonType, &send);
    if(!send || buttonType == NULL) {
        debug("Unable to find button type corresponding to %f",
                rawButtonType);
        return;
    }

    const char* buttonState = stateHandler(buttonStateSignal, signals,
            signalCount, rawButtonState, &send);
    if(!send || buttonState == NULL) {
        debug("Unable to find button state corresponding to %f",
                rawButtonState);
        return;
    }

    sendEventedStringMessage(BUTTON_EVENT_GENERIC_NAME, buttonType,
            buttonState, pipeline);
}

bool openxc::signals::handlers::handleTurnSignalCommand(const char* name,
        cJSON* value, cJSON* event, CanSignal* signals, int signalCount) {
    const char* direction = value->valuestring;
    CanSignal* signal = NULL;
    if(!strcmp("left", direction)) {
        signal = lookupSignal("turn_signal_left", signals, signalCount);
    } else if(!strcmp("right", direction)) {
        signal = lookupSignal("turn_signal_right", signals, signalCount);
    }

    if(signal != NULL) {
        return can::write::sendSignal(signal, cJSON_CreateBool(true),
                booleanWriter, signals, signalCount, true);
    } else {
        debug("Unable to find signal for %s turn signal", direction);
    }
    return false;
}

void sendOccupancyStatus(const char* seatId, uint64_t data,
        CanSignal* lowerSignal, CanSignal* upperSignal,
        CanSignal* signals, int signalCount, Pipeline* pipeline) {
    if(lowerSignal == NULL || upperSignal == NULL) {
        debug("Upper or lower occupancy signal for seat ID %s is NULL, "
                "vehicle may not support", seatId);
        return;
    }

    float rawLowerStatus = can::read::decodeSignal(lowerSignal, data);
    float rawUpperStatus = can::read::decodeSignal(upperSignal, data);

    bool send = true;
    bool lowerStatus = booleanHandler(NULL, signals, signalCount,
            rawLowerStatus, &send);
    bool upperStatus = booleanHandler(NULL, signals, signalCount,
            rawUpperStatus, &send);
    if(lowerStatus) {
        if(upperStatus) {
            sendEventedStringMessage(OCCUPANCY_STATUS_GENERIC_NAME, seatId,
                    "adult", pipeline);
        } else {
            sendEventedStringMessage(OCCUPANCY_STATUS_GENERIC_NAME, seatId,
                    "child", pipeline);
        }
    } else {
        sendEventedStringMessage(OCCUPANCY_STATUS_GENERIC_NAME, seatId,
                "empty", pipeline);
    }
}

void openxc::signals::handlers::handleOccupancyMessage(int messageId,
        uint64_t data, CanSignal* signals, int signalCount,
        Pipeline* pipeline) {
    sendOccupancyStatus("driver", data,
            lookupSignal("driver_occupancy_lower", signals, signalCount),
            lookupSignal("driver_occupancy_upper", signals, signalCount),
            signals, signalCount, pipeline);
    sendOccupancyStatus("passenger", data,
            lookupSignal("passenger_occupancy_lower", signals, signalCount),
            lookupSignal("passenger_occupancy_upper", signals, signalCount),
            signals, signalCount, pipeline);
}
<|endoftext|>


<commit_before>#ifndef __SNOWMAN_HPP__
#define __SNOWMAN_HPP__

#include <vector>
#include <string>
#include <map>

struct Variable {
    // constructors
    Variable(): undefinedVal(true) { type = UNDEFINED; }
    Variable(bool x): undefinedVal(x) { type = UNDEFINED; }
    Variable(double x): numVal(x) { type = NUM; }
    Variable(std::vector<Variable>* x): arrayVal(x) { type = ARRAY; }
    Variable(std::string* x): blockVal(x) { type = BLOCK; }

    // destructor
    ~Variable() {}

    // operators
    bool operator==(const Variable& v) const {
        if (type != v.type) return false;
        switch (v.type) {
        case UNDEFINED: return true;
        case NUM: return numVal == v.numVal;
        case ARRAY: return arrayVal == v.arrayVal;
        case BLOCK: return blockVal == v.blockVal;
        }
    }
    bool operator<(const Variable& v) const {
        if (type != v.type) return type < v.type;
        switch (v.type) {
        case UNDEFINED: return false;
        case NUM: return numVal < v.numVal;
        case ARRAY: return arrayVal < v.arrayVal;
        case BLOCK: return blockVal < v.blockVal;
        }
    }

    // essentially operator='s, except specialer
    void set(bool x) { mm(); type = UNDEFINED; undefinedVal = x; }
    void set(double x) { mm(); type = NUM; numVal = x; }
    void set(std::vector<Variable>* x) { mm(); type = ARRAY; arrayVal = x; }
    void set(std::string* x) { mm(); type = BLOCK; blockVal = x; }
    void set(Variable& v) {
        mm();
        switch (v.type) {
        case UNDEFINED: set(v.undefinedVal); break;
        case NUM: set(v.numVal); break;
        case ARRAY: set(v.arrayVal); break;
        case BLOCK: set(v.blockVal); break;
        }
    }

    // manage memory (use when modifying value)
    // BE VERY CAREFUL when calling this function
    void mm() {
        switch (type) {
        case ARRAY: delete arrayVal; break;
        case BLOCK: delete blockVal; break;
        }
    }

    enum { UNDEFINED, NUM, ARRAY, BLOCK } type;
    union {
        bool undefinedVal;
        double numVal;
        std::vector<Variable>* arrayVal;
        std::string* blockVal;
    };
};

class Snowman {
    private:
        static std::vector<std::string> tokenize(std::string code);
        void evalToken(std::string token);
        void store(Variable v);
        std::vector<Variable> retrieve(int type, int count = 1, bool consume =
            true, int skip = 0);
        static std::string arrstring(Variable arr);
        static Variable stringarr(std::string str);
        static std::string inspect(Variable str);
        static bool toBool(Variable v);
        Variable vars[8];
        bool activeVars[8];
        std::map<int, Variable> permavars;
        int activePermavar;
    public:
        Snowman();
        ~Snowman();
        void run(std::string code);
        std::string debug();
        bool debugOutput;
        const static int MAJOR_VERSION = 0;
        const static int MINOR_VERSION = 0;
        const static int PATCH_VERSION = 0;
};

#endif
<commit_msg>release 0.1.0<commit_after>#ifndef __SNOWMAN_HPP__
#define __SNOWMAN_HPP__

#include <vector>
#include <string>
#include <map>

struct Variable {
    // constructors
    Variable(): undefinedVal(true) { type = UNDEFINED; }
    Variable(bool x): undefinedVal(x) { type = UNDEFINED; }
    Variable(double x): numVal(x) { type = NUM; }
    Variable(std::vector<Variable>* x): arrayVal(x) { type = ARRAY; }
    Variable(std::string* x): blockVal(x) { type = BLOCK; }

    // destructor
    ~Variable() {}

    // operators
    bool operator==(const Variable& v) const {
        if (type != v.type) return false;
        switch (v.type) {
        case UNDEFINED: return true;
        case NUM: return numVal == v.numVal;
        case ARRAY: return arrayVal == v.arrayVal;
        case BLOCK: return blockVal == v.blockVal;
        }
    }
    bool operator<(const Variable& v) const {
        if (type != v.type) return type < v.type;
        switch (v.type) {
        case UNDEFINED: return false;
        case NUM: return numVal < v.numVal;
        case ARRAY: return arrayVal < v.arrayVal;
        case BLOCK: return blockVal < v.blockVal;
        }
    }

    // essentially operator='s, except specialer
    void set(bool x) { mm(); type = UNDEFINED; undefinedVal = x; }
    void set(double x) { mm(); type = NUM; numVal = x; }
    void set(std::vector<Variable>* x) { mm(); type = ARRAY; arrayVal = x; }
    void set(std::string* x) { mm(); type = BLOCK; blockVal = x; }
    void set(Variable& v) {
        mm();
        switch (v.type) {
        case UNDEFINED: set(v.undefinedVal); break;
        case NUM: set(v.numVal); break;
        case ARRAY: set(v.arrayVal); break;
        case BLOCK: set(v.blockVal); break;
        }
    }

    // manage memory (use when modifying value)
    // BE VERY CAREFUL when calling this function
    void mm() {
        switch (type) {
        case ARRAY: delete arrayVal; break;
        case BLOCK: delete blockVal; break;
        }
    }

    enum { UNDEFINED, NUM, ARRAY, BLOCK } type;
    union {
        bool undefinedVal;
        double numVal;
        std::vector<Variable>* arrayVal;
        std::string* blockVal;
    };
};

class Snowman {
    private:
        static std::vector<std::string> tokenize(std::string code);
        void evalToken(std::string token);
        void store(Variable v);
        std::vector<Variable> retrieve(int type, int count = 1, bool consume =
            true, int skip = 0);
        static std::string arrstring(Variable arr);
        static Variable stringarr(std::string str);
        static std::string inspect(Variable str);
        static bool toBool(Variable v);
        Variable vars[8];
        bool activeVars[8];
        std::map<int, Variable> permavars;
        int activePermavar;
    public:
        Snowman();
        ~Snowman();
        void run(std::string code);
        std::string debug();
        bool debugOutput;
        const static int MAJOR_VERSION = 0;
        const static int MINOR_VERSION = 1;
        const static int PATCH_VERSION = 0;
};

#endif
<|endoftext|>


<commit_before>/*
 * Args - Programs that calculates the number od inputs.
 *
 * Author - Moses Olawoyin <m.bastford@gmail.com>
 *
 * Date - March 20th, 2015.
 *
 */

#include <iostream>

int main (int argc, char* argv[])
{
    std::cout << "The number of the line is: " << argc<< argv[0] << std::endl;

    return 0;
}
<commit_msg> created correct output. closes #65<commit_after>/*
 * Word count - Programs that calculates the number of inputs.
 *
 * Author - Moses Olawoyin <m.bastford@gmail.com>
 *
 * Date - March 20th, 2015.
 *
 */

#include <iostream>

int main (int argc, char* argv[])

{
    int i;
    std::cout << "I got " << argc -1 << " Command-line arguments.They are:"<< std::endl;

    for( int i = 1; i<argc; ++i)
    {
        std::cout << i <<"."<< argv[i]<<std::endl;
    }

    return 0;
}
<|endoftext|>