<commit_before>#include <algorithm>
#include <array>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

template <typename T=unsigned int>
class Memory
{
private:
    std::array<T, 30000> memory_;
    typename decltype(memory_)::iterator ptr_;

public:
    Memory() : memory_(), ptr_(memory_.begin()) {}
    ~Memory() = default;

    inline void inc(T offset)       { *this->ptr_ += offset; }
    inline void dec(T offset)       { *this->ptr_ -= offset; }
    inline void fwd(ssize_t offset) {  this->ptr_ += offset; }
    inline void bwd(ssize_t offset) {  this->ptr_ -= offset; }

    inline T read() {
        return *this->ptr_;
    }
    inline void write(T c) {
        *this->ptr_=c;
    }
};

class Increment;
class Decrement;
class Forward;
class Backward;
class Input;
class Output;
class Loop;

class BaseMatcher
{
public:
    virtual bool match(const Increment&) const {return false;}
    virtual bool match(const Decrement&) const {return false;}
    virtual bool match(const Forward&) const {return false;}
    virtual bool match(const Backward&) const {return false;}
    virtual bool match(const Input&) const {return false;}
    virtual bool match(const Output&) const {return false;}
    virtual bool match(const Loop&) const {return false;}
};

template <typename T>
class ConcreteMatcher : public BaseMatcher
{
    virtual bool match(const T&) const {return true;}
};

using MatcherPtr = std::unique_ptr<BaseMatcher>;

class Runner;
class ExpressionBase
{
public:
    ExpressionBase() {}
    virtual ~ExpressionBase() {}

    virtual void run(Runner& runner) const = 0;
    virtual void extend() = 0;
    virtual bool matches(const ExpressionBase& other) const  = 0;
    virtual MatcherPtr matcher() const = 0;
};

using ExpressionPtr = std::unique_ptr<ExpressionBase>;
using ExpressionVector = std::vector<ExpressionPtr>;

class Runner {
private:
    Memory<> memory_;

public:
    Runner() = default;
    ~Runner() = default;

    inline Memory<>& memory() {return memory_;};

    void run(const ExpressionVector& expressions) {
        for(const auto &expression: expressions) {
            expression->run(*this);
        }
    }
};

class Increment : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Increment(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Increment() = default;
    virtual void run(Runner& runner) const {runner.memory().inc(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Increment>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Decrement : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Decrement(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Decrement() = default;
    virtual void run(Runner& runner) const {runner.memory().dec(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Decrement>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Forward : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Forward(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Forward() = default;
    virtual void run(Runner& runner) const {runner.memory().fwd(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Forward>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Backward : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Backward(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Backward() = default;
    virtual void run(Runner& runner) const {runner.memory().bwd(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Backward>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Input : public ExpressionBase
{
public:
    Input() : ExpressionBase() {}

    virtual ~Input() = default;

    virtual void run(Runner& runner) const {
        runner.memory().write(getchar());
        if (runner.memory().read() == EOF)
            exit(0);
    }

    virtual void extend() {}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new BaseMatcher());
    }
    virtual bool matches(const ExpressionBase& other) const {return false;}
};

class Output : public ExpressionBase
{
public:
    Output() : ExpressionBase() {}

    virtual ~Output() = default;

    virtual void run(Runner& runner) const {
        putchar(runner.memory().read());
        fflush(stdout);
    }

    virtual void extend() {}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new BaseMatcher());
    }
    virtual bool matches(const ExpressionBase& other) const {return false;}
};

class Loop : public ExpressionBase
{
private:
    ExpressionVector children_;

public:
    Loop(ExpressionVector &&children)
     : ExpressionBase(),
       children_(std::move(children)) {}

    Loop(const Loop&) = delete;

    virtual ~Loop() = default;

    virtual void run(Runner& runner) const {
        while(runner.memory().read() > 0) {
            runner.run(children_);
        }
    }

    virtual void extend() {}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new BaseMatcher());
    }
    virtual bool matches(const ExpressionBase& other) const {return false;}
};

using TokenVector = std::vector<char>;

class Parser
{
public:
    Parser() = default;
    ~Parser() = default;

    ExpressionVector parse(TokenVector&);
};

ExpressionVector Parser::parse(TokenVector& tokens) {
    using ExpressionVectorPtr = std::unique_ptr<ExpressionVector>;

    std::vector<ExpressionVectorPtr> stack;
    ExpressionVectorPtr expressions(new ExpressionVector());

    for (auto token: tokens) {
        ExpressionPtr next;

        switch(token) {
            case '+': next = ExpressionPtr(new Increment(1)); break;
            case '-': next = ExpressionPtr(new Decrement(1)); break;
            case '>': next = ExpressionPtr(new Forward(1));   break;
            case '<': next = ExpressionPtr(new Backward(1));  break;
            case ',': next = ExpressionPtr(new Input());      break;
            case '.': next = ExpressionPtr(new Output());     break;
            case '[':
                stack.push_back(std::move(expressions));
                expressions = ExpressionVectorPtr(new ExpressionVector());
                break;
            case ']':
                next = ExpressionPtr(new Loop(std::move(*expressions)));
                expressions = std::move(stack.back());
                stack.pop_back();
                break;
        }

        if (!next) {
            continue;
        } else if (expressions->empty() ||
                  !expressions->back()->matches(*next)) {
            expressions->push_back(std::move(next));
        } else {
            expressions->back()->extend();
        }
    }

    return std::move(*expressions);
}

int main(int argc, char *argv[]) {
    std::ifstream ifs(argv[1]);

    if (!ifs) {
        std::cerr << "Invalid filename!" << std::endl;
        return 1;
    }

    std::vector<char> program;

    std::copy(
        (std::istreambuf_iterator<char>(ifs)),
        (std::istreambuf_iterator<char>()),
        std::back_inserter(program)
    );

    auto expressions = Parser().parse(program);

    Runner().run(expressions);

    return 0;
}
<commit_msg>C++-OOP: Exceptions<commit_after>#include <array>
#include <exception>
#include <fstream>
#include <iostream>
#include <memory>
#include <vector>

template <typename T=unsigned int>
class Memory
{
private:
    std::array<T, 30000> memory_;
    typename decltype(memory_)::iterator ptr_;

public:
    Memory() : memory_(), ptr_(memory_.begin()) {}
    ~Memory() = default;

    inline void inc(T offset)       { *this->ptr_ += offset; }
    inline void dec(T offset)       { *this->ptr_ -= offset; }
    inline void fwd(ssize_t offset) {  this->ptr_ += offset; }
    inline void bwd(ssize_t offset) {  this->ptr_ -= offset; }

    inline T read() const { return *this->ptr_; }
    inline void write(T c) { *this->ptr_=c; }
};

class Increment;
class Decrement;
class Forward;
class Backward;
class Input;
class Output;
class Loop;

class BaseMatcher
{
public:
    virtual bool match(const Increment&) const {return false;}
    virtual bool match(const Decrement&) const {return false;}
    virtual bool match(const Forward&) const {return false;}
    virtual bool match(const Backward&) const {return false;}
    virtual bool match(const Input&) const {return false;}
    virtual bool match(const Output&) const {return false;}
    virtual bool match(const Loop&) const {return false;}
};

template <typename T>
class ConcreteMatcher : public BaseMatcher
{
    virtual bool match(const T&) const {return true;}
};

using MatcherPtr = std::unique_ptr<BaseMatcher>;

class Runner;
class ExpressionBase
{
public:
    ExpressionBase() {}
    virtual ~ExpressionBase() {}

    virtual void run(Runner& runner) const = 0;
    virtual void extend() = 0;
    virtual bool matches(const ExpressionBase& other) const  = 0;
    virtual MatcherPtr matcher() const = 0;
};

using ExpressionPtr = std::unique_ptr<ExpressionBase>;
using ExpressionVector = std::vector<ExpressionPtr>;

class Runner {
private:
    Memory<> memory_;

public:
    Runner() = default;
    ~Runner() = default;

    inline Memory<>& memory() {return memory_;};

    void run(const ExpressionVector& expressions) {
        for(const auto &expression: expressions) {
            expression->run(*this);
        }
    }
};

class Increment : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Increment(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Increment() = default;
    virtual void run(Runner& runner) const {runner.memory().inc(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Increment>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Decrement : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Decrement(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Decrement() = default;
    virtual void run(Runner& runner) const {runner.memory().dec(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Decrement>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Forward : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Forward(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Forward() = default;
    virtual void run(Runner& runner) const {runner.memory().fwd(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Forward>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Backward : public ExpressionBase
{
private:
    ssize_t offset_;
public:
    Backward(ssize_t offset) : ExpressionBase(), offset_(offset) {}
    virtual ~Backward() = default;
    virtual void run(Runner& runner) const {runner.memory().bwd(offset_);}
    virtual void extend() {++offset_;}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new ConcreteMatcher<Backward>());
    }
    virtual bool matches(const ExpressionBase& other) const {
        return other.matcher()->match(*this);
    }
};

class Input : public ExpressionBase
{
public:
    Input() : ExpressionBase() {}

    virtual ~Input() = default;

    virtual void run(Runner& runner) const {
        runner.memory().write(getchar());
        if (runner.memory().read() == EOF)
            exit(0);
    }

    virtual void extend() {}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new BaseMatcher());
    }
    virtual bool matches(const ExpressionBase& other) const {return false;}
};

class Output : public ExpressionBase
{
public:
    Output() : ExpressionBase() {}

    virtual ~Output() = default;

    virtual void run(Runner& runner) const {
        putchar(runner.memory().read());
        fflush(stdout);
    }

    virtual void extend() {}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new BaseMatcher());
    }
    virtual bool matches(const ExpressionBase& other) const {return false;}
};

class Loop : public ExpressionBase
{
private:
    ExpressionVector children_;

public:
    Loop(ExpressionVector &&children)
     : ExpressionBase(),
       children_(std::move(children)) {}

    Loop(const Loop&) = delete;

    virtual ~Loop() = default;

    virtual void run(Runner& runner) const {
        while(runner.memory().read() > 0) {
            runner.run(children_);
        }
    }

    virtual void extend() {}
    virtual MatcherPtr matcher() const {
        return MatcherPtr(new BaseMatcher());
    }
    virtual bool matches(const ExpressionBase& other) const {return false;}
};

using TokenVector = std::vector<char>;

class ExcessiveOpeningBrackets: public std::exception {
    virtual const char* what() const throw() {
        return "Too many opening brackets";
    }
};

class UnexpectedClosingBracket: public std::exception {
    virtual const char* what() const throw() {
        return "Too many closing brackets";
    }
};

class Parser
{
public:
    Parser() = default;
    ~Parser() = default;

    ExpressionVector parse(TokenVector&);
};

ExpressionVector Parser::parse(TokenVector& tokens) {
    using ExpressionVectorPtr = std::unique_ptr<ExpressionVector>;

    std::vector<ExpressionVectorPtr> stack;
    ExpressionVectorPtr expressions(new ExpressionVector());

    for (auto token: tokens) {
        ExpressionPtr next;

        switch(token) {
            case '+': next = ExpressionPtr(new Increment(1)); break;
            case '-': next = ExpressionPtr(new Decrement(1)); break;
            case '>': next = ExpressionPtr(new Forward(1));   break;
            case '<': next = ExpressionPtr(new Backward(1));  break;
            case ',': next = ExpressionPtr(new Input());      break;
            case '.': next = ExpressionPtr(new Output());     break;
            case '[':
                stack.push_back(std::move(expressions));
                expressions = ExpressionVectorPtr(new ExpressionVector());
                break;
            case ']':
                if (stack.empty()) throw UnexpectedClosingBracket();
                next = ExpressionPtr(new Loop(std::move(*expressions)));
                expressions = std::move(stack.back());
                stack.pop_back();
                break;
        }

        if (!next) {
            continue;
        } else if (expressions->empty() ||
                  !expressions->back()->matches(*next)) {
            expressions->push_back(std::move(next));
        } else {
            expressions->back()->extend();
        }
    }

    if (!stack.empty()) throw ExcessiveOpeningBrackets();

    return std::move(*expressions);
}

int main(int argc, char *argv[]) {
    std::ifstream ifs(argv[1]);

    if (!ifs) {
        std::cerr << "Invalid filename!" << std::endl;
        return 1;
    }

    std::vector<char> program;

    std::copy(
        (std::istreambuf_iterator<char>(ifs)),
        (std::istreambuf_iterator<char>()),
        std::back_inserter(program)
    );

    try {
        auto expressions = Parser().parse(program);
        Runner().run(expressions);
    } catch (std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2014 Tavendo GmbH
//
//  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.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef AUTOBAHN_HPP
#define AUTOBAHN_HPP

#include <cstdint>
#include <stdexcept>
#include <istream>
#include <ostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include <functional>

#if defined(_WIN32) || defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#endif

#define MSGPACK_USE_LEGACY_NAME_AS_FLOAT

#include <msgpack.hpp>

#ifdef ERROR
#undef ERROR
#endif

// http://stackoverflow.com/questions/22597948/using-boostfuture-with-then-continuations/
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#include <boost/thread/future.hpp>
//#include <future>

#include <boost/any.hpp>
#include <boost/asio.hpp>

/*! \mainpage Reference Documentation
 *
 * Welcome to the reference documentation of Autobahn|Cpp.

 *
 * For a more gentle introduction, please visit http://autobahn.ws/cpp/.
 */

/*!
 * Autobahn namespace.
 */
namespace autobahn {

   /// A map holding any values and string keys.
   typedef std::map<std::string, boost::any> anymap;

   /// A vector holding any values.
   typedef std::vector<boost::any> anyvec;

   /// A pair of ::anyvec and ::anymap.
   typedef std::pair<anyvec, anymap> anyvecmap;

   /// Handler type for use with session::subscribe(const std::string&, handler_t)
   typedef std::function<void(const anyvec&, const anymap&)> handler_t;

   /// Endpoint type for use with session::provide(const std::string&, endpoint_t)
   typedef std::function<boost::any(const anyvec&, const anymap&)> endpoint_t;

   /// Endpoint type for use with session::provide_v(const std::string&, endpoint_v_t)
   typedef std::function<anyvec(const anyvec&, const anymap&)> endpoint_v_t;

   /// Endpoint type for use with session::provide_m(const std::string&, endpoint_m_t)
   typedef std::function<anymap(const anyvec&, const anymap&)> endpoint_m_t;

   /// Endpoint type for use with session::provide_vm(const std::string&, endpoint_vm_t)
   typedef std::function<anyvecmap(const anyvec&, const anymap&)> endpoint_vm_t;

   /// Endpoint type for use with session::provide(const std::string&, endpoint_ft)
   typedef std::function<boost::future<boost::any>(const anyvec&, const anymap&)> endpoint_f_t;

   /// Endpoint type for use with session::provide_fv(const std::string&, endpoint_fv_t)
   typedef std::function<boost::future<anyvec>(const anyvec&, const anymap&)> endpoint_fv_t;

   /// Endpoint type for use with session::provide_fm(const std::string&, endpoint_fm_t)
   typedef std::function<boost::future<anymap>(const anyvec&, const anymap&)> endpoint_fm_t;

   /// Endpoint type for use with session::provide_fvm(const std::string&, endpoint_fvm_t)
   typedef std::function<boost::future<anyvecmap>(const anyvec&, const anymap&)> endpoint_fvm_t;

   /// Represents a procedure registration.
   struct registration {
      registration() : id(0) {};
      registration(uint64_t id) : id(id) {};
      uint64_t id;
   };

   /// Represents a topic subscription.
   struct subscription {
      subscription() : id(0) {};
      subscription(uint64_t id) : id(id) {};
      uint64_t id;
   };

   /// Represents an event publication (for acknowledged publications).
   struct publication {
      publication() : id(0) {};
      publication(uint64_t id) : id(id) {};
      uint64_t id;
   };

   /*!
    * A WAMP session.
    */
   template<typename IStream, typename OStream>
   class session {

      public:

         /*!
          * Create a new WAMP session.
          *
          * \param in The input stream to run this session on.
          * \param out THe output stream to run this session on.
          */
         session(boost::asio::io_service& io, IStream& in, OStream& out, bool debug = false);

         /*!
          * Start listening on the IStream provided to the constructor
          * of this session.
          */
         inline
         void start();

         /*!
          * Closes the IStream and the OStream provided to the constructor
          * of this session.
          */
         inline
         void stop();

         /*!
          * Join a realm with this session.
          *
          * \param realm The realm to join on the WAMP router connected to.
          * \return A future that resolves with the session ID when the realm was joined.
          */
         inline
         boost::future<uint64_t> join(const std::string& realm);

         /*!
          * Leave the realm.
          *
          * \param reason An optional WAMP URI providing a reason for leaving.
          * \return A future that resolves with the reason sent by the peer.
          */
         inline
         boost::future<std::string> leave(const std::string& reason = std::string("wamp.error.close_realm"));

         /*!
          * Publish an event with empty payload to a topic.
          *
          * \param topic The URI of the topic to publish to.
          */
         inline
         void publish(const std::string& topic);

         /*!
          * Publish an event with positional payload to a topic.
          *
          * \param topic The URI of the topic to publish to.
          * \param args The positional payload for the event.
          */
         inline
         void publish(const std::string& topic, const anyvec& args);

         /*!
          * Publish an event with both positional and keyword payload to a topic.
          *
          * \param topic The URI of the topic to publish to.
          * \param args The positional payload for the event.
          * \param kwargs The keyword payload for the event.
          */
         inline
         void publish(const std::string& topic, const anyvec& args, const anymap& kwargs);

         /*!
          * Subscribe a handler to a topic to receive events.
          *
          * \param topic The URI of the topic to subscribe to.
          * \param handler The handler that will receive events under the subscription.
          * \return A future that resolves to a autobahn::subscription
          */
         inline
         boost::future<subscription> subscribe(const std::string& topic, handler_t handler);

         /*!
          * Calls a remote procedure with no arguments.
          *
          * \param procedure The URI of the remote procedure to call.
          * \return A future that resolves to the result of the remote procedure call.
          */
         inline
         boost::future<boost::any> call(const std::string& procedure);

         /*!
          * Calls a remote procedure with positional arguments.
          *
          * \param procedure The URI of the remote procedure to call.
          * \param args The positional arguments for the call.
          * \return A future that resolves to the result of the remote procedure call.
          */
         inline
         boost::future<boost::any> call(const std::string& procedure, const anyvec& args);

         /*!
          * Calls a remote procedure with positional and keyword arguments.
          *
          * \param procedure The URI of the remote procedure to call.
          * \param args The positional arguments for the call.
          * \param kwargs The keyword arguments for the call.
          * \return A future that resolves to the result of the remote procedure call.
          */
         inline
         boost::future<boost::any> call(const std::string& procedure, const anyvec& args, const anymap& kwargs);

         /*!
          * Register an endpoint as a procedure that can be called remotely.
          *
          * \param procedure The URI under which the procedure is to be exposed.
          * \param endpoint The endpoint to be exposed as a remotely callable procedure.
          * \return A future that resolves to a autobahn::registration
          */
         inline boost::future<registration> provide(const std::string& procedure, endpoint_t endpoint);

         inline boost::future<registration> provide_v(const std::string& procedure, endpoint_v_t endpoint);

         inline boost::future<registration> provide_m(const std::string& procedure, endpoint_m_t endpoint);

         inline boost::future<registration> provide_vm(const std::string& procedure, endpoint_vm_t endpoint);

         inline boost::future<registration> provide_f(const std::string& procedure, endpoint_f_t endpoint);

         inline boost::future<registration> provide_fv(const std::string& procedure, endpoint_fv_t endpoint);

         inline boost::future<registration> provide_fm(const std::string& procedure, endpoint_fm_t endpoint);

         inline boost::future<registration> provide_fvm(const std::string& procedure, endpoint_fvm_t endpoint);

      private:

         template<typename E>
         inline boost::future<registration> _provide(const std::string& procedure, E endpoint);

         //////////////////////////////////////////////////////////////////////////////////////
         /// Caller

         /// An outstanding WAMP call.
         struct call_t {
            boost::promise<boost::any> m_res;
         };

         /// Map of outstanding WAMP calls (request ID -> call).
         typedef std::map<uint64_t, call_t> calls_t;

         /// Map of WAMP call ID -> call
         calls_t m_calls;

         //////////////////////////////////////////////////////////////////////////////////////
         /// Subscriber

         /// An outstanding WAMP subscribe request.
         struct subscribe_request_t {
            subscribe_request_t() {};
            subscribe_request_t(handler_t handler) : m_handler(handler) {};
            handler_t m_handler;
            boost::promise<subscription> m_res;
         };

         /// Map of outstanding WAMP subscribe requests (request ID -> subscribe request).
         typedef std::map<uint64_t, subscribe_request_t> subscribe_requests_t;

         /// Map of WAMP subscribe request ID -> subscribe request
         subscribe_requests_t m_subscribe_requests;

         /// Map of subscribed handlers (subscription ID -> handler)
         typedef std::multimap<uint64_t, handler_t> handlers_t;

         /// Map of WAMP subscription ID -> handler
         handlers_t m_handlers;

         //////////////////////////////////////////////////////////////////////////////////////
         /// Callee

         /// An outstanding WAMP register request.
         struct register_request_t {
            register_request_t() {};
            register_request_t(boost::any endpoint) : m_endpoint(endpoint) {};
			register_request_t(register_request_t &&other)
				: m_endpoint(std::move(other.m_endpoint))
				, m_res(std::move(other.m_res))
			{}
            boost::any m_endpoint;
            boost::promise<registration> m_res;
         };

         /// Map of outstanding WAMP register requests (request ID -> register request).
         typedef std::map<uint64_t, register_request_t> register_requests_t;

         /// Map of WAMP register request ID -> register request
         register_requests_t m_register_requests;

         /// Map of registered endpoints (registration ID -> endpoint)
         typedef std::map<uint64_t, boost::any> endpoints_t;

         /// Map of WAMP registration ID -> endpoint
         endpoints_t m_endpoints;

         /// An unserialized, raw WAMP message.
         typedef std::vector<msgpack::object> wamp_msg_t;

         /// Process a WAMP ERROR message.
         inline void process_error(const wamp_msg_t& msg);

         /// Process a WAMP HELLO message.
         inline void process_welcome(const wamp_msg_t& msg);

         /// Process a WAMP RESULT message.
         inline void process_call_result(const wamp_msg_t& msg);

         /// Process a WAMP SUBSCRIBED message.
         inline void process_subscribed(const wamp_msg_t& msg);

         /// Process a WAMP EVENT message.
         inline void process_event(const wamp_msg_t& msg);

         /// Process a WAMP REGISTERED message.
         inline void process_registered(const wamp_msg_t& msg);

         /// Process a WAMP INVOCATION message.
         inline void process_invocation(const wamp_msg_t& msg);

         /// Process a WAMP GOODBYE message.
         inline void process_goodbye(const wamp_msg_t& msg);

         /// Unpacks any MsgPack object into boost::any value.
         inline boost::any unpack_any(msgpack::object& obj);

         /// Unpacks MsgPack array into anyvec.
         inline void unpack_anyvec(std::vector<msgpack::object>& raw_args, anyvec& args);

         /// Unpacks MsgPack map into anymap.
         inline void unpack_anymap(std::map<std::string, msgpack::object>& raw_kwargs, anymap& kwargs);

         /// Pack any value into serializion buffer.
         inline void pack_any(const boost::any& value);

         /// Send out message serialized in serialization buffer to ostream.
         inline void send();

         /// Receive one message from istream in m_unpacker.
         inline void receive_msg();

         void got_handshake_reply(const boost::system::error_code& error);

         void got_msg_header(const boost::system::error_code& error);

         void got_msg_body(const boost::system::error_code& error);

         void got_msg(const msgpack::object& obj);

         bool m_debug;

         bool m_stopped;

         boost::asio::io_service& m_io;

         /// Input stream this session runs on.
         IStream& m_in;

         /// Output stream this session runs on.
         OStream& m_out;

         char m_buffer_msg_len[4];
         uint32_t m_msg_len;

         boost::promise<boost::any> m_test_promise;

         /// MsgPack serialization buffer.
         msgpack::sbuffer m_buffer;

         /// MsgPacker serialization packer.
         msgpack::packer<msgpack::sbuffer> m_packer;

         /// MsgPack unserialization unpacker.
         msgpack::unpacker m_unpacker;

         /// WAMP session ID (if the session is joined to a realm).
         uint64_t m_session_id;

         /// Future to be fired when session was joined.
         boost::promise<uint64_t> m_session_join;

         /// Last request ID of outgoing WAMP requests.
         uint64_t m_request_id;

         bool m_goodbye_sent;

         boost::promise<std::string> m_session_leave;

         /// WAMP message type codes.
         enum class msg_code : int {
            HELLO = 1,
            WELCOME = 2,
            ABORT = 3,
            CHALLENGE = 4,
            AUTHENTICATE = 5,
            GOODBYE = 6,
            HEARTBEAT = 7,
            ERROR = 8,
            PUBLISH = 16,
            PUBLISHED = 17,
            SUBSCRIBE = 32,
            SUBSCRIBED = 33,
            UNSUBSCRIBE = 34,
            UNSUBSCRIBED = 35,
            EVENT = 36,
            CALL = 48,
            CANCEL = 49,
            RESULT = 50,
            REGISTER = 64,
            REGISTERED = 65,
            UNREGISTER = 66,
            UNREGISTERED = 67,
            INVOCATION = 68,
            INTERRUPT = 69,
            YIELD = 70
         };
   };

   class protocol_error : public std::runtime_error {
      public:
         protocol_error(const std::string& msg) : std::runtime_error(msg) {};
   };

   class no_session_error : public std::runtime_error {
      public:
         no_session_error() : std::runtime_error("session not joined") {};
   };

}

#include "autobahn_impl.hpp"

#endif // AUTOBAHN_HPP
<commit_msg>comment out legacy switch now that we merged PR 33<commit_after>///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2014 Tavendo GmbH
//
//  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.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef AUTOBAHN_HPP
#define AUTOBAHN_HPP

#include <cstdint>
#include <stdexcept>
#include <istream>
#include <ostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include <functional>

#if defined(_WIN32) || defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#endif

// We don't need the following anymore, since
// https://github.com/tavendo/AutobahnCpp/pull/33 was merged
//#define MSGPACK_USE_LEGACY_NAME_AS_FLOAT

#include <msgpack.hpp>

#ifdef ERROR
#undef ERROR
#endif

// http://stackoverflow.com/questions/22597948/using-boostfuture-with-then-continuations/
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#include <boost/thread/future.hpp>
//#include <future>

#include <boost/any.hpp>
#include <boost/asio.hpp>

/*! \mainpage Reference Documentation
 *
 * Welcome to the reference documentation of Autobahn|Cpp.

 *
 * For a more gentle introduction, please visit http://autobahn.ws/cpp/.
 */

/*!
 * Autobahn namespace.
 */
namespace autobahn {

   /// A map holding any values and string keys.
   typedef std::map<std::string, boost::any> anymap;

   /// A vector holding any values.
   typedef std::vector<boost::any> anyvec;

   /// A pair of ::anyvec and ::anymap.
   typedef std::pair<anyvec, anymap> anyvecmap;

   /// Handler type for use with session::subscribe(const std::string&, handler_t)
   typedef std::function<void(const anyvec&, const anymap&)> handler_t;

   /// Endpoint type for use with session::provide(const std::string&, endpoint_t)
   typedef std::function<boost::any(const anyvec&, const anymap&)> endpoint_t;

   /// Endpoint type for use with session::provide_v(const std::string&, endpoint_v_t)
   typedef std::function<anyvec(const anyvec&, const anymap&)> endpoint_v_t;

   /// Endpoint type for use with session::provide_m(const std::string&, endpoint_m_t)
   typedef std::function<anymap(const anyvec&, const anymap&)> endpoint_m_t;

   /// Endpoint type for use with session::provide_vm(const std::string&, endpoint_vm_t)
   typedef std::function<anyvecmap(const anyvec&, const anymap&)> endpoint_vm_t;

   /// Endpoint type for use with session::provide(const std::string&, endpoint_ft)
   typedef std::function<boost::future<boost::any>(const anyvec&, const anymap&)> endpoint_f_t;

   /// Endpoint type for use with session::provide_fv(const std::string&, endpoint_fv_t)
   typedef std::function<boost::future<anyvec>(const anyvec&, const anymap&)> endpoint_fv_t;

   /// Endpoint type for use with session::provide_fm(const std::string&, endpoint_fm_t)
   typedef std::function<boost::future<anymap>(const anyvec&, const anymap&)> endpoint_fm_t;

   /// Endpoint type for use with session::provide_fvm(const std::string&, endpoint_fvm_t)
   typedef std::function<boost::future<anyvecmap>(const anyvec&, const anymap&)> endpoint_fvm_t;

   /// Represents a procedure registration.
   struct registration {
      registration() : id(0) {};
      registration(uint64_t id) : id(id) {};
      uint64_t id;
   };

   /// Represents a topic subscription.
   struct subscription {
      subscription() : id(0) {};
      subscription(uint64_t id) : id(id) {};
      uint64_t id;
   };

   /// Represents an event publication (for acknowledged publications).
   struct publication {
      publication() : id(0) {};
      publication(uint64_t id) : id(id) {};
      uint64_t id;
   };

   /*!
    * A WAMP session.
    */
   template<typename IStream, typename OStream>
   class session {

      public:

         /*!
          * Create a new WAMP session.
          *
          * \param in The input stream to run this session on.
          * \param out THe output stream to run this session on.
          */
         session(boost::asio::io_service& io, IStream& in, OStream& out, bool debug = false);

         /*!
          * Start listening on the IStream provided to the constructor
          * of this session.
          */
         inline
         void start();

         /*!
          * Closes the IStream and the OStream provided to the constructor
          * of this session.
          */
         inline
         void stop();

         /*!
          * Join a realm with this session.
          *
          * \param realm The realm to join on the WAMP router connected to.
          * \return A future that resolves with the session ID when the realm was joined.
          */
         inline
         boost::future<uint64_t> join(const std::string& realm);

         /*!
          * Leave the realm.
          *
          * \param reason An optional WAMP URI providing a reason for leaving.
          * \return A future that resolves with the reason sent by the peer.
          */
         inline
         boost::future<std::string> leave(const std::string& reason = std::string("wamp.error.close_realm"));

         /*!
          * Publish an event with empty payload to a topic.
          *
          * \param topic The URI of the topic to publish to.
          */
         inline
         void publish(const std::string& topic);

         /*!
          * Publish an event with positional payload to a topic.
          *
          * \param topic The URI of the topic to publish to.
          * \param args The positional payload for the event.
          */
         inline
         void publish(const std::string& topic, const anyvec& args);

         /*!
          * Publish an event with both positional and keyword payload to a topic.
          *
          * \param topic The URI of the topic to publish to.
          * \param args The positional payload for the event.
          * \param kwargs The keyword payload for the event.
          */
         inline
         void publish(const std::string& topic, const anyvec& args, const anymap& kwargs);

         /*!
          * Subscribe a handler to a topic to receive events.
          *
          * \param topic The URI of the topic to subscribe to.
          * \param handler The handler that will receive events under the subscription.
          * \return A future that resolves to a autobahn::subscription
          */
         inline
         boost::future<subscription> subscribe(const std::string& topic, handler_t handler);

         /*!
          * Calls a remote procedure with no arguments.
          *
          * \param procedure The URI of the remote procedure to call.
          * \return A future that resolves to the result of the remote procedure call.
          */
         inline
         boost::future<boost::any> call(const std::string& procedure);

         /*!
          * Calls a remote procedure with positional arguments.
          *
          * \param procedure The URI of the remote procedure to call.
          * \param args The positional arguments for the call.
          * \return A future that resolves to the result of the remote procedure call.
          */
         inline
         boost::future<boost::any> call(const std::string& procedure, const anyvec& args);

         /*!
          * Calls a remote procedure with positional and keyword arguments.
          *
          * \param procedure The URI of the remote procedure to call.
          * \param args The positional arguments for the call.
          * \param kwargs The keyword arguments for the call.
          * \return A future that resolves to the result of the remote procedure call.
          */
         inline
         boost::future<boost::any> call(const std::string& procedure, const anyvec& args, const anymap& kwargs);

         /*!
          * Register an endpoint as a procedure that can be called remotely.
          *
          * \param procedure The URI under which the procedure is to be exposed.
          * \param endpoint The endpoint to be exposed as a remotely callable procedure.
          * \return A future that resolves to a autobahn::registration
          */
         inline boost::future<registration> provide(const std::string& procedure, endpoint_t endpoint);

         inline boost::future<registration> provide_v(const std::string& procedure, endpoint_v_t endpoint);

         inline boost::future<registration> provide_m(const std::string& procedure, endpoint_m_t endpoint);

         inline boost::future<registration> provide_vm(const std::string& procedure, endpoint_vm_t endpoint);

         inline boost::future<registration> provide_f(const std::string& procedure, endpoint_f_t endpoint);

         inline boost::future<registration> provide_fv(const std::string& procedure, endpoint_fv_t endpoint);

         inline boost::future<registration> provide_fm(const std::string& procedure, endpoint_fm_t endpoint);

         inline boost::future<registration> provide_fvm(const std::string& procedure, endpoint_fvm_t endpoint);

      private:

         template<typename E>
         inline boost::future<registration> _provide(const std::string& procedure, E endpoint);

         //////////////////////////////////////////////////////////////////////////////////////
         /// Caller

         /// An outstanding WAMP call.
         struct call_t {
            boost::promise<boost::any> m_res;
         };

         /// Map of outstanding WAMP calls (request ID -> call).
         typedef std::map<uint64_t, call_t> calls_t;

         /// Map of WAMP call ID -> call
         calls_t m_calls;

         //////////////////////////////////////////////////////////////////////////////////////
         /// Subscriber

         /// An outstanding WAMP subscribe request.
         struct subscribe_request_t {
            subscribe_request_t() {};
            subscribe_request_t(handler_t handler) : m_handler(handler) {};
            handler_t m_handler;
            boost::promise<subscription> m_res;
         };

         /// Map of outstanding WAMP subscribe requests (request ID -> subscribe request).
         typedef std::map<uint64_t, subscribe_request_t> subscribe_requests_t;

         /// Map of WAMP subscribe request ID -> subscribe request
         subscribe_requests_t m_subscribe_requests;

         /// Map of subscribed handlers (subscription ID -> handler)
         typedef std::multimap<uint64_t, handler_t> handlers_t;

         /// Map of WAMP subscription ID -> handler
         handlers_t m_handlers;

         //////////////////////////////////////////////////////////////////////////////////////
         /// Callee

         /// An outstanding WAMP register request.
         struct register_request_t {
            register_request_t() {};
            register_request_t(boost::any endpoint) : m_endpoint(endpoint) {};
			register_request_t(register_request_t &&other)
				: m_endpoint(std::move(other.m_endpoint))
				, m_res(std::move(other.m_res))
			{}
            boost::any m_endpoint;
            boost::promise<registration> m_res;
         };

         /// Map of outstanding WAMP register requests (request ID -> register request).
         typedef std::map<uint64_t, register_request_t> register_requests_t;

         /// Map of WAMP register request ID -> register request
         register_requests_t m_register_requests;

         /// Map of registered endpoints (registration ID -> endpoint)
         typedef std::map<uint64_t, boost::any> endpoints_t;

         /// Map of WAMP registration ID -> endpoint
         endpoints_t m_endpoints;

         /// An unserialized, raw WAMP message.
         typedef std::vector<msgpack::object> wamp_msg_t;

         /// Process a WAMP ERROR message.
         inline void process_error(const wamp_msg_t& msg);

         /// Process a WAMP HELLO message.
         inline void process_welcome(const wamp_msg_t& msg);

         /// Process a WAMP RESULT message.
         inline void process_call_result(const wamp_msg_t& msg);

         /// Process a WAMP SUBSCRIBED message.
         inline void process_subscribed(const wamp_msg_t& msg);

         /// Process a WAMP EVENT message.
         inline void process_event(const wamp_msg_t& msg);

         /// Process a WAMP REGISTERED message.
         inline void process_registered(const wamp_msg_t& msg);

         /// Process a WAMP INVOCATION message.
         inline void process_invocation(const wamp_msg_t& msg);

         /// Process a WAMP GOODBYE message.
         inline void process_goodbye(const wamp_msg_t& msg);

         /// Unpacks any MsgPack object into boost::any value.
         inline boost::any unpack_any(msgpack::object& obj);

         /// Unpacks MsgPack array into anyvec.
         inline void unpack_anyvec(std::vector<msgpack::object>& raw_args, anyvec& args);

         /// Unpacks MsgPack map into anymap.
         inline void unpack_anymap(std::map<std::string, msgpack::object>& raw_kwargs, anymap& kwargs);

         /// Pack any value into serializion buffer.
         inline void pack_any(const boost::any& value);

         /// Send out message serialized in serialization buffer to ostream.
         inline void send();

         /// Receive one message from istream in m_unpacker.
         inline void receive_msg();

         void got_handshake_reply(const boost::system::error_code& error);

         void got_msg_header(const boost::system::error_code& error);

         void got_msg_body(const boost::system::error_code& error);

         void got_msg(const msgpack::object& obj);

         bool m_debug;

         bool m_stopped;

         boost::asio::io_service& m_io;

         /// Input stream this session runs on.
         IStream& m_in;

         /// Output stream this session runs on.
         OStream& m_out;

         char m_buffer_msg_len[4];
         uint32_t m_msg_len;

         boost::promise<boost::any> m_test_promise;

         /// MsgPack serialization buffer.
         msgpack::sbuffer m_buffer;

         /// MsgPacker serialization packer.
         msgpack::packer<msgpack::sbuffer> m_packer;

         /// MsgPack unserialization unpacker.
         msgpack::unpacker m_unpacker;

         /// WAMP session ID (if the session is joined to a realm).
         uint64_t m_session_id;

         /// Future to be fired when session was joined.
         boost::promise<uint64_t> m_session_join;

         /// Last request ID of outgoing WAMP requests.
         uint64_t m_request_id;

         bool m_goodbye_sent;

         boost::promise<std::string> m_session_leave;

         /// WAMP message type codes.
         enum class msg_code : int {
            HELLO = 1,
            WELCOME = 2,
            ABORT = 3,
            CHALLENGE = 4,
            AUTHENTICATE = 5,
            GOODBYE = 6,
            HEARTBEAT = 7,
            ERROR = 8,
            PUBLISH = 16,
            PUBLISHED = 17,
            SUBSCRIBE = 32,
            SUBSCRIBED = 33,
            UNSUBSCRIBE = 34,
            UNSUBSCRIBED = 35,
            EVENT = 36,
            CALL = 48,
            CANCEL = 49,
            RESULT = 50,
            REGISTER = 64,
            REGISTERED = 65,
            UNREGISTER = 66,
            UNREGISTERED = 67,
            INVOCATION = 68,
            INTERRUPT = 69,
            YIELD = 70
         };
   };

   class protocol_error : public std::runtime_error {
      public:
         protocol_error(const std::string& msg) : std::runtime_error(msg) {};
   };

   class no_session_error : public std::runtime_error {
      public:
         no_session_error() : std::runtime_error("session not joined") {};
   };

}

#include "autobahn_impl.hpp"

#endif // AUTOBAHN_HPP
<|endoftext|>


<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
*/

#include "vw_builder.h"
#include "parser.h"
// #include "primitives.h"

namespace VW
{
    VowpalWabbitExampleBuilder::VowpalWabbitExampleBuilder(VowpalWabbit^ vw) :
        m_vw(vw), m_example(nullptr)
    {
        if (vw == nullptr)
            throw gcnew ArgumentNullException("vw");

        m_example = vw->GetOrCreateNativeExample();
    }

    VowpalWabbitExampleBuilder::~VowpalWabbitExampleBuilder()
    {
        this->!VowpalWabbitExampleBuilder();
    }

    VowpalWabbitExampleBuilder::!VowpalWabbitExampleBuilder()
    {
        if (m_example != nullptr)
        {
            // in case CreateExample is not getting called
            delete m_example;

            m_example = nullptr;
        }
    }

    VowpalWabbitExample^ VowpalWabbitExampleBuilder::CreateExample()
    {
        if (m_example == nullptr)
            return nullptr;

        try
        {
            // finalize example
            VW::parse_atomic_example(*m_vw->m_vw, m_example->m_example, false);
            VW::setup_example(*m_vw->m_vw, m_example->m_example);
        }
        CATCHRETHROW

        // hand memory management off to VowpalWabbitExample
        auto ret = m_example;
        m_example = nullptr;

        return ret;
    }

    void VowpalWabbitExampleBuilder::ParseLabel(String^ value)
    {
        if (value == nullptr)
            return;

        auto bytes = System::Text::Encoding::UTF8->GetBytes(value);
        auto valueHandle = GCHandle::Alloc(bytes, GCHandleType::Pinned);

        try
        {
            VW::parse_example_label(*m_vw->m_vw, *m_example->m_example, reinterpret_cast<char*>(valueHandle.AddrOfPinnedObject().ToPointer()));
        }
        CATCHRETHROW
        finally
        { valueHandle.Free();
        }
    }

    VowpalWabbitNamespaceBuilder^ VowpalWabbitExampleBuilder::AddNamespace(Char featureGroup)
    {
        return AddNamespace((Byte)featureGroup);
    }

    VowpalWabbitNamespaceBuilder^ VowpalWabbitExampleBuilder::AddNamespace(Byte featureGroup)
    {
        uint32_t index = featureGroup;
        example* ex = m_example->m_example;

        return gcnew VowpalWabbitNamespaceBuilder(ex->feature_space + index, featureGroup, m_example->m_example);
    }

    VowpalWabbitNamespaceBuilder::VowpalWabbitNamespaceBuilder(features* features,
        unsigned char index, example* example)
        : m_features(features), m_index(index), m_example(example)
    {
    }

    VowpalWabbitNamespaceBuilder::~VowpalWabbitNamespaceBuilder()
    {
        this->!VowpalWabbitNamespaceBuilder();
    }

    VowpalWabbitNamespaceBuilder::!VowpalWabbitNamespaceBuilder()
    {
        if (m_features->size() > 0)
        {
            unsigned char temp = m_index;
            m_example->indices.push_back(temp);
        }
    }

    void VowpalWabbitNamespaceBuilder::AddFeaturesUnchecked(uint64_t weight_index_base, float* begin, float* end)
    {
        for (; begin != end; begin++)
        {
            float x = *begin;
            if (x != 0)
            {
                m_features->values.push_back_unchecked(x);
                m_features->indicies.push_back_unchecked(weight_index_base);
            }
            weight_index_base++;
        }

    }

    void VowpalWabbitNamespaceBuilder::AddFeature(uint64_t weight_index, float x)
    {
        // filter out 0-values
        if (x == 0)
            return;

        m_features->values.push_back(x);
        m_features->indicies.push_back(weight_index);
    }

    void VowpalWabbitNamespaceBuilder::PreAllocate(int size)
    {
        m_features->values.resize(m_features->values.end - m_features->values.begin + size);
        m_features->indicies.resize(m_features->indicies.end - m_features->indicies.begin + size);
    }
}
<commit_msg>fixed tests<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
*/

#include "vw_builder.h"
#include "parser.h"
// #include "primitives.h"

namespace VW
{
    VowpalWabbitExampleBuilder::VowpalWabbitExampleBuilder(VowpalWabbit^ vw) :
        m_vw(vw), m_example(nullptr)
    {
        if (vw == nullptr)
            throw gcnew ArgumentNullException("vw");

        m_example = vw->GetOrCreateNativeExample();
    }

    VowpalWabbitExampleBuilder::~VowpalWabbitExampleBuilder()
    {
        this->!VowpalWabbitExampleBuilder();
    }

    VowpalWabbitExampleBuilder::!VowpalWabbitExampleBuilder()
    {
        if (m_example != nullptr)
        {
            // in case CreateExample is not getting called
            delete m_example;

            m_example = nullptr;
        }
    }

    VowpalWabbitExample^ VowpalWabbitExampleBuilder::CreateExample()
    {
        if (m_example == nullptr)
            return nullptr;

        try
        {
            // finalize example
            VW::parse_atomic_example(*m_vw->m_vw, m_example->m_example, false);
            VW::setup_example(*m_vw->m_vw, m_example->m_example);
        }
        CATCHRETHROW

        // hand memory management off to VowpalWabbitExample
        auto ret = m_example;
        m_example = nullptr;

        return ret;
    }

    void VowpalWabbitExampleBuilder::ParseLabel(String^ value)
    {
        if (value == nullptr)
            return;

        auto bytes = System::Text::Encoding::UTF8->GetBytes(value);
        auto valueHandle = GCHandle::Alloc(bytes, GCHandleType::Pinned);

        try
        {
            VW::parse_example_label(*m_vw->m_vw, *m_example->m_example, reinterpret_cast<char*>(valueHandle.AddrOfPinnedObject().ToPointer()));
        }
        CATCHRETHROW
        finally
        { valueHandle.Free();
        }
    }

    VowpalWabbitNamespaceBuilder^ VowpalWabbitExampleBuilder::AddNamespace(Char featureGroup)
    {
        return AddNamespace((Byte)featureGroup);
    }

    VowpalWabbitNamespaceBuilder^ VowpalWabbitExampleBuilder::AddNamespace(Byte featureGroup)
    {
        uint32_t index = featureGroup;
        example* ex = m_example->m_example;

        return gcnew VowpalWabbitNamespaceBuilder(ex->feature_space + index, featureGroup, m_example->m_example);
    }

    VowpalWabbitNamespaceBuilder::VowpalWabbitNamespaceBuilder(features* features,
        unsigned char index, example* example)
        : m_features(features), m_index(index), m_example(example)
    {
    }

    VowpalWabbitNamespaceBuilder::~VowpalWabbitNamespaceBuilder()
    {
        this->!VowpalWabbitNamespaceBuilder();
    }

    VowpalWabbitNamespaceBuilder::!VowpalWabbitNamespaceBuilder()
    {
        if (m_features->size() > 0)
        {
            unsigned char temp = m_index;
            m_example->indices.push_back(temp);
        }
    }

    void VowpalWabbitNamespaceBuilder::AddFeaturesUnchecked(uint64_t weight_index_base, float* begin, float* end)
    {
        for (; begin != end; begin++)
        {
            float x = *begin;
            if (x != 0)
            {
                m_features->values.push_back_unchecked(x);
                m_features->indicies.push_back_unchecked(weight_index_base);
            }
            weight_index_base++;
        }

    }

    void VowpalWabbitNamespaceBuilder::AddFeature(uint64_t weight_index, float x)
    {
        // filter out 0-values
        if (x == 0)
            return;

        m_features->push_back(x, weight_index);
    }

    void VowpalWabbitNamespaceBuilder::PreAllocate(int size)
    {
        m_features->values.resize(m_features->values.end - m_features->values.begin + size);
        m_features->indicies.resize(m_features->indicies.end - m_features->indicies.begin + size);
    }
}
<|endoftext|>


<commit_before>/*
        AtlasCodec.cpp
        ----------------
        begin           : 1999.11.29
        copyright       : (C) 1999 by John Barrett (ZW)
        email           : jbarrett@box100.com
*/

#include <stdio.h>

#include "AtlasCodec.h"

ACodec::ACodec(AProtocol* aproto)
{
	proto = aproto;
	proto->getDecoder()->newStream();

	state = codecIDLE;    // waiting for message to start

	nestd = 0;
}

string ACodec::encodeMessage(const AObject& amsg)
{
	return proto->getEncoder()->encodeMessage(amsg);
}

int ACodec::encodedLength()
{
	return proto->getEncoder()->encodedLength();
}

void ACodec::feedStream(string& data)
{
	proto->getDecoder()->feedStream(data);
}

AObject& ACodec::getMessage()
{
	DebugMsg1(5,"GETTING MESSAGE\n\n","");
	return msg;
}

void ACodec::freeMessage()
{
	//delete msg;
	//msg->clear();
}

int ACodec::hasMessage()
{
	// cant have a message until we have recieved tokens
	if (!proto->getDecoder()->hasTokens()) return 0;
	// got a token, we must be busy processing a message !!
	state = codecBUSY;
	// process tokens until we run out or we complete a msg
	DebugMsg1(1,"Scanning Tokens","");
	AProtocolDecoder* adec = proto->getDecoder();
	do {
		int tok = proto->getDecoder()->getToken();
		int type = proto->getDecoder()->getType();
		string name = proto->getDecoder()->getName();
		if (name.length() == 0) name = string("(null)");
		DebugMsg3(1,"tok=%i name=%s type=%i", tok, name.c_str(), type);
		if (tok == AProtocol::atlasATRVAL) {
			// got a value for an attribute
			if (type == AProtocol::atlasSTR) stack[nestd] = AObject::mkString(adec->getString());
			if (type == AProtocol::atlasINT) stack[nestd] = AObject::mkLong(adec->getInt());
			if (type == AProtocol::atlasFLT) stack[nestd] = AObject::mkFloat(adec->getFloat());
			DebugMsg2(1,"ADDATTR nestd=%i name=%s", nestd, name.c_str());
		}
		if (tok == AProtocol::atlasATRBEG) {
			// got an attribute header
			names[nestd] = name;
			if (type == AProtocol::atlasMAP) {
				// start a nested list
				DebugMsg1(1,"MAKE_MAP","");
				stack[nestd] = AObject::mkMap();
				DebugMsg2(1,"ADD_MAP nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLST) {
				// start a nested list
				stack[nestd] = AObject::mkList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else {
				// its a scalar, wait for the value
				waitn = 1;
			}
		}
		if (tok == AProtocol::atlasATREND) {
			// end of attribute detected.. un-nest
			if (type == AProtocol::atlasLST || type == AProtocol::atlasMAP) {
				nestd--;
				DebugMsg1(1,"ENDLIST nest=%i", nestd);
			}
			if (nestd > 0) {
				if (stack[nestd-1].isList()) {
					DebugMsg1(1,"UNSTACK nest=%i LIST", nestd);
					stack[nestd-1].append(stack[nestd]);
				} else {
					DebugMsg2(1,"UNSTACK nest=%i MAP name=%s", nestd, names[nestd].c_str());
					stack[nestd-1].set(names[nestd], stack[nestd]);
				}
			}
			waitn = 0;
		}
		if (tok == AProtocol::atlasMSGBEG) {
			// got a message header
			// start constructing a message on the stack
			// stack[0] = AObject::mkMap();
			nestd = 0;
			waitn = 0;
		}
		if (tok == AProtocol::atlasMSGEND) {
			// got a message trailer
			//assert(nestd == 1);
			// should have unraveled all nesting by now
			DebugMsg1(1,"MESSAGE COMPLETE","");
			msg = stack[0];
			state = codecIDLE; // get outa the loop !!
		}
	} while (proto->getDecoder()->hasTokens() && state == codecBUSY);
	// check if we have a complete message
	if (state == codecIDLE) {
		AObject::dump(msg);
		DebugMsg1(1,"Returning HAS MESSAGE !!","");
		return 1;
	}
	// still more message to process
	return 0;
}

<commit_msg>Codec decoder driver update for URI and Typed Lists<commit_after>/*
        AtlasCodec.cpp
        ----------------
        begin           : 1999.11.29
        copyright       : (C) 1999 by John Barrett (ZW)
        email           : jbarrett@box100.com
*/

#include <stdio.h>

#include "AtlasCodec.h"

ACodec::ACodec(AProtocol* aproto)
{
	proto = aproto;
	proto->getDecoder()->newStream();

	state = codecIDLE;    // waiting for message to start

	nestd = 0;
}

string ACodec::encodeMessage(const AObject& amsg)
{
	return proto->getEncoder()->encodeMessage(amsg);
}

int ACodec::encodedLength()
{
	return proto->getEncoder()->encodedLength();
}

void ACodec::feedStream(string& data)
{
	proto->getDecoder()->feedStream(data);
}

AObject& ACodec::getMessage()
{
	DebugMsg1(5,"GETTING MESSAGE\n\n","");
	return msg;
}

void ACodec::freeMessage()
{
	//delete msg;
	//msg->clear();
}

int ACodec::hasMessage()
{
	// cant have a message until we have recieved tokens
	if (!proto->getDecoder()->hasTokens()) return 0;
	// got a token, we must be busy processing a message !!
	state = codecBUSY;
	// process tokens until we run out or we complete a msg
	DebugMsg1(1,"Scanning Tokens","");
	AProtocolDecoder* adec = proto->getDecoder();
	do {
		int tok = proto->getDecoder()->getToken();
		int type = proto->getDecoder()->getType();
		string name = proto->getDecoder()->getName();
		if (name.length() == 0) name = string("(null)");
		DebugMsg3(1,"tok=%i name=%s type=%i", tok, name.c_str(), type);
		if (tok == AProtocol::atlasATRVAL) {
			// got a value for an attribute
			if (type == AProtocol::atlasSTR) stack[nestd] = AObject::mkString(adec->getString());
			if (type == AProtocol::atlasINT) stack[nestd] = AObject::mkInt(adec->getInt());
			if (type == AProtocol::atlasLNG) stack[nestd] = AObject::mkLong(adec->getInt());
			if (type == AProtocol::atlasURI) stack[nestd] = AObject::mkURI(adec->getString());
			if (type == AProtocol::atlasFLT) stack[nestd] = AObject::mkFloat(adec->getFloat());
			DebugMsg2(1,"ADDATTR nestd=%i name=%s", nestd, name.c_str());
		}
		if (tok == AProtocol::atlasATRBEG) {
			// got an attribute header
			names[nestd] = name;
			if (type == AProtocol::atlasMAP) {
				// start a nested list
				DebugMsg1(1,"MAKE_MAP","");
				stack[nestd] = AObject::mkMap();
				DebugMsg2(1,"ADD_MAP nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLST) {
				// start a nested list
				stack[nestd] = AObject::mkList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLSTURI) {
				// start a nested list
				stack[nestd] = AObject::mkURIList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLSTINT) {
				// start a nested list
				stack[nestd] = AObject::mkIntList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLSTLNG) {
				// start a nested list
				stack[nestd] = AObject::mkLongList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLSTFLT) {
				// start a nested list
				stack[nestd] = AObject::mkFloatList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else if (type == AProtocol::atlasLSTSTR) {
				// start a nested list
				stack[nestd] = AObject::mkStringList(0);
				DebugMsg2(1,"ADDLIST nestd=%i name=%s", nestd, names[nestd].c_str());
				nestd++;
			} else {
				// its a scalar, wait for the value
				waitn = 1;
			}
		}
		if (tok == AProtocol::atlasATREND) {
			// end of attribute detected.. un-nest
			if (type == AProtocol::atlasLST || type == AProtocol::atlasMAP) {
				nestd--;
				DebugMsg1(1,"ENDLIST nest=%i", nestd);
			}
			if (nestd > 0) {
				if (stack[nestd-1].isList()) {
					DebugMsg1(1,"UNSTACK nest=%i LIST", nestd);
					stack[nestd-1].append(stack[nestd]);
				} else {
					DebugMsg2(1,"UNSTACK nest=%i MAP name=%s", nestd, names[nestd].c_str());
					stack[nestd-1].set(names[nestd], stack[nestd]);
				}
			}
			waitn = 0;
		}
		if (tok == AProtocol::atlasMSGBEG) {
			// got a message header
			// start constructing a message on the stack
			// stack[0] = AObject::mkMap();
			nestd = 0;
			waitn = 0;
		}
		if (tok == AProtocol::atlasMSGEND) {
			// got a message trailer
			//assert(nestd == 1);
			// should have unraveled all nesting by now
			DebugMsg1(1,"MESSAGE COMPLETE","");
			msg = stack[0];
			state = codecIDLE; // get outa the loop !!
		}
	} while (proto->getDecoder()->hasTokens() && state == codecBUSY);
	// check if we have a complete message
	if (state == codecIDLE) {
		AObject::dump(msg);
		DebugMsg1(1,"Returning HAS MESSAGE !!","");
		return 1;
	}
	// still more message to process
	return 0;
}

<|endoftext|>


<commit_before>#include <bits/stdc++.h>

using namespace std;
const int N = 1e2 +5 , M = 1e4 +5, OO = 1000000007;

int n;
bool r[N], md[2*N+5], sd[5*N+5];
bool board[N][N];

void printSolution(){
  for(int i = 0 ; i < n ; ++i){
    for(int j = 0; j < n ; ++j)
      printf("%c", board[i][j]? 'Q' : '.');
    puts("");
  }
}

bool valid(int x, int y){
  return (!r[x] && !md[x-y+2*N] && !sd[x+y]);
}

bool solveNQ(int col = 0){
  if(col>=n)  return 1;
  for(int row = 0 ; row < n ; ++row){
    if(valid(row, col)){
      r[row] = 1;
      md[row-col+2*N] = 1;
      sd[row+col] = 1;
      board[row][col] = 1;
      if(solveNQ(col+1))  return 1;
      r[row] = 0;
      md[row-col+2*N] = 0;
      sd[row+col] = 0;
      board[row][col] = 0;
    }
  }
  return 0;
}

int main(){
  // freopen("i.in", "rt", stdin);
  // freopen("o.out", "wt", stdout);
  scanf("%d", &n);
  if(solveNQ()) printSolution();
  else  printf("No Solution\n");
  return 0;
}

/*
*/
<commit_msg>Made in a general form<commit_after>#include <cstdio>

using namespace std;
const int N = 15 , M = 1e4 +5, OO = 1000000007;

int n;
bool col[N], md[2*N], sd[2*N];
char board[N][N];

void printGrid(){
  puts("---------------------------------");
  for(int i = 0 ; i < n ; ++i){
    for(int j = 0; j < n ; ++j)
      printf("%c", board[i][j]);
    puts("");
  }
  puts("---------------------------------");
}

bool valid(int r, int c){
  return (!col[c] && !md[r-c+N] && !sd[r+c]);
}

void solveNQ(int r = 0){
  if(r == n){
    printGrid();
  }else{
    for(int c = 0 ; c < n ; ++c){
      if(valid(r, c)){
        col[c] = md[r-c+N] = sd[r+c] = 1;     //do
        board[r][c] = 'Q';                    //do
        solveNQ(r+1);                         //recurse
        col[c] = md[r-c+N] = sd[r+c] = 0;     //undo
        board[r][c] = '.';                    //undo
      }
    }
  }
}

int main(){
  scanf("%d", &n);
  for(int i = 0 ; i < n ; ++i)
    for(int j = 0 ; j < n ; ++j)  board[i][j] = '.';
  solveNQ();
  return 0;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <time.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "erl_interface.h"
#include "ei.h"

#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>

#include "types.hh"
#include "event_array.hh"
#include "leaderboard.hh"

#define BUFSIZE 1024

bool is_call_funcname(std::string func_name, ETERM* message);
#define IS_CALL_HANDLE_EVENT(X)      (is_call_funcname("event", X))
#define IS_CALL_GET_COUNTER(X)       (is_call_funcname("get_counter", X))
#define IS_CALL_GET_LEADERBOARD(X)   (is_call_funcname("get_leaderboard", X))
#define IS_CALL_LIST_LEADERBOARDS(X) (is_call_funcname("list_leaderboards", X))

int my_listen(int port);

std::string term2str(ETERM* ch_str) {
  unsigned char* str = ERL_BIN_PTR(ch_str);
  return std::string(str, str +  ERL_BIN_SIZE(ch_str));
}

std::ostream& operator<<(std::ostream& out,  const struct event e)  {
  out << "{" << e.event_idx << ", " << e.timestamp << " } ";
  return out;
}

std::ostream& operator<<(std::ostream& out,  const circular_queue<struct event>& queue)  {
  for(int i = 0; i != queue.size; i ++){
    int idx = (queue.back_p - queue.size + i)%queue.container_size;
    out << queue.data[idx] <<" ";
  }
  return out;
}

std::ostream& operator<<(std::ostream& out,  const circular_queue<int>& queue)  {
  for(int i = 0; i != queue.size; i ++){
    int idx = (queue.back_p - queue.size + i)%queue.container_size;
    out << queue.data[idx] <<" ";
  }
  return out;
}

int main(int argc, char **argv) {

  // tally_core ip localname longname secret
  if(argc != 5) {
    std::cout << "usage: ./tally_core <ip> <localname> <longname> <cookie>" << std::endl;
  }

  struct in_addr addr;                     /* 32-bit IP number of host */
  int listen;                              /* Listen socket */
  int fd;                                  /* fd to Erlang node */
  ErlConnect conn;                         /* Connection data */

  int loop = 1;                            /* Loop flag */
  int got;                                 /* Result of receive */
  unsigned char buf[BUFSIZE];              /* Buffer for incoming message */
  ErlMessage emsg;                         /* Incoming message */

  int port = 3456;// atoi(argv[1]);
  char *erl_secret    = argv[4];
  char erl_node[]     = "tally";
  char *erl_localname = argv[2];
  char *erl_longname  = argv[3];

  const unsigned int hour  = 60*60;
  const unsigned int day   = 24*hour;
  const unsigned int week  = 7*day;
  const unsigned int month = 4 *week;
  std::vector<unsigned> intervals = {10,     20,
                                     hour,   2*hour,
                                     day,    2*day,
                                     week,   2*week,
                                     month,  2*month};

  std::reverse(intervals.begin(), intervals.end());
  std::vector<event_array*> event_arrays;
  for(unsigned i : intervals) {
    if(event_arrays.empty()) event_arrays.push_back(new event_array(i));
    else event_arrays.push_back(new event_array(i, event_arrays.back()));
  }
  std::reverse(event_arrays.begin(), event_arrays.end());

  erl_init(NULL, 0);

  addr.s_addr = inet_addr(argv[1]);

  if (erl_connect_xinit(erl_localname, erl_node, erl_longname, &addr, erl_secret, 0) == -1)
    erl_err_quit("erl_connect_xinit failed");

  if ((listen = my_listen(port)) <= 0)
    erl_err_quit("my_listen failed ( likely unable to connect to socket )");

  if (erl_publish(port) == -1)
    erl_err_quit("erl_publish failed");

  if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
    erl_err_quit("erl_accept failed");

  while(true){

    loop = 1;

    while (loop) {
      // update the datastructure
      event_arrays.front()->update( time(0) );

      got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
      if (got == ERL_TICK) { /* ignore */ }
      else if (got == ERL_ERROR) {
        //      loop = 0;
      } else {

        if (emsg.type == ERL_REG_SEND) {
          if(IS_CALL_HANDLE_EVENT(emsg.msg)){
            ETERM* tuplep, *event_list, *binding_list;

            tuplep       = erl_element(3, emsg.msg);
            event_list   = erl_element(2, tuplep);
            binding_list = erl_element(3, tuplep);

            std::vector< std::string> counters;
            while(!ERL_IS_NIL(event_list)){
              ETERM* head = ERL_CONS_HEAD(event_list);
              counters.push_back(term2str(head));
              std::sort(counters.begin(), counters.end());
              event_list =  ERL_CONS_TAIL(event_list);
            }

            // for(auto& events : event_arrays) {
            //   std::cout << "timespan : " << events->timespan << std::endl;
            //   events->print();
            // }

            while(!ERL_IS_NIL(binding_list)){
              ETERM* head = ERL_CONS_HEAD(binding_list);
              std::string counter_id = term2str(erl_element(1, head));
              std::string lb_id      = term2str(erl_element(2, head));

              // std::cout << "leaderboard bind : "<< counter_id << " to " << lb_id << std::endl;

              if(event_array::lb_map.count(lb_id) == 0) {
                for(auto i : intervals) {
                  event_array::lb_map[lb_id][i] = new leaderboard;
                }
              }
              event_array::lb_lookup_map[counter_id].insert(lb_id);
              binding_list =  ERL_CONS_TAIL(binding_list);
            }

            event_arrays.front()->event(counters, time(0));
            erl_free_compound(tuplep);
          }
          else if (IS_CALL_GET_COUNTER(emsg.msg)) {
            ETERM *fromp;
            fromp = erl_element(2, emsg.msg);

            ETERM* tuplep;
            tuplep = erl_element(3, emsg.msg);

            std::string id_str = term2str(erl_element(2, tuplep));

            ETERM* list = erl_mk_empty_list();
            for(auto& events : event_arrays) {

              ETERM* tuple[2];
              tuple[0] = erl_mk_uint(events->timespan);

              // for(auto s : events->counters){
              //   std::cout << s.first << " : " << s.second << std::endl;
              // }
              tuple[1] = erl_mk_ulonglong(events->counters[id_str]);
              list = erl_cons(erl_mk_tuple(tuple, 2), list);
            }

            ETERM* tuple[2];
            tuple[0] = erl_mk_atom("tally");
            tuple[1] = list;
            ETERM* resp = erl_mk_tuple(tuple, 2);

            erl_send(fd, fromp, resp);
            erl_free_term(fromp);
            erl_free_term(resp);
          }
          else if (IS_CALL_GET_LEADERBOARD(emsg.msg)) {
            ETERM *fromp  = erl_element(2, emsg.msg);
            ETERM* tuplep = erl_element(3, emsg.msg);
            std::string  lb_id  = term2str(erl_element(2, tuplep));
            unsigned int lb_dim = ERL_INT_UVALUE(erl_element(3, tuplep));
            ETERM* list = erl_mk_empty_list();
            if(event_array::lb_map.count(lb_id) != 0 && event_array::lb_map[lb_id].size() != 0){
              for(auto entry = event_array::lb_map[lb_id][lb_dim]->board.begin();
                  entry != event_array::lb_map[lb_id][lb_dim]->board.end(); entry++) {
                ETERM* tuple[2];
                tuple[0] = erl_mk_binary(entry->second.c_str(), entry->second.length());
                tuple[1] = erl_mk_uint(entry->first);
                list = erl_cons(erl_mk_tuple(tuple, 2), list);
              }
            }

            ETERM* tuple[2];
            tuple[0] = erl_mk_atom("tally");
            tuple[1] = list;
            ETERM* resp = erl_mk_tuple(tuple, 2);

            erl_send(fd, fromp, resp);
            erl_free_term(fromp);
            erl_free_compound(resp);
          }

          else if (IS_CALL_LIST_LEADERBOARDS(emsg.msg)) {
            ETERM *fromp = erl_element(2, emsg.msg);
            ETERM* list  = erl_mk_empty_list();
            for(auto board : event_array::lb_map) {
              for(auto i : intervals) {
                ETERM* tuple[2];
                tuple[0] = erl_mk_binary(board.first.c_str(), board.first.length());
                tuple[1] = erl_mk_uint(i);
                list = erl_cons(erl_mk_tuple(tuple, 2), list);
              }
            }
            ETERM* tuple[2];
            tuple[0] = erl_mk_atom("tally");
            tuple[1] = list;
            ETERM* resp = erl_mk_tuple(tuple, 2);

            erl_send(fd, fromp, resp);
            erl_free_term(fromp);
            erl_free_compound(resp);
          }

          erl_free_term(emsg.to);
          erl_free_term(emsg.from);
          erl_free_term(emsg.msg);

        }
      }

    } /* while */
    erl_close_connection(fd);
  }
}

bool is_call_funcname(std::string func_name, ETERM* call_term) {
  ETERM  *tuplep = erl_element(3, call_term);
  ETERM  *fnp    = erl_element(1, tuplep   );

  // printf("testing : %s \n", ERL_ATOM_PTR(fnp));
  bool res = (strncmp(ERL_ATOM_PTR(fnp), func_name.c_str(), strlen(func_name.c_str())) == 0);

  erl_free_term(tuplep);
  erl_free_term(fnp);
  return res;
}

int my_listen(int port) {
  int listen_fd;
  struct sockaddr_in addr;
  int on = 1;

  if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    return (-1);

  setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

  memset((void*) &addr, 0, (size_t) sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
    return (-1);

  listen(listen_fd, 100);
  return listen_fd;
}

<commit_msg>support for inserts with known timestamps<commit_after>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <time.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "erl_interface.h"
#include "ei.h"

#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>

#include "types.hh"
#include "event_array.hh"
#include "leaderboard.hh"

#define BUFSIZE 1024

bool is_call_funcname(std::string func_name, ETERM* message);
#define IS_CALL_HANDLE_EVENT(X)      (is_call_funcname("event", X))
#define IS_CALL_HANDLE_EVENT_TZ(X)      (is_call_funcname("event_tz", X))
#define IS_CALL_GET_COUNTER(X)       (is_call_funcname("get_counter", X))
#define IS_CALL_GET_LEADERBOARD(X)   (is_call_funcname("get_leaderboard", X))
#define IS_CALL_LIST_LEADERBOARDS(X) (is_call_funcname("list_leaderboards", X))

int my_listen(int port);

std::string term2str(ETERM* ch_str) {
  unsigned char* str = ERL_BIN_PTR(ch_str);
  return std::string(str, str +  ERL_BIN_SIZE(ch_str));
}

std::ostream& operator<<(std::ostream& out,  const struct event e)  {
  out << "{" << e.event_idx << ", " << e.timestamp << " } ";
  return out;
}

std::ostream& operator<<(std::ostream& out,  const circular_queue<struct event>& queue)  {
  for(int i = 0; i != queue.size; i ++){
    int idx = (queue.back_p - queue.size + i)%queue.container_size;
    out << queue.data[idx] <<" ";
  }
  return out;
}

std::ostream& operator<<(std::ostream& out,  const circular_queue<int>& queue)  {
  for(int i = 0; i != queue.size; i ++){
    int idx = (queue.back_p - queue.size + i)%queue.container_size;
    out << queue.data[idx] <<" ";
  }
  return out;
}

int main(int argc, char **argv) {

  // tally_core ip localname longname secret
  if(argc != 5) {
    std::cout << "usage: ./tally_core <ip> <localname> <longname> <cookie>" << std::endl;
  }

  struct in_addr addr;                     /* 32-bit IP number of host */
  int listen;                              /* Listen socket */
  int fd;                                  /* fd to Erlang node */
  ErlConnect conn;                         /* Connection data */

  int loop = 1;                            /* Loop flag */
  int got;                                 /* Result of receive */
  unsigned char buf[BUFSIZE];              /* Buffer for incoming message */
  ErlMessage emsg;                         /* Incoming message */

  int port = 3456;// atoi(argv[1]);
  char *erl_secret    = argv[4];
  char erl_node[]     = "tally";
  char *erl_localname = argv[2];
  char *erl_longname  = argv[3];

  const unsigned int hour  = 60*60;
  const unsigned int day   = 24*hour;
  const unsigned int week  = 7*day;
  const unsigned int month = 4 *week;
  std::vector<unsigned> intervals = {10,     20,
                                     hour,   2*hour,
                                     day,    2*day,
                                     week,   2*week,
                                     month,  2*month};

  std::reverse(intervals.begin(), intervals.end());
  std::vector<event_array*> event_arrays;
  for(unsigned i : intervals) {
    if(event_arrays.empty()) event_arrays.push_back(new event_array(i));
    else event_arrays.push_back(new event_array(i, event_arrays.back()));
  }
  std::reverse(event_arrays.begin(), event_arrays.end());

  erl_init(NULL, 0);

  addr.s_addr = inet_addr(argv[1]);

  if (erl_connect_xinit(erl_localname, erl_node, erl_longname, &addr, erl_secret, 0) == -1)
    erl_err_quit("erl_connect_xinit failed");

  if ((listen = my_listen(port)) <= 0)
    erl_err_quit("my_listen failed ( likely unable to connect to socket )");

  if (erl_publish(port) == -1)
    erl_err_quit("erl_publish failed");

  if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
    erl_err_quit("erl_accept failed");

  while(true){

    loop = 1;

    while (loop) {
      // update the datastructure
      event_arrays.front()->update( time(0) );

      got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
      if (got == ERL_TICK) { /* ignore */ }
      else if (got == ERL_ERROR) {
        //      loop = 0;
      } else {

        if (emsg.type == ERL_REG_SEND) {
          if(IS_CALL_HANDLE_EVENT(emsg.msg)){
            ETERM* tuplep, *event_list, *binding_list;

            tuplep       = erl_element(3, emsg.msg);
            event_list   = erl_element(2, tuplep);
            binding_list = erl_element(3, tuplep);

            std::vector< std::string> counters;
            while(!ERL_IS_NIL(event_list)){
              ETERM* head = ERL_CONS_HEAD(event_list);
              counters.push_back(term2str(head));
              std::sort(counters.begin(), counters.end());
              event_list =  ERL_CONS_TAIL(event_list);
            }

            while(!ERL_IS_NIL(binding_list)){
              ETERM* head = ERL_CONS_HEAD(binding_list);
              std::string counter_id = term2str(erl_element(1, head));
              std::string lb_id      = term2str(erl_element(2, head));

              // std::cout << "leaderboard bind : "<< counter_id << " to " << lb_id << std::endl;

              if(event_array::lb_map.count(lb_id) == 0) {
                for(auto i : intervals) {
                  event_array::lb_map[lb_id][i] = new leaderboard;
                }
              }
              event_array::lb_lookup_map[counter_id].insert(lb_id);
              binding_list =  ERL_CONS_TAIL(binding_list);
            }

            event_arrays.front()->event(counters, time(0));
            erl_free_compound(tuplep);
          }
          else if(IS_CALL_HANDLE_EVENT_TZ(emsg.msg)){
            ETERM* tuplep, *event_list, *binding_list, *tz;

            tuplep       = erl_element(4, emsg.msg);
            event_list   = erl_element(2, tuplep);
            binding_list = erl_element(3, tuplep);
            tz           = erl_element(4, tuplep);

            std::vector< std::string> counters;
            while(!ERL_IS_NIL(event_list)){
              ETERM* head = ERL_CONS_HEAD(event_list);
              counters.push_back(term2str(head));
              std::sort(counters.begin(), counters.end());
              event_list =  ERL_CONS_TAIL(event_list);
            }

            while(!ERL_IS_NIL(binding_list)){
              ETERM* head = ERL_CONS_HEAD(binding_list);
              std::string counter_id = term2str(erl_element(1, head));
              std::string lb_id      = term2str(erl_element(2, head));

              // std::cout << "leaderboard bind : "<< counter_id << " to " << lb_id << std::endl;

              if(event_array::lb_map.count(lb_id) == 0) {
                for(auto i : intervals) {
                  event_array::lb_map[lb_id][i] = new leaderboard;
                }
              }
              event_array::lb_lookup_map[counter_id].insert(lb_id);
              binding_list =  ERL_CONS_TAIL(binding_list);
            }

            event_arrays.front()->event(counters,ERL_IS_INTEGER(tz));
            erl_free_compound(tuplep);
          }
          else if (IS_CALL_GET_COUNTER(emsg.msg)) {
            ETERM *fromp;
            fromp = erl_element(2, emsg.msg);

            ETERM* tuplep;
            tuplep = erl_element(3, emsg.msg);

            std::string id_str = term2str(erl_element(2, tuplep));

            ETERM* list = erl_mk_empty_list();
            for(auto& events : event_arrays) {

              ETERM* tuple[2];
              tuple[0] = erl_mk_uint(events->timespan);
              tuple[1] = erl_mk_ulonglong(events->counters[id_str]);
              list = erl_cons(erl_mk_tuple(tuple, 2), list);
            }

            ETERM* tuple[2];
            tuple[0] = erl_mk_atom("tally");
            tuple[1] = list;
            ETERM* resp = erl_mk_tuple(tuple, 2);

            erl_send(fd, fromp, resp);
            erl_free_term(fromp);
            erl_free_term(resp);
          }
          else if (IS_CALL_GET_LEADERBOARD(emsg.msg)) {
            ETERM *fromp  = erl_element(2, emsg.msg);
            ETERM* tuplep = erl_element(3, emsg.msg);
            std::string  lb_id  = term2str(erl_element(2, tuplep));
            unsigned int lb_dim = ERL_INT_UVALUE(erl_element(3, tuplep));
            ETERM* list = erl_mk_empty_list();

            if(event_array::lb_map.count(lb_id) != 0 && event_array::lb_map[lb_id].size() != 0){
              auto& board = event_array::lb_map[lb_id][lb_dim]->board;
              for(auto entry = board.begin(); entry != board.end(); entry++) {
                ETERM* tuple[2];
                tuple[0] = erl_mk_binary(entry->second.c_str(), entry->second.length());
                tuple[1] = erl_mk_uint(entry->first);

                list = erl_cons(erl_mk_tuple(tuple, 2), list);
              }
            }

            ETERM* tuple[2];
            tuple[0] = erl_mk_atom("tally");
            tuple[1] = list;
            ETERM* resp = erl_mk_tuple(tuple, 2);

            erl_send(fd, fromp, resp);
            erl_free_term(fromp);
            erl_free_compound(resp);
          }

          else if (IS_CALL_LIST_LEADERBOARDS(emsg.msg)) {
            ETERM *fromp = erl_element(2, emsg.msg);
            ETERM* list  = erl_mk_empty_list();
            for(auto board : event_array::lb_map) {
              for(auto i : intervals) {
                ETERM* tuple[2];
                tuple[0] = erl_mk_binary(board.first.c_str(), board.first.length());
                tuple[1] = erl_mk_uint(i);
                list = erl_cons(erl_mk_tuple(tuple, 2), list);
              }
            }
            ETERM* tuple[2];
            tuple[0] = erl_mk_atom("tally");
            tuple[1] = list;
            ETERM* resp = erl_mk_tuple(tuple, 2);

            erl_send(fd, fromp, resp);
            erl_free_term(fromp);
            erl_free_compound(resp);
          }

          erl_free_term(emsg.to);
          erl_free_term(emsg.from);
          erl_free_term(emsg.msg);

        }
      }

    } /* while */
    erl_close_connection(fd);
  }
}

bool is_call_funcname(std::string func_name, ETERM* call_term) {
  ETERM  *tuplep = erl_element(3, call_term);
  ETERM  *fnp    = erl_element(1, tuplep   );

  // printf("testing : %s \n", ERL_ATOM_PTR(fnp));
  bool res = (strncmp(ERL_ATOM_PTR(fnp), func_name.c_str(), strlen(func_name.c_str())) == 0);

  erl_free_term(tuplep);
  erl_free_term(fnp);
  return res;
}

int my_listen(int port) {
  int listen_fd;
  struct sockaddr_in addr;
  int on = 1;

  if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    return (-1);

  setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

  memset((void*) &addr, 0, (size_t) sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
    return (-1);

  listen(listen_fd, 100);
  return listen_fd;
}

<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <vector>
#include <chrono>

namespace Utility
{
    namespace Timer
    {
        class MeasureInfo
        {
        public:
            /**
                Constructor
            */
            MeasureInfo();

            /**
    Constructor
*/
            MeasureInfo(const std::string& p_name);

            /**
    Resets the timer
*/
            MeasureInfo& Reset();

            /**
            Starts the timer
            */
            MeasureInfo& Start();

            /**
            Stops the timer
            */
            MeasureInfo& Stop();

            /**
            Gets the elapsed seconds since started
            */
            double GetSeconds() const;

            const std::string& GetName() const { return name; }
            const size_t& GetStartCount() const { return m_startCount; }
            const size_t& GetStopCount() const { return m_stopCount; }

        protected:
            // TOODRT As it were an struct earlier the names are incorrect.
            std::string name;
            std::chrono::time_point<std::chrono::high_resolution_clock> startSeconds, stopSeconds;
            std::chrono::duration<double> accumulatedTime;
            //  double accumulatedTime;
            size_t m_startCount, m_stopCount;
        };
    }
}
<commit_msg>Removed unused variable<commit_after>#pragma once

#include <string>
#include <vector>
#include <chrono>

namespace Utility
{
    namespace Timer
    {
        class MeasureInfo
        {
        public:
            /**
                Constructor
            */
            MeasureInfo();

            /**
    Constructor
*/
            MeasureInfo(const std::string& p_name);

            /**
    Resets the timer
*/
            MeasureInfo& Reset();

            /**
            Starts the timer
            */
            MeasureInfo& Start();

            /**
            Stops the timer
            */
            MeasureInfo& Stop();

            /**
            Gets the elapsed seconds since started
            */
            double GetSeconds() const;

            const std::string& GetName() const { return name; }
            const size_t& GetStartCount() const { return m_startCount; }
            const size_t& GetStopCount() const { return m_stopCount; }

        protected:
            // TOODRT As it were an struct earlier the names are incorrect.
            std::string name;
            std::chrono::time_point<std::chrono::high_resolution_clock> startSeconds, stopSeconds;
            std::chrono::duration<double> accumulatedTime;
            size_t m_startCount, m_stopCount;
        };
    }
}
<|endoftext|>


<commit_before>/*
This file is part of the ORK library.
Full copyright and license terms can be found in the LICENSE.txt file.
*/
#include"ork/geometry.hpp"
#include"ork/xml.hpp"

#if ORK_USE_PUGI
#include"pugixml.hpp"
#endif

#if ORK_USE_JSON
#include"json/json.h"
#endif

namespace ork {
namespace xml {

#if ORK_USE_PUGI

void export_file(const string&filename, const exportable&object, const string&root_node_name) {
	pugi::xml_document doc;
	object.export_xml(doc.append_child(root_node_name.c_str()));
	ork::ensure_directory(filename);
	ORK_FILE_WRITE(filename);
	doc.save(fout);
}
void load_and_parse(i_stream&fin, pugi::xml_document&xml) {
	pugi::xml_parse_result result = xml.load(fin);
	if(!result) {
		ORK_THROW(ORK("XML parse error") \
			<< ORK("\n -- Error: ") << result.description() \
			<< ORK("\n -- Offset: ") << result.offset)//<< ORK(" at [") << (source + result.offset) << ORK("]"))
	}
	else {
		ORK_LOG(ork::severity_level::trace) << ORK("XML parse success");
	}
}

#endif

#if ORK_USE_GLM

double&vector::x() {
	return _data.x;
}
const double&vector::x()const {
	return _data.x;
}

double&vector::y() {
	return _data.y;
}
const double&vector::y()const {
	return _data.y;
}

double&vector::z() {
	return _data.z;
}
const double&vector::z()const {
	return _data.z;
}

glm::dvec3&vector::get() {
	return _data;
}
const glm::dvec3&vector::get()const {
	return _data;
}

string vector::as_string() const {
	string_stream stream;
	stream << ORK("(") << to_dimension(_data.x)
		<< ORK(", ") << to_dimension(_data.y)
		<< ORK(", ") << to_dimension(_data.z) << ORK(")");
	return stream.str();
}

bool vector::operator == (const vector &other) const {
	return GLM::equal(_data, other._data);
}

#if ORK_USE_PUGI
vector::vector(pugi::xml_node &node) {
	_data.x = node.attribute(ORK("x")).as_double();
	_data.y = node.attribute(ORK("y")).as_double();
	_data.z = node.attribute(ORK("z")).as_double();
}
void vector::export_xml(pugi::xml_node &node) const {
	node.append_attribute(ORK("x")).set_value(to_dimension(_data.x).c_str());
	node.append_attribute(ORK("y")).set_value(to_dimension(_data.y).c_str());
	node.append_attribute(ORK("z")).set_value(to_dimension(_data.z).c_str());
}
#endif

#endif//ORK_USE_GLM

}//namespace xml

namespace json {

#if ORK_USE_JSON

void export_file(const string&filename, const exportable&object) {
	ork::ensure_directory(filename);
	ORK_FILE_WRITE(ORK("filename.json"));
	Json::Value root;
	object.export_json(root);
	fout << root << BORK("\n");
}
void load_and_parse(i_stream&fin, Json::Value&root) {
	fin >> root;
}

#endif

}//namespace json
}//namespace ork
<commit_msg>Fixed bug in json export filename<commit_after>/*
This file is part of the ORK library.
Full copyright and license terms can be found in the LICENSE.txt file.
*/
#include"ork/geometry.hpp"
#include"ork/xml.hpp"

#if ORK_USE_PUGI
#include"pugixml.hpp"
#endif

#if ORK_USE_JSON
#include"json/json.h"
#endif

namespace ork {
namespace xml {

#if ORK_USE_PUGI

void export_file(const string&filename, const exportable&object, const string&root_node_name) {
	pugi::xml_document doc;
	object.export_xml(doc.append_child(root_node_name.c_str()));
	ork::ensure_directory(filename);
	ORK_FILE_WRITE(filename);
	doc.save(fout);
}
void load_and_parse(i_stream&fin, pugi::xml_document&xml) {
	pugi::xml_parse_result result = xml.load(fin);
	if(!result) {
		ORK_THROW(ORK("XML parse error") \
			<< ORK("\n -- Error: ") << result.description() \
			<< ORK("\n -- Offset: ") << result.offset)//<< ORK(" at [") << (source + result.offset) << ORK("]"))
	}
	else {
		ORK_LOG(ork::severity_level::trace) << ORK("XML parse success");
	}
}

#endif

#if ORK_USE_GLM

double&vector::x() {
	return _data.x;
}
const double&vector::x()const {
	return _data.x;
}

double&vector::y() {
	return _data.y;
}
const double&vector::y()const {
	return _data.y;
}

double&vector::z() {
	return _data.z;
}
const double&vector::z()const {
	return _data.z;
}

glm::dvec3&vector::get() {
	return _data;
}
const glm::dvec3&vector::get()const {
	return _data;
}

string vector::as_string() const {
	string_stream stream;
	stream << ORK("(") << to_dimension(_data.x)
		<< ORK(", ") << to_dimension(_data.y)
		<< ORK(", ") << to_dimension(_data.z) << ORK(")");
	return stream.str();
}

bool vector::operator == (const vector &other) const {
	return GLM::equal(_data, other._data);
}

#if ORK_USE_PUGI
vector::vector(pugi::xml_node &node) {
	_data.x = node.attribute(ORK("x")).as_double();
	_data.y = node.attribute(ORK("y")).as_double();
	_data.z = node.attribute(ORK("z")).as_double();
}
void vector::export_xml(pugi::xml_node &node) const {
	node.append_attribute(ORK("x")).set_value(to_dimension(_data.x).c_str());
	node.append_attribute(ORK("y")).set_value(to_dimension(_data.y).c_str());
	node.append_attribute(ORK("z")).set_value(to_dimension(_data.z).c_str());
}
#endif

#endif//ORK_USE_GLM

}//namespace xml

namespace json {

#if ORK_USE_JSON

void export_file(const string&filename, const exportable&object) {
	ork::ensure_directory(filename);
	ORK_FILE_WRITE(filename);

	Json::Value root;
	object.export_json(root);

	Json::StyledWriter writer;
	fout << writer.write(root);
}
void load_and_parse(i_stream&fin, Json::Value&root) {
	fin >> root;
}

#endif

}//namespace json
}//namespace ork
<|endoftext|>