<commit_before>/**
 * @file   serialization_macros.hpp
 * @author Simon Lynen <simon.lynen@mavt.ethz.ch>
 * @date   Thu May 22 02:55:13 2013
 *
 * @brief  Comparison macros to facilitate checking in serialization methods.
 *
 *
 */

#ifndef SM_SERIALIZATION_MACROS_HPP
#define SM_SERIALIZATION_MACROS_HPP

#include <type_traits>
#include <sstream>
#include <ostream>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/shared_ptr.hpp>
#include <sm/typetraits.hpp>

namespace cv{
class Mat;
}

namespace sm{
namespace serialization{
namespace internal_types{
typedef char yes;
typedef int no;
}
}

struct AnyT {
  template<class T> AnyT(const T &);
};

sm::serialization::internal_types::no operator <<(const AnyT &, const AnyT &);

namespace serialization{
namespace internal{

template<class T> sm::serialization::internal_types::yes check(const T&);
sm::serialization::internal_types::no check(sm::serialization::internal_types::no);

struct makeCompilerSilent{ //rm warning about unused functions
  void foo(){
    check(sm::serialization::internal_types::no());
    AnyT t(5);
    operator <<(t, t);
  }
};

//this template metaprogramming struct can tell us if there is the operator<< defined somewhere
template<typename StreamType, typename T>
class HasOStreamOperator {
  static StreamType & stream;
  static T & x;
 public:
  enum {
    value = sizeof(check(stream << x)) == sizeof(sm::serialization::internal_types::yes)
  };
};

template<typename StreamType, typename T>
class HasOStreamOperator<StreamType, boost::shared_ptr<T> > {
 public:
  enum {
     value = HasOStreamOperator<StreamType, T>::value
   };
};

template<typename StreamType, typename T>
class HasOStreamOperator<StreamType, T* > {
 public:
  enum {
     value = HasOStreamOperator<StreamType, T>::value
   };
};

template<typename StreamType, typename T>
class HasOStreamOperator<StreamType, T& > {
 public:
  enum {
     value = HasOStreamOperator<StreamType, T>::value
   };
};

//this template metaprogramming struct can tell us whether a class has a member
//function isBinaryEqual
template<typename T>
class HasIsBinaryEqual {
  //for non const methods (which is actually wrong)
  template<typename U, bool (U::*)(const T&)> struct Check;
  template<typename U> static char func(Check<U, &U::isBinaryEqual> *);
  template<typename U> static int func(...);
  //for const methods
  template<typename U, bool (U::*)(const T&) const> struct CheckConst;
  template<typename U> static char funcconst(CheckConst<U, &U::isBinaryEqual> *);
  template<typename U> static int funcconst(...);
 public:
  enum {
    value = (sizeof(func<T>(0)) == sizeof(char)) || (sizeof(funcconst<T>(0)) == sizeof(char))
  };
};
template<typename T>
class HasIsBinaryEqual<boost::shared_ptr<T> > {
 public:
  enum {
    value = HasIsBinaryEqual<T>::value
  };
};
template<typename T>
class HasIsBinaryEqual<T*> {
 public:
  enum {
    value = HasIsBinaryEqual<T>::value
  };
};
template<typename T>
class HasIsBinaryEqual<T&> {
 public:
  enum {
    value = HasIsBinaryEqual<T>::value
  };
};

//these structs are used to choose between isBinaryEqual function call and the
//default operator==
template<bool, typename A>
struct isSame;

template<typename A>
struct isSame<true, A> {
  static bool eval(const A& lhs, const A& rhs) {
    return lhs.isBinaryEqual(rhs);
  }
};

template<typename A>
struct isSame<true, boost::shared_ptr<A> > {
  static bool eval(const boost::shared_ptr<A>& lhs, const boost::shared_ptr<A>& rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return lhs->isBinaryEqual(*rhs);
  }
};

template<typename A>
struct isSame<true, A* > {
  static bool eval(const A* const lhs, const A* const rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return lhs->isBinaryEqual(*rhs);
  }
};

template<typename A>
struct isSame<false, A> {
  static bool eval(const A& lhs, const A& rhs) {
    return lhs == rhs;
  }
};

template<typename A>
struct isSame<false, A*> {
  static bool eval(A const * lhs, A const * rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return *lhs == *rhs;
  }
};

template<typename A>
struct isSame<false, boost::shared_ptr<A> > {
  static bool eval(const boost::shared_ptr<A>& lhs, const boost::shared_ptr<A>& rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return *lhs == *rhs;
  }
};

//for opencv Mat we have to use the sm opencv isBinaryEqual method otherwise sm_common has to depend on sm_opencv

template<typename T, bool B>
struct checkTypeIsNotOpencvMat {
  enum{
    value = true,
  };
};

template<bool B>
struct checkTypeIsNotOpencvMat<cv::Mat, B> {
  enum{
    value = true, //yes true is correct here
  };
  BOOST_STATIC_ASSERT_MSG((B == !B) /*false*/, "You cannot use the macro SM_CHECKSAME or SM_CHECKSAMEMEMBER on opencv mat. Use sm::opencv::isBinaryEqual instead");
};

template<bool B>
struct checkTypeIsNotOpencvMat<boost::shared_ptr<cv::Mat>, B > {
  enum{
    value = true, //yes true is correct here
  };
  BOOST_STATIC_ASSERT_MSG((B == !B) /*false*/, "You cannot use the macro SM_CHECKSAME or SM_CHECKSAMEMEMBER on opencv mat. Use sm::opencv::isBinaryEqual instead");
};

template<bool B>
struct checkTypeIsNotOpencvMat<cv::Mat*, B> {
  enum{
    value = true, //yes true is correct here
  };
  BOOST_STATIC_ASSERT_MSG((B == !B) /*false*/, "You cannot use the macro SM_CHECKSAME or SM_CHECKSAMEMEMBER on opencv mat. Use sm::opencv::isBinaryEqual instead");
};

//if the object supports it stream to ostream, otherwise put NA
template<bool, typename A>
struct streamIf;

template<typename A>
struct streamIf<true, A> {
  static std::string eval(const A& rhs) {
    std::stringstream ss;
    ss << rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<true, A*> {
  static std::string eval(const A* rhs) {
    if (!rhs) {
      return "NULL";
    }
    std::stringstream ss;
    ss << *rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<true, boost::shared_ptr<A> > {
  static std::string eval(const boost::shared_ptr<A>& rhs) {
    if (!rhs) {
      return "NULL";
    }
    std::stringstream ss;
    ss << *rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<true, boost::shared_ptr<const A> > {
  static std::string eval(const boost::shared_ptr<const A>& rhs) {
    if (!rhs) {
      return "NULL";
    }
    std::stringstream ss;
    ss << *rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<false, A> {
  static std::string eval(const A&) {
    return "NA";
  }
};
}
}
}

//these defines set the default behaviour if no verbosity argument is given
#define SM_SERIALIZATION_CHECKSAME_VERBOSE(THIS, OTHER) SM_SERIALIZATION_CHECKSAME_IMPL(THIS, OTHER, true)
#define SM_SERIALIZATION_CHECKMEMBERSSAME_VERBOSE(OTHER, MEMBER) SM_SERIALIZATION_CHECKMEMBERSSAME_IMPL(OTHER, MEMBER, true)

#define SM_SERIALIZATION_CHECKSAME_IMPL(THIS, OTHER, VERBOSE) \
    (sm::serialization::internal::checkTypeIsNotOpencvMat<typename sm::common::StripConstReference<decltype(OTHER)>::result_t, false>::value &&  /*for opencvMats we have to use sm::opencv::isBinaryEqual otherwise this code has to depend on opencv*/ \
    sm::serialization::internal::isSame<sm::serialization::internal::HasIsBinaryEqual<typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::value, /*first run the test of equality: either isBinaryEqual or op==*/ \
    typename sm::common::StripConstReference<decltype(OTHER)>::result_t >::eval(THIS, OTHER)) ? true : /*return true if good*/ \
    (VERBOSE ? (std::cout <<  "*** Validation failed on " << #OTHER << ": "<< /*if not true, check whether VERBOSE and then try to output the failed values using operator<<*/  \
    sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::value, /*here we check whether operator<< is available*/ \
    typename sm::common::StripConstReference<decltype(OTHER)>::result_t >::eval(THIS) << \
    " other " << sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::eval(OTHER) \
    << " at " << __PRETTY_FUNCTION__ << /*we print the function where this happened*/ \
    " In: " << __FILE__ << ":" << __LINE__ << std::endl << std::endl) && false : false) /*we print the line and file where this happened*/

#define SM_SERIALIZATION_CHECKMEMBERSSAME_IMPL(OTHER, MEMBER, VERBOSE) \
    ((sm::serialization::internal::checkTypeIsNotOpencvMat<typename sm::common::StripConstReference<decltype(OTHER)>::result_t, false>::value) &&  /*for opencvMats we have to use sm::opencv::isBinaryEqual otherwise this code has to depend on opencv*/\
    (sm::serialization::internal::isSame<sm::serialization::internal::HasIsBinaryEqual<typename sm::common::StripConstReference<decltype(MEMBER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(MEMBER)>::result_t >::eval(this->MEMBER, OTHER.MEMBER))) ? true :\
    (VERBOSE ? (std::cout <<  "*** Validation failed on " << #MEMBER << ": "<< \
        sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(MEMBER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(MEMBER)>::result_t >::eval(this->MEMBER) << \
    " other " << sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(MEMBER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(MEMBER)>::result_t >::eval(OTHER.MEMBER) \
    << " at " << __PRETTY_FUNCTION__ << \
    " In: " << __FILE__ << ":" << __LINE__ << std::endl << std::endl) && false : false)

//this is some internal default macro parameter deduction
#define SM_SERIALIZATION_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
#define SM_SERIALIZATION_GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4

#define SM_SERIALIZATION_MACRO_CHOOSER_MEMBER_SAME(...) \
    SM_SERIALIZATION_GET_4TH_ARG(__VA_ARGS__, SM_SERIALIZATION_CHECKMEMBERSSAME_IMPL,  SM_SERIALIZATION_CHECKMEMBERSSAME_VERBOSE )
#define SM_SERIALIZATION_MACRO_CHOOSER_SAME(...) \
    SM_SERIALIZATION_GET_4TH_ARG(__VA_ARGS__, SM_SERIALIZATION_CHECKSAME_IMPL,  SM_SERIALIZATION_CHECKSAME_VERBOSE )

//\brief This macro checks this->MEMBER against OTHER.MEMBER  with the appropriate IsBinaryEqual or operator==.
//Pointers and boost::shared_ptr are handled automatically
#define SM_CHECKMEMBERSSAME(...) SM_SERIALIZATION_MACRO_CHOOSER_MEMBER_SAME(__VA_ARGS__)(__VA_ARGS__)

//\brief This macro checks THIS against OTHER with the appropriate IsBinaryEqual or operator==.
//Pointers and boost::shared_ptr are handled automatically
#define SM_CHECKSAME(...) SM_SERIALIZATION_MACRO_CHOOSER_SAME(__VA_ARGS__)(__VA_ARGS__)

#endif //SM_SERIALIZATION_MACROS_HPP
<commit_msg>hiding of internal types otherwise sm_assert macros somehow uses them if they are also in sm::<commit_after>/**
 * @file   serialization_macros.hpp
 * @author Simon Lynen <simon.lynen@mavt.ethz.ch>
 * @date   Thu May 22 02:55:13 2013
 *
 * @brief  Comparison macros to facilitate checking in serialization methods.
 *
 *
 */

#ifndef SM_SERIALIZATION_MACROS_HPP
#define SM_SERIALIZATION_MACROS_HPP

#include <type_traits>
#include <sstream>
#include <ostream>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/shared_ptr.hpp>
#include <sm/typetraits.hpp>

namespace cv{
class Mat;
}

namespace sm_serialization{
namespace internal_types{
typedef char yes;
typedef int no;
}
}

struct AnyT {
  template<class T> AnyT(const T &);
};

sm_serialization::internal_types::no operator <<(const AnyT &, const AnyT &);

namespace sm{
namespace serialization{
namespace internal{

template<class T> sm_serialization::internal_types::yes check(const T&);
sm_serialization::internal_types::no check(sm_serialization::internal_types::no);

struct makeCompilerSilent{ //rm warning about unused functions
  void foo(){
    check(sm_serialization::internal_types::no());
    AnyT t(5);
    operator <<(t, t);
  }
};

//this template metaprogramming struct can tell us if there is the operator<< defined somewhere
template<typename StreamType, typename T>
class HasOStreamOperator {
  static StreamType & stream;
  static T & x;
 public:
  enum {
    value = sizeof(check(stream << x)) == sizeof(sm_serialization::internal_types::yes)
  };
};

template<typename StreamType, typename T>
class HasOStreamOperator<StreamType, boost::shared_ptr<T> > {
 public:
  enum {
     value = HasOStreamOperator<StreamType, T>::value
   };
};

template<typename StreamType, typename T>
class HasOStreamOperator<StreamType, T* > {
 public:
  enum {
     value = HasOStreamOperator<StreamType, T>::value
   };
};

template<typename StreamType, typename T>
class HasOStreamOperator<StreamType, T& > {
 public:
  enum {
     value = HasOStreamOperator<StreamType, T>::value
   };
};

//this template metaprogramming struct can tell us whether a class has a member
//function isBinaryEqual
template<typename T>
class HasIsBinaryEqual {
  //for non const methods (which is actually wrong)
  template<typename U, bool (U::*)(const T&)> struct Check;
  template<typename U> static char func(Check<U, &U::isBinaryEqual> *);
  template<typename U> static int func(...);
  //for const methods
  template<typename U, bool (U::*)(const T&) const> struct CheckConst;
  template<typename U> static char funcconst(CheckConst<U, &U::isBinaryEqual> *);
  template<typename U> static int funcconst(...);
 public:
  enum {
    value = (sizeof(func<T>(0)) == sizeof(char)) || (sizeof(funcconst<T>(0)) == sizeof(char))
  };
};
template<typename T>
class HasIsBinaryEqual<boost::shared_ptr<T> > {
 public:
  enum {
    value = HasIsBinaryEqual<T>::value
  };
};
template<typename T>
class HasIsBinaryEqual<T*> {
 public:
  enum {
    value = HasIsBinaryEqual<T>::value
  };
};
template<typename T>
class HasIsBinaryEqual<T&> {
 public:
  enum {
    value = HasIsBinaryEqual<T>::value
  };
};

//these structs are used to choose between isBinaryEqual function call and the
//default operator==
template<bool, typename A>
struct isSame;

template<typename A>
struct isSame<true, A> {
  static bool eval(const A& lhs, const A& rhs) {
    return lhs.isBinaryEqual(rhs);
  }
};

template<typename A>
struct isSame<true, boost::shared_ptr<A> > {
  static bool eval(const boost::shared_ptr<A>& lhs, const boost::shared_ptr<A>& rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return lhs->isBinaryEqual(*rhs);
  }
};

template<typename A>
struct isSame<true, A* > {
  static bool eval(const A* const lhs, const A* const rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return lhs->isBinaryEqual(*rhs);
  }
};

template<typename A>
struct isSame<false, A> {
  static bool eval(const A& lhs, const A& rhs) {
    return lhs == rhs;
  }
};

template<typename A>
struct isSame<false, A*> {
  static bool eval(A const * lhs, A const * rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return *lhs == *rhs;
  }
};

template<typename A>
struct isSame<false, boost::shared_ptr<A> > {
  static bool eval(const boost::shared_ptr<A>& lhs, const boost::shared_ptr<A>& rhs) {
    if (!lhs && !rhs) {
      return true;
    }
    if (!lhs || !rhs) {
      return false;
    }
    return *lhs == *rhs;
  }
};

//for opencv Mat we have to use the sm opencv isBinaryEqual method otherwise sm_common has to depend on sm_opencv

template<typename T, bool B>
struct checkTypeIsNotOpencvMat {
  enum{
    value = true,
  };
};

template<bool B>
struct checkTypeIsNotOpencvMat<cv::Mat, B> {
  enum{
    value = true, //yes true is correct here
  };
  BOOST_STATIC_ASSERT_MSG((B == !B) /*false*/, "You cannot use the macro SM_CHECKSAME or SM_CHECKSAMEMEMBER on opencv mat. Use sm::opencv::isBinaryEqual instead");
};

template<bool B>
struct checkTypeIsNotOpencvMat<boost::shared_ptr<cv::Mat>, B > {
  enum{
    value = true, //yes true is correct here
  };
  BOOST_STATIC_ASSERT_MSG((B == !B) /*false*/, "You cannot use the macro SM_CHECKSAME or SM_CHECKSAMEMEMBER on opencv mat. Use sm::opencv::isBinaryEqual instead");
};

template<bool B>
struct checkTypeIsNotOpencvMat<cv::Mat*, B> {
  enum{
    value = true, //yes true is correct here
  };
  BOOST_STATIC_ASSERT_MSG((B == !B) /*false*/, "You cannot use the macro SM_CHECKSAME or SM_CHECKSAMEMEMBER on opencv mat. Use sm::opencv::isBinaryEqual instead");
};

//if the object supports it stream to ostream, otherwise put NA
template<bool, typename A>
struct streamIf;

template<typename A>
struct streamIf<true, A> {
  static std::string eval(const A& rhs) {
    std::stringstream ss;
    ss << rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<true, A*> {
  static std::string eval(const A* rhs) {
    if (!rhs) {
      return "NULL";
    }
    std::stringstream ss;
    ss << *rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<true, boost::shared_ptr<A> > {
  static std::string eval(const boost::shared_ptr<A>& rhs) {
    if (!rhs) {
      return "NULL";
    }
    std::stringstream ss;
    ss << *rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<true, boost::shared_ptr<const A> > {
  static std::string eval(const boost::shared_ptr<const A>& rhs) {
    if (!rhs) {
      return "NULL";
    }
    std::stringstream ss;
    ss << *rhs;
    return ss.str();
  }
};

template<typename A>
struct streamIf<false, A> {
  static std::string eval(const A&) {
    return "NA";
  }
};
}
}
}

//these defines set the default behaviour if no verbosity argument is given
#define SM_SERIALIZATION_CHECKSAME_VERBOSE(THIS, OTHER) SM_SERIALIZATION_CHECKSAME_IMPL(THIS, OTHER, true)
#define SM_SERIALIZATION_CHECKMEMBERSSAME_VERBOSE(OTHER, MEMBER) SM_SERIALIZATION_CHECKMEMBERSSAME_IMPL(OTHER, MEMBER, true)

#define SM_SERIALIZATION_CHECKSAME_IMPL(THIS, OTHER, VERBOSE) \
    (sm::serialization::internal::checkTypeIsNotOpencvMat<typename sm::common::StripConstReference<decltype(OTHER)>::result_t, false>::value &&  /*for opencvMats we have to use sm::opencv::isBinaryEqual otherwise this code has to depend on opencv*/ \
    sm::serialization::internal::isSame<sm::serialization::internal::HasIsBinaryEqual<typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::value, /*first run the test of equality: either isBinaryEqual or op==*/ \
    typename sm::common::StripConstReference<decltype(OTHER)>::result_t >::eval(THIS, OTHER)) ? true : /*return true if good*/ \
    (VERBOSE ? (std::cout <<  "*** Validation failed on " << #OTHER << ": "<< /*if not true, check whether VERBOSE and then try to output the failed values using operator<<*/  \
    sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::value, /*here we check whether operator<< is available*/ \
    typename sm::common::StripConstReference<decltype(OTHER)>::result_t >::eval(THIS) << \
    " other " << sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(OTHER)>::result_t>::eval(OTHER) \
    << " at " << __PRETTY_FUNCTION__ << /*we print the function where this happened*/ \
    " In: " << __FILE__ << ":" << __LINE__ << std::endl << std::endl) && false : false) /*we print the line and file where this happened*/

#define SM_SERIALIZATION_CHECKMEMBERSSAME_IMPL(OTHER, MEMBER, VERBOSE) \
    ((sm::serialization::internal::checkTypeIsNotOpencvMat<typename sm::common::StripConstReference<decltype(OTHER)>::result_t, false>::value) &&  /*for opencvMats we have to use sm::opencv::isBinaryEqual otherwise this code has to depend on opencv*/\
    (sm::serialization::internal::isSame<sm::serialization::internal::HasIsBinaryEqual<typename sm::common::StripConstReference<decltype(MEMBER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(MEMBER)>::result_t >::eval(this->MEMBER, OTHER.MEMBER))) ? true :\
    (VERBOSE ? (std::cout <<  "*** Validation failed on " << #MEMBER << ": "<< \
        sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(MEMBER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(MEMBER)>::result_t >::eval(this->MEMBER) << \
    " other " << sm::serialization::internal::streamIf<sm::serialization::internal::HasOStreamOperator<std::ostream, typename sm::common::StripConstReference<decltype(MEMBER)>::result_t>::value, \
    typename sm::common::StripConstReference<decltype(MEMBER)>::result_t >::eval(OTHER.MEMBER) \
    << " at " << __PRETTY_FUNCTION__ << \
    " In: " << __FILE__ << ":" << __LINE__ << std::endl << std::endl) && false : false)

//this is some internal default macro parameter deduction
#define SM_SERIALIZATION_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
#define SM_SERIALIZATION_GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4

#define SM_SERIALIZATION_MACRO_CHOOSER_MEMBER_SAME(...) \
    SM_SERIALIZATION_GET_4TH_ARG(__VA_ARGS__, SM_SERIALIZATION_CHECKMEMBERSSAME_IMPL,  SM_SERIALIZATION_CHECKMEMBERSSAME_VERBOSE )
#define SM_SERIALIZATION_MACRO_CHOOSER_SAME(...) \
    SM_SERIALIZATION_GET_4TH_ARG(__VA_ARGS__, SM_SERIALIZATION_CHECKSAME_IMPL,  SM_SERIALIZATION_CHECKSAME_VERBOSE )

//\brief This macro checks this->MEMBER against OTHER.MEMBER  with the appropriate IsBinaryEqual or operator==.
//Pointers and boost::shared_ptr are handled automatically
#define SM_CHECKMEMBERSSAME(...) SM_SERIALIZATION_MACRO_CHOOSER_MEMBER_SAME(__VA_ARGS__)(__VA_ARGS__)

//\brief This macro checks THIS against OTHER with the appropriate IsBinaryEqual or operator==.
//Pointers and boost::shared_ptr are handled automatically
#define SM_CHECKSAME(...) SM_SERIALIZATION_MACRO_CHOOSER_SAME(__VA_ARGS__)(__VA_ARGS__)

#endif //SM_SERIALIZATION_MACROS_HPP
<|endoftext|>


<commit_before><commit_msg>[Minor] Support time_t args in clang plugin<commit_after><|endoftext|>


<commit_before>
#include <math.h>
#include <netdb.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include "statsd_client.h"
#include <fcntl.h>

using namespace std;
namespace statsd {

inline bool fequal(float a, float b)
{
    const float epsilon = 0.0001;
    return ( fabs(a - b) < epsilon );
}

inline bool should_send(float sample_rate)
{
    if ( fequal(sample_rate, 1.0) )
    {
        return true;
    }

    float p = ((float)random() / RAND_MAX);
    return sample_rate > p;
}

struct _StatsdClientData {
    int     sock;
    struct  sockaddr_in server;

    string  ns;
    string  host;
    short   port;
    bool    init;

    char    errmsg[1024];
};

StatsdClient::StatsdClient(const string& host, int port, const string& ns)
{
    d = new _StatsdClientData;
    d->sock = -1;
    config(host, port, ns);
    srandom(time(NULL));
}

StatsdClient::~StatsdClient()
{
    // close socket
    if (d->sock >= 0) {
        close(d->sock);
        d->sock = -1;
        delete d;
        d = NULL;
    }
}

void StatsdClient::config(const string& host, int port, const string& ns)
{
    d->ns = ns;
    d->host = host;
    d->port = port;
    d->init = false;
    if ( d->sock >= 0 ) {
        close(d->sock);
    }
    d->sock = -1;
}

int StatsdClient::init()
{
    if ( d->init ) return 0;

    d->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if ( d->sock == -1 ) {
        snprintf(d->errmsg, sizeof(d->errmsg), "could not create socket, err=%m");
        return -1;
    }

    memset(&d->server, 0, sizeof(d->server));
    d->server.sin_family = AF_INET;
    d->server.sin_port = htons(d->port);

    int ret = inet_aton(d->host.c_str(), &d->server.sin_addr);
    if ( ret == 0 )
    {
        // host must be a domain, get it from internet
        struct addrinfo hints, *result = NULL;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_DGRAM;

        ret = getaddrinfo(d->host.c_str(), NULL, &hints, &result);
        if ( ret ) {
            snprintf(d->errmsg, sizeof(d->errmsg),
                    "getaddrinfo fail, error=%d, msg=%s", ret, gai_strerror(ret) );
            return -2;
        }
        struct sockaddr_in* host_addr = (struct sockaddr_in*)result->ai_addr;
        memcpy(&d->server.sin_addr, &host_addr->sin_addr, sizeof(struct in_addr));
        freeaddrinfo(result);
    }

    d->init = true;
    return 0;
}

/* will change the original string */
void StatsdClient::cleanup(string& key)
{
    size_t pos = key.find_first_of(":|@");
    while ( pos != string::npos )
    {
        key[pos] = '_';
        pos = key.find_first_of(":|@");
    }
}

int StatsdClient::dec(const string& key, float sample_rate)
{
    return count(key, -1, sample_rate);
}

int StatsdClient::inc(const string& key, float sample_rate)
{
    return count(key, 1, sample_rate);
}

int StatsdClient::count(const string& key, size_t value, float sample_rate)
{
    return send(key, value, "c", sample_rate);
}

int StatsdClient::gauge(const string& key, size_t value, float sample_rate)
{
    return send(key, value, "g", sample_rate);
}

int StatsdClient::timing(const string& key, size_t ms, float sample_rate)
{
    return send(key, ms, "ms", sample_rate);
}

int StatsdClient::send(string key, size_t value, const string &type, float sample_rate)
{
    if (!should_send(sample_rate)) {
        return 0;
    }

    cleanup(key);

    char buf[256];
    if ( fequal( sample_rate, 1.0 ) )
    {
        snprintf(buf, sizeof(buf), "%s%s:%zd|%s",
                d->ns.c_str(), key.c_str(), value, type.c_str());
    }
    else
    {
        snprintf(buf, sizeof(buf), "%s%s:%zd|%s|@%.2f",
                d->ns.c_str(), key.c_str(), value, type.c_str(), sample_rate);
    }

    return send(buf);
}

int StatsdClient::send(const string &message)
{
    int ret = init();
    if ( ret )
    {
        return ret;
    }
    ret = sendto(d->sock, message.data(), message.size(), 0, (struct sockaddr *) &d->server, sizeof(d->server));
    if ( ret == -1) {
        snprintf(d->errmsg, sizeof(d->errmsg),
                "sendto server fail, host=%s:%d, err=%m", d->host.c_str(), d->port);
        return -1;
    }
    return 0;
}

const char* StatsdClient::errmsg()
{
    return d->errmsg;
}

}

<commit_msg>init procedure: fix a bug<commit_after>
#include <math.h>
#include <netdb.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include "statsd_client.h"
#include <fcntl.h>

using namespace std;
namespace statsd {

inline bool fequal(float a, float b)
{
    const float epsilon = 0.0001;
    return ( fabs(a - b) < epsilon );
}

inline bool should_send(float sample_rate)
{
    if ( fequal(sample_rate, 1.0) )
    {
        return true;
    }

    float p = ((float)random() / RAND_MAX);
    return sample_rate > p;
}

struct _StatsdClientData {
    int     sock;
    struct  sockaddr_in server;

    string  ns;
    string  host;
    short   port;
    bool    init;

    char    errmsg[1024];
};

StatsdClient::StatsdClient(const string& host, int port, const string& ns)
{
    d = new _StatsdClientData;
    d->sock = -1;
    config(host, port, ns);
    srandom(time(NULL));
}

StatsdClient::~StatsdClient()
{
    // close socket
    if (d->sock >= 0) {
        close(d->sock);
        d->sock = -1;
        delete d;
        d = NULL;
    }
}

void StatsdClient::config(const string& host, int port, const string& ns)
{
    d->ns = ns;
    d->host = host;
    d->port = port;
    d->init = false;
    if ( d->sock >= 0 ) {
        close(d->sock);
    }
    d->sock = -1;
}

int StatsdClient::init()
{
    if ( d->init ) return 0;

    d->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if ( d->sock == -1 ) {
        snprintf(d->errmsg, sizeof(d->errmsg), "could not create socket, err=%m");
        return -1;
    }

    memset(&d->server, 0, sizeof(d->server));
    d->server.sin_family = AF_INET;
    d->server.sin_port = htons(d->port);

    int ret = inet_aton(d->host.c_str(), &d->server.sin_addr);
    if ( ret == 0 )
    {
        // host must be a domain, get it from internet
        struct addrinfo hints, *result = NULL;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_DGRAM;

        ret = getaddrinfo(d->host.c_str(), NULL, &hints, &result);
        if ( ret ) {
            close(d->sock);
            d->sock = -1;
            snprintf(d->errmsg, sizeof(d->errmsg),
                    "getaddrinfo fail, error=%d, msg=%s", ret, gai_strerror(ret) );
            return -2;
        }
        struct sockaddr_in* host_addr = (struct sockaddr_in*)result->ai_addr;
        memcpy(&d->server.sin_addr, &host_addr->sin_addr, sizeof(struct in_addr));
        freeaddrinfo(result);
    }

    d->init = true;
    return 0;
}

/* will change the original string */
void StatsdClient::cleanup(string& key)
{
    size_t pos = key.find_first_of(":|@");
    while ( pos != string::npos )
    {
        key[pos] = '_';
        pos = key.find_first_of(":|@");
    }
}

int StatsdClient::dec(const string& key, float sample_rate)
{
    return count(key, -1, sample_rate);
}

int StatsdClient::inc(const string& key, float sample_rate)
{
    return count(key, 1, sample_rate);
}

int StatsdClient::count(const string& key, size_t value, float sample_rate)
{
    return send(key, value, "c", sample_rate);
}

int StatsdClient::gauge(const string& key, size_t value, float sample_rate)
{
    return send(key, value, "g", sample_rate);
}

int StatsdClient::timing(const string& key, size_t ms, float sample_rate)
{
    return send(key, ms, "ms", sample_rate);
}

int StatsdClient::send(string key, size_t value, const string &type, float sample_rate)
{
    if (!should_send(sample_rate)) {
        return 0;
    }

    cleanup(key);

    char buf[256];
    if ( fequal( sample_rate, 1.0 ) )
    {
        snprintf(buf, sizeof(buf), "%s%s:%zd|%s",
                d->ns.c_str(), key.c_str(), value, type.c_str());
    }
    else
    {
        snprintf(buf, sizeof(buf), "%s%s:%zd|%s|@%.2f",
                d->ns.c_str(), key.c_str(), value, type.c_str(), sample_rate);
    }

    return send(buf);
}

int StatsdClient::send(const string &message)
{
    int ret = init();
    if ( ret )
    {
        return ret;
    }
    ret = sendto(d->sock, message.data(), message.size(), 0, (struct sockaddr *) &d->server, sizeof(d->server));
    if ( ret == -1) {
        snprintf(d->errmsg, sizeof(d->errmsg),
                "sendto server fail, host=%s:%d, err=%m", d->host.c_str(), d->port);
        return -1;
    }
    return 0;
}

const char* StatsdClient::errmsg()
{
    return d->errmsg;
}

}

<|endoftext|>


<commit_before>/**
 * This file is part of the "libstx" project
 *   Copyright (c) 2015 Laura Schlimmer, Paul Asmuth
 *
 * libstx is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "stx/human.h"
#include "stx/ISO8601.h"
#include "stx/test/unittest.h"

using namespace stx;

UNIT_TEST(HumanTest);

TEST_CASE(HumanTest, TestParseHumanTime, [] () {
  auto t_sec = Human::parseTime("1421442618");
  EXPECT_EQ(t_sec.get().unixMicros(), 1421442618 * kMicrosPerSecond);

  auto t_milli = Human::parseTime("1421442618000");
  EXPECT_EQ(t_milli.get().unixMicros(), 1421442618 * kMicrosPerSecond);

  auto t_micro = Human::parseTime("1421442618000000");
  EXPECT_EQ(t_micro.get().unixMicros(), 1421442618 * kMicrosPerSecond);

  /*auto t_now = Human::parseTime("now");
  EXPECT_EQ(t_now.unixMicros(), UnixTime().unixMicros());*/

  auto t1 = Human::parseTime("-2hour", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t1.get().unixMicros(), 1421525160 * kMicrosPerSecond);

  auto t2 = Human::parseTime("-2h", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t2.get().unixMicros(), 1421525160 * kMicrosPerSecond);

  auto t3 = Human::parseTime("-2m", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t3.get().unixMicros(), 1421532240 * kMicrosPerSecond);

  auto t4 = Human::parseTime("-2minute", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t4.get().unixMicros(), 1421532240 * kMicrosPerSecond);

  auto t6 = Human::parseTime("-1day", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t6.get().unixMicros(), 1421445960 * kMicrosPerSecond);

  auto t7 = Human::parseTime("-1d", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t7.get().unixMicros(), 1421445960 * kMicrosPerSecond);

  auto t8 = Human::parseTime("-5s", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t8.get().unixMicros(), 1421532355 * kMicrosPerSecond);

  auto t9 = Human::parseTime("-5second", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t9.get().unixMicros(), 1421532355 * kMicrosPerSecond);

  auto t10 = Human::parseTime("-1w", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t10.get().unixMicros(), 1420927560 * kMicrosPerSecond);

  auto t11 = Human::parseTime("2014-01-15");
  EXPECT_EQ(t11.get().unixMicros(), 1389744000 * kMicrosPerSecond);

  auto t12 = Human::parseTime("2014-11-02");
  EXPECT_EQ(t12.get().unixMicros(), 1414886400 * kMicrosPerSecond);

  auto t13 = Human::parseTime("2014-11-02T18:23:10-01:00");
  EXPECT_EQ(t13.get().unixMicros(), 1414956190 * kMicrosPerSecond);

  auto t14 = Human::parseTime("2014-11-02T18:23:10.5-01:00");
  EXPECT_EQ(t14.get().unixMicros(), 1414956190 * kMicrosPerSecond + 500000);

  auto t15 = Human::parseTime("2014-11-02T18:23:10+00:00");
  EXPECT_EQ(t15.get().unixMicros(), 1414952590 * kMicrosPerSecond);

  auto t16 = Human::parseTime("2006-09-15 20:50:06");
  EXPECT_FALSE(t16.isEmpty());
  EXPECT_EQ(t16.get().unixMicros(), 1158346206 * kMicrosPerSecond);
});

TEST_CASE(HumanTest, RejectInvalidISO8601TimeValues, [] () {
  {
    auto t = ISO8601::parse("0,44");
    EXPECT_TRUE(t.isEmpty());
  }

  {
    auto t = ISO8601::parse("59,89%");
    EXPECT_TRUE(t.isEmpty());
  }
});

<commit_msg>compare with utc time if simple date time string without time zone<commit_after>/**
 * This file is part of the "libstx" project
 *   Copyright (c) 2015 Laura Schlimmer, Paul Asmuth
 *
 * libstx is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "stx/human.h"
#include "stx/ISO8601.h"
#include "stx/test/unittest.h"

using namespace stx;

UNIT_TEST(HumanTest);

TEST_CASE(HumanTest, TestParseHumanTime, [] () {
  auto t_sec = Human::parseTime("1421442618");
  EXPECT_EQ(t_sec.get().unixMicros(), 1421442618 * kMicrosPerSecond);

  auto t_milli = Human::parseTime("1421442618000");
  EXPECT_EQ(t_milli.get().unixMicros(), 1421442618 * kMicrosPerSecond);

  auto t_micro = Human::parseTime("1421442618000000");
  EXPECT_EQ(t_micro.get().unixMicros(), 1421442618 * kMicrosPerSecond);

  /*auto t_now = Human::parseTime("now");
  EXPECT_EQ(t_now.unixMicros(), UnixTime().unixMicros());*/

  auto t1 = Human::parseTime("-2hour", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t1.get().unixMicros(), 1421525160 * kMicrosPerSecond);

  auto t2 = Human::parseTime("-2h", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t2.get().unixMicros(), 1421525160 * kMicrosPerSecond);

  auto t3 = Human::parseTime("-2m", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t3.get().unixMicros(), 1421532240 * kMicrosPerSecond);

  auto t4 = Human::parseTime("-2minute", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t4.get().unixMicros(), 1421532240 * kMicrosPerSecond);

  auto t6 = Human::parseTime("-1day", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t6.get().unixMicros(), 1421445960 * kMicrosPerSecond);

  auto t7 = Human::parseTime("-1d", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t7.get().unixMicros(), 1421445960 * kMicrosPerSecond);

  auto t8 = Human::parseTime("-5s", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t8.get().unixMicros(), 1421532355 * kMicrosPerSecond);

  auto t9 = Human::parseTime("-5second", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t9.get().unixMicros(), 1421532355 * kMicrosPerSecond);

  auto t10 = Human::parseTime("-1w", UnixTime(1421532360 * kMicrosPerSecond));
  EXPECT_EQ(t10.get().unixMicros(), 1420927560 * kMicrosPerSecond);

  auto t11 = Human::parseTime("2014-01-15");
  EXPECT_EQ(t11.get().unixMicros(), 1389744000 * kMicrosPerSecond);

  auto t12 = Human::parseTime("2014-11-02");
  EXPECT_EQ(t12.get().unixMicros(), 1414886400 * kMicrosPerSecond);

  auto t13 = Human::parseTime("2014-11-02T18:23:10-01:00");
  EXPECT_EQ(t13.get().unixMicros(), 1414956190 * kMicrosPerSecond);

  auto t14 = Human::parseTime("2014-11-02T18:23:10.5-01:00");
  EXPECT_EQ(t14.get().unixMicros(), 1414956190 * kMicrosPerSecond + 500000);

  auto t15 = Human::parseTime("2014-11-02T18:23:10+00:00");
  EXPECT_EQ(t15.get().unixMicros(), 1414952590 * kMicrosPerSecond);

  auto t16 = Human::parseTime("2006-09-15 20:50:06");
  EXPECT_FALSE(t16.isEmpty());
  EXPECT_EQ(t16.get().unixMicros(), 1158353406 * kMicrosPerSecond);
});

TEST_CASE(HumanTest, RejectInvalidISO8601TimeValues, [] () {
  {
    auto t = ISO8601::parse("0,44");
    EXPECT_TRUE(t.isEmpty());
  }

  {
    auto t = ISO8601::parse("59,89%");
    EXPECT_TRUE(t.isEmpty());
  }
});

<|endoftext|>


<commit_before>/******************************************************************************
 * @file    flash_memory.cpp
 * @author  Rémi Pincent - INRIA
 * @date    17 sept. 2015
 *
 * @brief TODO_one_line_description_of_file
 *
 * Project : nrf51_template_application
 * Contact:  Rémi Pincent - remi.pincent@inria.fr
 *
 * Revision History:
 * TODO_revision history
 *****************************************************************************/

#include <flash_memory.h>
#include <delay.h>
#include <logger.h>
#include "application_config.h"
extern "C" {
#include "app_error.h"
#include "nrf_soc.h"
#include "app_scheduler.h"
}

FlashMemory FlashMem;

/** refer linker script */
/** end rom */
extern uint32_t __etext;

// divide the address by 1024
#define  PAGE_FROM_ADDRESS(address)  ((uint8_t)((uint32_t)address >> 10))

// multiple the page by 1024
#define  ADDRESS_OF_PAGE(page)  ((uint32_t*)(page << 10))

FlashMemory::FlashMemory(void) : _b_pendingOperation(false), _s8_writeStatus(NO_ERROR)
{
}

int8_t FlashMemory::readLong(int address, int32_t& value)
{
	value = 0;
	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}
	value = (*(uint32_t*)address);
	return sizeof(value);
}

int8_t FlashMemory::read(int address, int8_t& value)
{
	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}
	value = (*(uint32_t*)address) & 0xFF;
	return sizeof(value);
}

/**
 * @param address
 * @param value
 * @return
 */
int8_t FlashMemory::write(int address, uint8_t value)
{
	uint32_t err_code = NRF_SUCCESS;

	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}

	if(_b_pendingOperation)
	{
		return BUSY;
	}

	_b_pendingOperation = true;
	err_code = sd_flash_write((uint32_t*)address, (uint32_t*)&value, 1);
	APP_ERROR_CHECK(err_code);
	while(_b_pendingOperation)
	{
	    uint32_t err_code = sd_app_evt_wait();
	    APP_ERROR_CHECK(err_code);
	    if(USE_EVENT_SCHEDULER)
	    {
	    	/** Must be called - otherwise sysEvtDispatch() won't be called */
	    	app_sched_execute();
	    }
	}
	return (_s8_writeStatus == NO_ERROR) ? sizeof(value) : WRITE_ERROR;
}

int8_t FlashMemory::erasePage(int pageNumber)
{
	uint32_t err_code = NRF_SUCCESS;

	if(_b_pendingOperation)
	{
		return BUSY;
	}

	_b_pendingOperation = true;
	err_code = sd_flash_page_erase(pageNumber);
	APP_ERROR_CHECK(err_code);
	while(_b_pendingOperation)
	{
	    uint32_t err_code = sd_app_evt_wait();
	    APP_ERROR_CHECK(err_code);
	    if(USE_EVENT_SCHEDULER)
	    {
	    	/** Must be called - otherwise sysEvtDispatch() won't be called */
	    	app_sched_execute();
	    }
	    APP_ERROR_CHECK(err_code);
	}
	return (_s8_writeStatus == NO_ERROR) ? NO_ERROR : WRITE_ERROR;
}
int8_t FlashMemory::writeLong(int address, int32_t value)
{
	uint32_t err_code = NRF_SUCCESS;

	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}

	if(_b_pendingOperation)
	{
		return BUSY;
	}

	_b_pendingOperation = true;
	err_code = sd_flash_write((uint32_t*)address, (uint32_t*)&value, 1);
	APP_ERROR_CHECK(err_code);
	while(_b_pendingOperation)
	{
	    uint32_t err_code = sd_app_evt_wait();
	    APP_ERROR_CHECK(err_code);
	    if(USE_EVENT_SCHEDULER)
	    {
	    	/** Must be called - otherwise sysEvtDispatch() won't be called */
	    	app_sched_execute();
	    }
	}
	return (_s8_writeStatus == NO_ERROR) ? sizeof(value) : WRITE_ERROR;
}

/**
 * Flash handler
 */
void FlashMemory::flash_handler(uint32_t sys_evt)
{
    switch (sys_evt)
     {
         case NRF_EVT_FLASH_OPERATION_SUCCESS:
        	 FlashMem._s8_writeStatus = NO_ERROR;
		 FlashMem._b_pendingOperation = false;
        	 break;

         case NRF_EVT_FLASH_OPERATION_ERROR:
        	 FlashMem._s8_writeStatus = WRITE_ERROR;
		 FlashMem._b_pendingOperation = false;
             break;

         default:
             // No implementation needed.
             break;

     }
}

/**
 * Mapping between Soft device flash handler and FlashMemory handler
 * @param sys_evt
 */
void sd_flash_handler(uint32_t sys_evt)
{
	FlashMem.flash_handler(sys_evt);
}

<commit_msg>remove unused headers<commit_after>/******************************************************************************
 * @file    flash_memory.cpp
 * @author  Rémi Pincent - INRIA
 * @date    17 sept. 2015
 *
 * @brief TODO_one_line_description_of_file
 *
 * Project : nrf51_template_application
 * Contact:  Rémi Pincent - remi.pincent@inria.fr
 *
 * Revision History:
 * TODO_revision history
 *****************************************************************************/

#include <flash_memory.h>
#include "application_config.h"
extern "C" {
#include "app_error.h"
#include "nrf_soc.h"
#include "app_scheduler.h"
}

FlashMemory FlashMem;

/** refer linker script */
/** end rom */
extern uint32_t __etext;

// divide the address by 1024
#define  PAGE_FROM_ADDRESS(address)  ((uint8_t)((uint32_t)address >> 10))

// multiple the page by 1024
#define  ADDRESS_OF_PAGE(page)  ((uint32_t*)(page << 10))

FlashMemory::FlashMemory(void) : _b_pendingOperation(false), _s8_writeStatus(NO_ERROR)
{
}

int8_t FlashMemory::readLong(int address, int32_t& value)
{
	value = 0;
	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}
	value = (*(uint32_t*)address);
	return sizeof(value);
}

int8_t FlashMemory::read(int address, int8_t& value)
{
	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}
	value = (*(uint32_t*)address) & 0xFF;
	return sizeof(value);
}

/**
 * @param address
 * @param value
 * @return
 */
int8_t FlashMemory::write(int address, uint8_t value)
{
	uint32_t err_code = NRF_SUCCESS;

	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}

	if(_b_pendingOperation)
	{
		return BUSY;
	}

	_b_pendingOperation = true;
	err_code = sd_flash_write((uint32_t*)address, (uint32_t*)&value, 1);
	APP_ERROR_CHECK(err_code);
	while(_b_pendingOperation)
	{
	    uint32_t err_code = sd_app_evt_wait();
	    APP_ERROR_CHECK(err_code);
	    if(USE_EVENT_SCHEDULER)
	    {
	    	/** Must be called - otherwise sysEvtDispatch() won't be called */
	    	app_sched_execute();
	    }
	}
	return (_s8_writeStatus == NO_ERROR) ? sizeof(value) : WRITE_ERROR;
}

int8_t FlashMemory::erasePage(int pageNumber)
{
	uint32_t err_code = NRF_SUCCESS;

	if(_b_pendingOperation)
	{
		return BUSY;
	}

	_b_pendingOperation = true;
	err_code = sd_flash_page_erase(pageNumber);
	APP_ERROR_CHECK(err_code);
	while(_b_pendingOperation)
	{
	    uint32_t err_code = sd_app_evt_wait();
	    APP_ERROR_CHECK(err_code);
	    if(USE_EVENT_SCHEDULER)
	    {
	    	/** Must be called - otherwise sysEvtDispatch() won't be called */
	    	app_sched_execute();
	    }
	    APP_ERROR_CHECK(err_code);
	}
	return (_s8_writeStatus == NO_ERROR) ? NO_ERROR : WRITE_ERROR;
}
int8_t FlashMemory::writeLong(int address, int32_t value)
{
	uint32_t err_code = NRF_SUCCESS;

	if((uint32_t*) address <= &__etext)
	{
		/** writing in application code */
		return INVALID_ADDRESS;
	}

	if(_b_pendingOperation)
	{
		return BUSY;
	}

	_b_pendingOperation = true;
	err_code = sd_flash_write((uint32_t*)address, (uint32_t*)&value, 1);
	APP_ERROR_CHECK(err_code);
	while(_b_pendingOperation)
	{
	    uint32_t err_code = sd_app_evt_wait();
	    APP_ERROR_CHECK(err_code);
	    if(USE_EVENT_SCHEDULER)
	    {
	    	/** Must be called - otherwise sysEvtDispatch() won't be called */
	    	app_sched_execute();
	    }
	}
	return (_s8_writeStatus == NO_ERROR) ? sizeof(value) : WRITE_ERROR;
}

/**
 * Flash handler
 */
void FlashMemory::flash_handler(uint32_t sys_evt)
{
    switch (sys_evt)
     {
         case NRF_EVT_FLASH_OPERATION_SUCCESS:
        	 FlashMem._s8_writeStatus = NO_ERROR;
		 FlashMem._b_pendingOperation = false;
        	 break;

         case NRF_EVT_FLASH_OPERATION_ERROR:
        	 FlashMem._s8_writeStatus = WRITE_ERROR;
		 FlashMem._b_pendingOperation = false;
             break;

         default:
             // No implementation needed.
             break;

     }
}

/**
 * Mapping between Soft device flash handler and FlashMemory handler
 * @param sys_evt
 */
void sd_flash_handler(uint32_t sys_evt)
{
	FlashMem.flash_handler(sys_evt);
}

<|endoftext|>


<commit_before><commit_msg>fixed r,s s,r<commit_after><|endoftext|>


<commit_before>
#include <rj_common/time.hpp>
#include <rj_constants/constants.hpp>
#include <rj_constants/topic_names.hpp>
#include <rj_msgs/msg/detection_frame.hpp>
#include <rj_utils/logging_macros.hpp>
#include <rj_vision_filter/params.hpp>
#include <rj_vision_filter/vision_filter.hpp>
#include <robot.hpp>

namespace vision_filter {
DEFINE_FLOAT64(kVisionFilterParamModule, publish_hz, 120.0,
               "The rate in Hz at which VisionFilter publishes ball and robot "
               "observations.")

VisionFilter::VisionFilter(const rclcpp::NodeOptions& options)
    : rclcpp::Node{"vision_filter", options},
      config_client_{this},
      team_color_queue_{this, referee::topics::kTeamColorPub,
                        rj_msgs::build<TeamColorMsg>().is_blue(true)},
      param_provider_{this, kVisionFilterParamModule} {
    // Create a timer that calls predict on all of the Kalman filters.
    const std::chrono::duration<double> predict_timer_period(PARAM_vision_loop_dt);
    auto predict_callback = [this]() { predict_states(); };
    predict_timer_ = create_wall_timer(predict_timer_period, predict_callback);

    // Create a subscriber for the DetectionFrameMsg
    constexpr int kQueueSize = 10;
    const auto callback = [this](DetectionFrameMsg::UniquePtr msg) {
        detection_frame_queue_.push(std::move(msg));
    };
    detection_frame_sub_ = create_subscription<DetectionFrameMsg>(
        vision_receiver::topics::kDetectionFramePub, rclcpp::QoS(kQueueSize), callback);

    // Create publishers.
    world_state_pub_ = create_publisher<WorldStateMsg>(topics::kWorldStatePub, 10);
}

VisionFilter::WorldStateMsg VisionFilter::build_world_state_msg(bool us_blue) const {
    return rj_msgs::build<WorldStateMsg>()
        .last_update_time(rj_convert::convert_to_ros(world_.last_update_time()))
        .their_robots(build_robot_state_msgs(!us_blue))
        .our_robots(build_robot_state_msgs(us_blue))
        .ball(build_ball_state_msg());
}

VisionFilter::BallStateMsg VisionFilter::build_ball_state_msg() const {
    const WorldBall& wb = world_.get_world_ball();

    BallStateMsg msg{};
    msg.stamp = rj_convert::convert_to_ros(wb.get_time());
    msg.position = rj_convert::convert_to_ros(wb.get_pos());
    msg.velocity = rj_convert::convert_to_ros(wb.get_vel());
    msg.visible = rj_convert::convert_to_ros(wb.get_is_valid());
    return msg;
}

std::vector<VisionFilter::RobotStateMsg> VisionFilter::build_robot_state_msgs(
    bool blue_team) const {
    const auto& robots = blue_team ? world_.get_robots_blue() : world_.get_robots_yellow();

    // Fill our robots
    std::vector<RobotStateMsg> robot_state_msgs(kNumShells);
    for (size_t i = 0; i < kNumShells; i++) {
        const WorldRobot& wr = robots.at(i);

        RobotState robot_state;
        robot_state.visible = wr.get_is_valid();

        if (wr.get_is_valid()) {
            robot_state.pose = rj_geometry::Pose(wr.get_pos(), wr.get_theta());
            robot_state.velocity = rj_geometry::Twist(wr.get_vel(), wr.get_omega());
            robot_state.timestamp = wr.get_time();
        }

        robot_state_msgs.at(i) = rj_convert::convert_to_ros(robot_state);
    }
    return robot_state_msgs;
}

void VisionFilter::publish_state() {
    std::shared_ptr<TeamColorMsg> team_color = team_color_queue_.get();
    if (team_color == nullptr) {
        EZ_WARN_STREAM("Returning because team_color is nullptr");
        return;
    }

    WorldStateMsg::UniquePtr msg = std::make_unique<WorldStateMsg>();
    *msg = build_world_state_msg(team_color->is_blue);
    world_state_pub_->publish(std::move(msg));
}

void VisionFilter::get_frames() {
    std::vector<DetectionFrameMsg::UniquePtr> raw_frames = detection_frame_queue_.get_all();
    if (raw_frames.empty()) {
        return;
    }

    const double current_team_angle = team_angle();
    const rj_geometry::TransformMatrix current_world_to_team = world_to_team();
    for (const DetectionFrameMsg::UniquePtr& msg : raw_frames) {
        frame_buffer_.emplace_back(*msg, current_world_to_team, current_team_angle);
    }
}
void VisionFilter::predict_states() {
    const RJ::Time start = RJ::now();

    // Perform the updates on the Kalman Filters.
    predict_states_impl();

    // Check that predict_states runs fast enough, otherwise print a warning.
    const RJ::Seconds predict_time = RJ::now() - start;
    const RJ::Seconds diff_duration = RJ::Seconds(PARAM_vision_loop_dt) - predict_time;

    if (diff_duration < RJ::Seconds{0}) {
        constexpr int kWarningThrottleMS = 1000;
        EZ_WARN_STREAM_THROTTLE(kWarningThrottleMS,
                                "Predict is not called fast enough. Iteration took "
                                    << diff_duration.count() << " seconds, should be "
                                    << PARAM_vision_loop_dt << ".");
    }
}

void VisionFilter::predict_states_impl() {
    // Do update with whatever is in frame buffer
    get_frames();

    if (!frame_buffer_.empty()) {
        world_.update_with_camera_frame(RJ::now(), frame_buffer_);
        frame_buffer_.clear();
    } else {
        world_.update_without_camera_frame(RJ::now());
    }

    // Publish the updated world state at the end.
    publish_state();
}
}  // namespace vision_filter
<commit_msg>Predict time warning (#1615)<commit_after>
#include <rj_common/time.hpp>
#include <rj_constants/constants.hpp>
#include <rj_constants/topic_names.hpp>
#include <rj_msgs/msg/detection_frame.hpp>
#include <rj_utils/logging_macros.hpp>
#include <rj_vision_filter/params.hpp>
#include <rj_vision_filter/vision_filter.hpp>
#include <robot.hpp>

namespace vision_filter {
DEFINE_FLOAT64(kVisionFilterParamModule, publish_hz, 120.0,
               "The rate in Hz at which VisionFilter publishes ball and robot "
               "observations.")

VisionFilter::VisionFilter(const rclcpp::NodeOptions& options)
    : rclcpp::Node{"vision_filter", options},
      config_client_{this},
      team_color_queue_{this, referee::topics::kTeamColorPub,
                        rj_msgs::build<TeamColorMsg>().is_blue(true)},
      param_provider_{this, kVisionFilterParamModule} {
    // Create a timer that calls predict on all of the Kalman filters.
    const std::chrono::duration<double> predict_timer_period(PARAM_vision_loop_dt);
    auto predict_callback = [this]() { predict_states(); };
    predict_timer_ = create_wall_timer(predict_timer_period, predict_callback);

    // Create a subscriber for the DetectionFrameMsg
    constexpr int kQueueSize = 10;
    const auto callback = [this](DetectionFrameMsg::UniquePtr msg) {
        detection_frame_queue_.push(std::move(msg));
    };
    detection_frame_sub_ = create_subscription<DetectionFrameMsg>(
        vision_receiver::topics::kDetectionFramePub, rclcpp::QoS(kQueueSize), callback);

    // Create publishers.
    world_state_pub_ = create_publisher<WorldStateMsg>(topics::kWorldStatePub, 10);
}

VisionFilter::WorldStateMsg VisionFilter::build_world_state_msg(bool us_blue) const {
    return rj_msgs::build<WorldStateMsg>()
        .last_update_time(rj_convert::convert_to_ros(world_.last_update_time()))
        .their_robots(build_robot_state_msgs(!us_blue))
        .our_robots(build_robot_state_msgs(us_blue))
        .ball(build_ball_state_msg());
}

VisionFilter::BallStateMsg VisionFilter::build_ball_state_msg() const {
    const WorldBall& wb = world_.get_world_ball();

    BallStateMsg msg{};
    msg.stamp = rj_convert::convert_to_ros(wb.get_time());
    msg.position = rj_convert::convert_to_ros(wb.get_pos());
    msg.velocity = rj_convert::convert_to_ros(wb.get_vel());
    msg.visible = rj_convert::convert_to_ros(wb.get_is_valid());
    return msg;
}

std::vector<VisionFilter::RobotStateMsg> VisionFilter::build_robot_state_msgs(
    bool blue_team) const {
    const auto& robots = blue_team ? world_.get_robots_blue() : world_.get_robots_yellow();

    // Fill our robots
    std::vector<RobotStateMsg> robot_state_msgs(kNumShells);
    for (size_t i = 0; i < kNumShells; i++) {
        const WorldRobot& wr = robots.at(i);

        RobotState robot_state;
        robot_state.visible = wr.get_is_valid();

        if (wr.get_is_valid()) {
            robot_state.pose = rj_geometry::Pose(wr.get_pos(), wr.get_theta());
            robot_state.velocity = rj_geometry::Twist(wr.get_vel(), wr.get_omega());
            robot_state.timestamp = wr.get_time();
        }

        robot_state_msgs.at(i) = rj_convert::convert_to_ros(robot_state);
    }
    return robot_state_msgs;
}

void VisionFilter::publish_state() {
    std::shared_ptr<TeamColorMsg> team_color = team_color_queue_.get();
    if (team_color == nullptr) {
        EZ_WARN_STREAM("Returning because team_color is nullptr");
        return;
    }

    WorldStateMsg::UniquePtr msg = std::make_unique<WorldStateMsg>();
    *msg = build_world_state_msg(team_color->is_blue);
    world_state_pub_->publish(std::move(msg));
}

void VisionFilter::get_frames() {
    std::vector<DetectionFrameMsg::UniquePtr> raw_frames = detection_frame_queue_.get_all();
    if (raw_frames.empty()) {
        return;
    }

    const double current_team_angle = team_angle();
    const rj_geometry::TransformMatrix current_world_to_team = world_to_team();
    for (const DetectionFrameMsg::UniquePtr& msg : raw_frames) {
        frame_buffer_.emplace_back(*msg, current_world_to_team, current_team_angle);
    }
}
void VisionFilter::predict_states() {
    const RJ::Time start = RJ::now();

    // Perform the updates on the Kalman Filters.
    predict_states_impl();

    // Check that predict_states runs fast enough, otherwise print a warning.
    const RJ::Seconds predict_time = RJ::now() - start;
    const RJ::Seconds diff_duration = RJ::Seconds(PARAM_vision_loop_dt) - predict_time;

    if (diff_duration < RJ::Seconds{0}) {
        constexpr int kWarningThrottleMS = 1000;
        EZ_WARN_STREAM_THROTTLE(kWarningThrottleMS,
                                "Predict is not called fast enough. Iteration took "
                                    << predict_time.count() << " seconds, should be "
                                    << PARAM_vision_loop_dt << ".");
    }
}

void VisionFilter::predict_states_impl() {
    // Do update with whatever is in frame buffer
    get_frames();

    if (!frame_buffer_.empty()) {
        world_.update_with_camera_frame(RJ::now(), frame_buffer_);
        frame_buffer_.clear();
    } else {
        world_.update_without_camera_frame(RJ::now());
    }

    // Publish the updated world state at the end.
    publish_state();
}
}  // namespace vision_filter
<|endoftext|>


<commit_before><commit_msg>Set Move as default drop action<commit_after><|endoftext|>


<commit_before>/*
  E24C1024.cpp
  AT24C1024 Library for Arduino

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US

  This library is based on several projects:

  The Arduino EEPROM library found here:
  http://arduino.cc/en/Reference/EEPROM

  The 24C256 library found here:
  http://www.arduino.cc/playground/Code/I2CEEPROM

  The 24C512 library found here:
  http://www.arduino.cc/playground/Code/I2CEEPROM24LC512

  Our project page is here:
  http://www.arduino.cc/playground/Code/I2CEEPROM24C1024

  From the datasheet:

  The AT24C1024B provides 1,048,576 bits of serial electrically
  erasable and programmable read only memory (EEPROM) organized
  as 131,072 words of 8 bits each. The devices cascadable
  feature allows up to four devices to share a common two-wire
  bus.

  http://www.atmel.com/dyn/resources/prod_documents/doc5194.pdf

*/

#include <Wire.h>
#include "E24C1024.h"

E24C1024::E24C1024(void)
{
   Wire.begin();
}

void E24C1024::write(unsigned long dataAddress, uint8_t data)
{
   Wire.beginTransmission((uint8_t)((0x500000 | dataAddress) >> 16)); // B1010xxx
   Wire.send((uint8_t)((dataAddress & WORD_MASK) >> 8)); // MSB
   Wire.send((uint8_t)(dataAddress & 0xFF)); // LSB
   Wire.send(data);
   Wire.endTransmission();
   delay(5);
}

uint8_t E24C1024::read(unsigned long dataAddress)
{
   uint8_t data = 0x00;
   Wire.beginTransmission((uint8_t)((0x500000 | dataAddress) >> 16)); // B1010xxx
   Wire.send((uint8_t)((dataAddress & WORD_MASK) >> 8)); // MSB
   Wire.send((uint8_t)(dataAddress & 0xFF)); // LSB
   Wire.endTransmission();
   Wire.requestFrom(0x50,1);
   if (Wire.available()) data = Wire.receive();
   return data;
}

E24C1024 EEPROM1024;
<commit_msg>removed unnecessary include<commit_after>/*
  E24C1024.cpp
  AT24C1024 Library for Arduino

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  US

  This library is based on several projects:

  The Arduino EEPROM library found here:
  http://arduino.cc/en/Reference/EEPROM

  The 24C256 library found here:
  http://www.arduino.cc/playground/Code/I2CEEPROM

  The 24C512 library found here:
  http://www.arduino.cc/playground/Code/I2CEEPROM24LC512

  Our project page is here:
  http://www.arduino.cc/playground/Code/I2CEEPROM24C1024

  From the datasheet:

  The AT24C1024B provides 1,048,576 bits of serial electrically
  erasable and programmable read only memory (EEPROM) organized
  as 131,072 words of 8 bits each. The devices cascadable
  feature allows up to four devices to share a common two-wire
  bus.

  http://www.atmel.com/dyn/resources/prod_documents/doc5194.pdf

*/

#include "E24C1024.h"

E24C1024::E24C1024(void)
{
   Wire.begin();
}

void E24C1024::write(unsigned long dataAddress, uint8_t data)
{
   Wire.beginTransmission((uint8_t)((0x500000 | dataAddress) >> 16)); // B1010xxx
   Wire.send((uint8_t)((dataAddress & WORD_MASK) >> 8)); // MSB
   Wire.send((uint8_t)(dataAddress & 0xFF)); // LSB
   Wire.send(data);
   Wire.endTransmission();
   delay(5);
}

uint8_t E24C1024::read(unsigned long dataAddress)
{
   uint8_t data = 0x00;
   Wire.beginTransmission((uint8_t)((0x500000 | dataAddress) >> 16)); // B1010xxx
   Wire.send((uint8_t)((dataAddress & WORD_MASK) >> 8)); // MSB
   Wire.send((uint8_t)(dataAddress & 0xFF)); // LSB
   Wire.endTransmission();
   Wire.requestFrom(0x50,1);
   if (Wire.available()) data = Wire.receive();
   return data;
}

E24C1024 EEPROM1024;
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2020 Igor Zinken - https://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "processingchain.h"
#include "global.h"

namespace MWEngine {

// constructor

ProcessingChain::ProcessingChain()
{

}

ProcessingChain::~ProcessingChain()
{
    _activeProcessors.clear();
}

/* public methods */

void ProcessingChain::addProcessor( BaseProcessor* aProcessor )
{
    _activeProcessors.push_back( aProcessor );
    aProcessor->setChain( this );
}

void ProcessingChain::removeProcessor( BaseProcessor* aProcessor )
{
    for ( size_t i = 0; i < _activeProcessors.size(); i++ )
    {
        if ( _activeProcessors.at( i ) == aProcessor )
        {
            _activeProcessors.erase( _activeProcessors.begin() + i );
            aProcessor->setChain( nullptr );
            break;
        }
    }
}

BaseProcessor* ProcessingChain::getProcessorAt( int index )
{
    if ( index >= amountOfProcessors()) {
        return nullptr;
    }
    return _activeProcessors.at( index );
}

std::vector<BaseProcessor*> ProcessingChain::getActiveProcessors()
{
    return _activeProcessors;
}

bool ProcessingChain::hasProcessors()
{
    return !_activeProcessors.empty();
}

int ProcessingChain::amountOfProcessors()
{
    return _activeProcessors.size();
}

void ProcessingChain::reset()
{
    _activeProcessors.clear();
}

} // E.O namespace MWEngine
<commit_msg>When ProcessingChain is destroyed, all registered processors should be unregistered<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2020 Igor Zinken - https://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "processingchain.h"
#include "global.h"

namespace MWEngine {

// constructor

ProcessingChain::ProcessingChain()
{

}

ProcessingChain::~ProcessingChain()
{
    while ( _activeProcessors.size() > 0 ) {
        auto processor = _activeProcessors.at( 0 );
        if ( processor != nullptr ) {
            removeProcessor( processor );
        }
        _activeProcessors.erase( _activeProcessors.begin() );
    }
}

/* public methods */

void ProcessingChain::addProcessor( BaseProcessor* aProcessor )
{
    _activeProcessors.push_back( aProcessor );
    aProcessor->setChain( this );
}

void ProcessingChain::removeProcessor( BaseProcessor* aProcessor )
{
    for ( size_t i = 0; i < _activeProcessors.size(); i++ )
    {
        if ( _activeProcessors.at( i ) == aProcessor )
        {
            _activeProcessors.erase( _activeProcessors.begin() + i );
            aProcessor->setChain( nullptr );
            break;
        }
    }
}

BaseProcessor* ProcessingChain::getProcessorAt( int index )
{
    if ( index >= amountOfProcessors()) {
        return nullptr;
    }
    return _activeProcessors.at( index );
}

std::vector<BaseProcessor*> ProcessingChain::getActiveProcessors()
{
    return _activeProcessors;
}

bool ProcessingChain::hasProcessors()
{
    return !_activeProcessors.empty();
}

int ProcessingChain::amountOfProcessors()
{
    return _activeProcessors.size();
}

void ProcessingChain::reset()
{
    _activeProcessors.clear();
}

} // E.O namespace MWEngine
<|endoftext|>


<commit_before>//
// Copyright 2015 Google Inc.
//
// 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.
//
#include "Firebase.h"

const char* firebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t firebasePort = 443;

Firebase::Firebase(const String& host) : _host(host) {
  _http.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
  _auth = auth;
  return *this;
}

Firebase& Firebase::child(const String& key) {
  _path += key;
  return *this;
}

String Firebase::val() {
  return sendRequest("GET", _path);
}

String Firebase::push(const String& value) {
  return sendRequest("POST", _path, (uint8_t*)value.c_str(), value.length());
}

String Firebase::sendRequest(const char* method, const String& path, uint8_t* value, size_t size) {
  _error.reset();
  Serial.print("host:");
  Serial.println(_host);
  String url = "/" + path + ".json";
  if (_auth.length() > 0) {
    url += "?auth=" + _auth;
  }
  _http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
  int statusCode = _http.sendRequest(method, value, size);
  if (statusCode < 0) {
    _error.set(statusCode,
	       String(method) + " " + url + ": "
	       + HTTPClient::errorToString(statusCode));
    return "";
  }
  // no _http.end() because of connection reuse.
  return _http.getString();
}
<commit_msg>remove logging<commit_after>//
// Copyright 2015 Google Inc.
//
// 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.
//
#include "Firebase.h"

const char* firebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t firebasePort = 443;

Firebase::Firebase(const String& host) : _host(host) {
  _http.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
  _auth = auth;
  return *this;
}

Firebase& Firebase::child(const String& key) {
  _path += key;
  return *this;
}

String Firebase::val() {
  return sendRequest("GET", _path);
}

String Firebase::push(const String& value) {
  return sendRequest("POST", _path, (uint8_t*)value.c_str(), value.length());
}

String Firebase::sendRequest(const char* method, const String& path, uint8_t* value, size_t size) {
  _error.reset();
  String url = "/" + path + ".json";
  if (_auth.length() > 0) {
    url += "?auth=" + _auth;
  }
  _http.begin(_host.c_str(), firebasePort, url.c_str(), true, firebaseFingerprint);
  int statusCode = _http.sendRequest(method, value, size);
  if (statusCode < 0) {
    _error.set(statusCode,
	       String(method) + " " + url + ": "
	       + HTTPClient::errorToString(statusCode));
    return "";
  }
  // no _http.end() because of connection reuse.
  return _http.getString();
}
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "RPNCalc.h"
#include "RPNTestHelper.h"

using namespace P4_RPNCALC;

TEST_CASE("Operation Methods")
{
	RPNTestHelper test;

	SECTION("Method: clearAll()")
	{
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("C", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("C", ""));
	}

	SECTION("Method: clearEntry()")
	{
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("ce", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("ce", ""));
		REQUIRE(test.expectedInputOutput("50 100 + 200", "200"));
		REQUIRE(test.expectedInputOutput("ce", "150"));
		REQUIRE(test.expectedInputOutput("ce", ""));
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("CE", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("CE", ""));
		REQUIRE(test.expectedInputOutput("50 100 + 200", "200"));
		REQUIRE(test.expectedInputOutput("CE", "150"));
		REQUIRE(test.expectedInputOutput("CE", ""));
	}

	SECTION("Method: add()")
	{
		REQUIRE(test.expectedInputOutput("3 5 +", "8"));
		REQUIRE(test.expectedInputOutput("2 4 3 +", "7"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("3 4 + 6", "6"));
		REQUIRE(test.expectedInputOutput("4 +", "10"));
		REQUIRE(test.expectedInputOutput("-12 +", "-2"));
		REQUIRE(test.expectedInputOutput("5 +", "3"));
		REQUIRE(test.expectedInputOutput("3 +", "6"));
		REQUIRE(test.expectedInputOutput("+", "<<error>>"));
	}

	SECTION("Method: combinations of add() & subtract()")
	{
		REQUIRE(test.expectedInputOutput("40 50 + 60 -", "30"));
		REQUIRE(test.expectedInputOutput("40 50 - 60 +", "50"));
		REQUIRE(test.expectedInputOutput("40 50 60 + -", "-70"));
		REQUIRE(test.expectedInputOutput("40 50 60 - +", "30"));
		REQUIRE(test.expectedInputOutput("-40 -50 + 60 -", "-150"));
		REQUIRE(test.expectedInputOutput("-40 -50 + -60 -", "-30"));
		REQUIRE(test.expectedInputOutput("-40 -50 - 60 +", "70"));
		REQUIRE(test.expectedInputOutput("-40 -50 - -60 +", "-50"));
	}

	SECTION("Method: subtract()")
	{
		REQUIRE(test.expectedInputOutput("5 6 -", "-1"));
		REQUIRE(test.expectedInputOutput("3 9 4 -", "5"));
		REQUIRE(test.expectedInputOutput("-", "-2"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("-1 5 -", "-6"));
		REQUIRE(test.expectedInputOutput("-", "<<error>>"));
	}

	SECTION("Method: multiply()")
	{
		REQUIRE(test.expectedInputOutput("3 9 7 2 4 *", "8"));
		REQUIRE(test.expectedInputOutput("*", "56"));
		REQUIRE(test.expectedInputOutput("*", "504"));
		REQUIRE(test.expectedInputOutput("*", "1512"));
		REQUIRE(test.expectedInputOutput("*", "<<error>>"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("-4 -6 *", "24"));
		REQUIRE(test.expectedInputOutput("-2 *", "-48"));
	}

	SECTION("Method: divide()")
	{
		REQUIRE(test.expectedInputOutput("16 4 2 /", "2"));
		REQUIRE(test.expectedInputOutput("/", "8"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("2 5 /", "0.4"));
		REQUIRE(test.expectedInputOutput("9 3 7 /", "0.428571"));
		REQUIRE(test.expectedInputOutput("-1 /", "-0.428571"));
		REQUIRE(test.expectedInputOutput("-1 / ", "0.428571"));
		REQUIRE(test.expectedInputOutput("/", "<<error>>"));
	}

	SECTION("Method: mod()")
	{
		REQUIRE(test.expectedInputOutput("16 8 6 %", "2"));
		REQUIRE(test.expectedInputOutput("%", "0"));
		REQUIRE(test.expectedInputOutput("c", ""));

		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));

	}

	SECTION("Method: exp()")
	{
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
	}

	SECTION("Method: neg()")
	{
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
	}
}
<commit_msg>Create RPN_UnitTests.cpp<commit_after>#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "RPNCalc.h"
#include "RPNTestHelper.h"

using namespace P4_RPNCALC;

TEST_CASE("Operation Methods")
{
	RPNTestHelper test;

	SECTION("Method: clearAll()")
	{
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("C", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("C", ""));
	}

	SECTION("Method: clearEntry()")
	{
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("ce", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("ce", ""));
		REQUIRE(test.expectedInputOutput("50 100 + 200", "200"));
		REQUIRE(test.expectedInputOutput("ce", "150"));
		REQUIRE(test.expectedInputOutput("ce", ""));
		REQUIRE(test.expectedInputOutput("50", "50"));
		REQUIRE(test.expectedInputOutput("CE", ""));
		REQUIRE(test.expectedInputOutput("50 100 +", "150"));
		REQUIRE(test.expectedInputOutput("CE", ""));
		REQUIRE(test.expectedInputOutput("50 100 + 200", "200"));
		REQUIRE(test.expectedInputOutput("CE", "150"));
		REQUIRE(test.expectedInputOutput("CE", ""));
	}

	SECTION("Method: add()")
	{
		REQUIRE(test.expectedInputOutput("3 5 +", "8"));
		REQUIRE(test.expectedInputOutput("2 4 3 +", "7"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("3 4 + 6", "6"));
		REQUIRE(test.expectedInputOutput("4 +", "10"));
		REQUIRE(test.expectedInputOutput("-12 +", "-2"));
		REQUIRE(test.expectedInputOutput("5 +", "3"));
		REQUIRE(test.expectedInputOutput("3 +", "6"));
		REQUIRE(test.expectedInputOutput("10 100 +", "110"));
		REQUIRE(test.expectedInputOutput("10 100+", "110"));
		REQUIRE(test.expectedInputOutput("+", "<<error>>"));
	}

	SECTION("Method: combinations of add() & subtract()")
	{
		REQUIRE(test.expectedInputOutput("40 50 + 60 -", "30"));
		REQUIRE(test.expectedInputOutput("40 50 - 60 +", "50"));
		REQUIRE(test.expectedInputOutput("40 50 60 + -", "-70"));
		REQUIRE(test.expectedInputOutput("40 50 60 - +", "30"));
		REQUIRE(test.expectedInputOutput("-40 -50 + 60 -", "-150"));
		REQUIRE(test.expectedInputOutput("-40 -50 + -60 -", "-30"));
		REQUIRE(test.expectedInputOutput("-40 -50 - 60 +", "70"));
		REQUIRE(test.expectedInputOutput("-40 -50 - -60 +", "-50"));
	}

	SECTION("Method: subtract()")
	{
		REQUIRE(test.expectedInputOutput("5 6 -", "-1"));
		REQUIRE(test.expectedInputOutput("3 9 4 -", "5"));
		REQUIRE(test.expectedInputOutput("-", "-2"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("-1 5 -", "-6"));
		REQUIRE(test.expectedInputOutput("10 100 -", "-90"));
		REQUIRE(test.expectedInputOutput("10 100-", "-90"));
		REQUIRE(test.expectedInputOutput("-", "<<error>>"));
	}

	SECTION("Method: multiply()")
	{
		REQUIRE(test.expectedInputOutput("3 9 7 2 4 *", "8"));
		REQUIRE(test.expectedInputOutput("*", "56"));
		REQUIRE(test.expectedInputOutput("*", "504"));
		REQUIRE(test.expectedInputOutput("*", "1512"));
		REQUIRE(test.expectedInputOutput("*", "<<error>>"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("-4 -6 *", "24"));
		REQUIRE(test.expectedInputOutput("-2 *", "-48"));
		REQUIRE(test.expectedInputOutput("10 100 *", "1000"));
		REQUIRE(test.expectedInputOutput("10 100*", "1000"));
	}

	SECTION("Method: divide()")
	{
		REQUIRE(test.expectedInputOutput("16 4 2 /", "2"));
		REQUIRE(test.expectedInputOutput("/", "8"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("2 5 /", "0.4"));
		REQUIRE(test.expectedInputOutput("9 3 7 /", "0.428571"));
		REQUIRE(test.expectedInputOutput("-1 /", "-0.428571"));
		REQUIRE(test.expectedInputOutput("-1 / ", "0.428571"));
		REQUIRE(test.expectedInputOutput("100 10 /", "10"));
		REQUIRE(test.expectedInputOutput("100 10/", "10"));
		REQUIRE(test.expectedInputOutput("/", "<<error>>"));
	}

	SECTION("Method: mod()")
	{
		REQUIRE(test.expectedInputOutput("16 8 6 %", "2"));
		REQUIRE(test.expectedInputOutput("%", "0"));
		REQUIRE(test.expectedInputOutput("c", ""));
		REQUIRE(test.expectedInputOutput("%", "<<error>>"));
		REQUIRE(test.expectedInputOutput("10 1 %", "0"));
		REQUIRE(test.expectedInputOutput("10 2 %", "0"));
		REQUIRE(test.expectedInputOutput("10 3 %", "1"));
		REQUIRE(test.expectedInputOutput("10 4 %", "2"));
		REQUIRE(test.expectedInputOutput("10 5 %", "0"));
		REQUIRE(test.expectedInputOutput("10 6 %", "4"));
		REQUIRE(test.expectedInputOutput("10 7 %", "3"));
		REQUIRE(test.expectedInputOutput("10 8 %", "2"));
		REQUIRE(test.expectedInputOutput("10 9 %", "1"));
		REQUIRE(test.expectedInputOutput("10 10 %", "0"));
		REQUIRE(test.expectedInputOutput("100 70 %", "30"));
		REQUIRE(test.expectedInputOutput("100 70%", "30"));
	}

	SECTION("Method: exp()")
	{
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
	}

	SECTION("Method: neg()")
	{
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
		REQUIRE(test.expectedInputOutput("", ""));
	}
}
<|endoftext|>


<commit_before>#include <functional>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <chrono>
#include <thread>

#include "Common.hpp"
#include "Engine.hpp"
#include "BaseTypes.hpp"
#include "dataspace/Dataspace.hpp"
#include "BaseCollections.hpp"
#include "Builtins.hpp"

namespace K3 {
  using std::endl;
  using std::to_string;

  // Standard context implementations
  __standard_context::__standard_context(Engine& __engine)
    : __k3_context(__engine)
  {}

  unit_t __tcmalloc_context::heapProfilerStart(const string_impl& s) {
    #ifdef MEMPROFILE
    HeapProfilerStart(s.c_str());
    #else
    std::cout << "heapProfilerStart: MEMPROFILE is not defined. not starting." << std::endl;
    #endif
    return unit_t {};
  }

  unit_t __tcmalloc_context::heapProfilerStop(unit_t) {
    #ifdef MEMPROFILE
    HeapProfilerDump("End of Program");
    HeapProfilerStop();
    #endif
    return unit_t {};
  }

  unit_t __standard_context::openBuiltin(string_impl ch_id, string_impl builtin_ch_id, string_impl fmt) {
    __engine.openBuiltin(ch_id, builtin_ch_id, fmt);
    return unit_t();
  }

  unit_t __standard_context::openFile(string_impl ch_id, string_impl path, string_impl fmt, string_impl mode) {
    IOMode iomode = __engine.ioMode(mode);
    __engine.openFile(ch_id, path, fmt, iomode);
    return unit_t();
  }

  unit_t __standard_context::openSocket(string_impl ch_id, Address a, string_impl fmt, string_impl mode) {
    IOMode iomode = __engine.ioMode(mode);
    __engine.openSocket(ch_id, a, fmt, iomode);
    return unit_t();
  }

  bool __standard_context::hasRead(string_impl ch_id) {
    return  __engine.hasRead(std::string(ch_id));
  }

  template<typename T>
  T __standard_context::doRead(string_impl ch_id) {
    shared_ptr<T> v = __engine.doReadExternal<T>(std::string(ch_id));
    if ( v ) { return *v; }
    T r;
    return r;
  }

  template<typename T>
  Collection<R_elem<T>> __standard_context::doReadBlock(string_impl ch_id, int block_size) {
    return  __engine.doReadExternalBlock<T>(std::string(ch_id), block_size);
  }

  bool __standard_context::hasWrite(string_impl ch_id) {
   return  __engine.hasWrite(std::string(ch_id));
  }

  template<typename T>
  unit_t  __standard_context::doWrite(string_impl ch_id, T& val) {
   __engine.doWriteExternal<T>(std::string(ch_id), val);
   return unit_t{};
  }

  unit_t __standard_context::close(string_impl chan_id) {
      __engine.close(chan_id);
      return unit_t();
  }

  int __standard_context::random(int n) {
    throw std::runtime_error("Not implemented: random");
  }

  double __standard_context::randomFraction(unit_t) {
    throw std::runtime_error("Not implemented: random");
  }

  unit_t __standard_context::print(string_impl message) {
    std::cout << message << endl;
    return unit_t();
  }

  unit_t __standard_context::haltEngine(unit_t) {
    __engine.forceTerminateEngine();
    return unit_t();
  }

  unit_t __standard_context::drainEngine(unit_t) {
    throw std::runtime_error("Not implemented: drainEngine");
  }

  unit_t __standard_context::sleep(int n) {
    std::this_thread::sleep_for(std::chrono::milliseconds(n));
  }

  __pcm_context::__pcm_context() {}

  __pcm_context::~__pcm_context() {}

  unit_t __pcm_context::cacheProfilerStart(unit_t) {
    #ifdef CACHEPROFILE
    instance = PCM::getInstance();
    if (instance->program() != PCM::Success) {
      std::cout << "PCM startup error!" << std::endl;
    }
    initial_state = std::make_shared<SystemCounterState>(getSystemCounterState());
    #else
    std::cout << "cacheProfileStart: CACHEPROFILE not set. not starting." << std::endl;
    #endif
  }

  unit_t __pcm_context::cacheProfilerStop(unit_t) {
    #ifdef CACHEPROFILE
    SystemCounterState after_sstate = getSystemCounterState();
    std::cout << "QPI Incoming: " << getAllIncomingQPILinkBytes(*initial_state, after_sstate) << std::endl;
    std::cout << "QPI Outgoing: " << getAllOutgoingQPILinkBytes(*initial_state, after_sstate) << std::endl;
    std::cout << "L2 cache hit ratio:" << getL2CacheHitRatio(*initial_state,after_sstate) << std::endl;
    std::cout << "L3 cache hit ratio:" << getL3CacheHitRatio(*initial_state,after_sstate) << std::endl;
    std::cout << "Instructions per clock:" << getIPC(*initial_state,after_sstate) << std::endl;
    instance->cleanup();
    #endif
  }

  // TODO fix copies related to base_str / std::sring conversion
  F<Collection<R_elem<string_impl>>(const string_impl &)> __string_context::regex_matcher(const string_impl& regex) {
    auto pattern = make_shared<RE2>(regex);
    return [pattern] (const string_impl& in_str) {
      std::string str = in_str;
      re2::StringPiece input(str);
      Collection<R_elem<string_impl>> results;
      std::string s;
      while(RE2::FindAndConsume(&input, *pattern, &s)) {
        results.insert(string_impl(s));
      }
      return results;
    };

  }

  Collection<R_elem<string_impl>> __string_context::regex_matcher_q4(const string_impl& in_str) {
    if (!pattern) {
      pattern = make_shared<RE2>("(?P<url>https?://[^\\s]+)");
    }
    std::string str = in_str;
    re2::StringPiece input(str);
    Collection<R_elem<string_impl>> results;
    std::string s;
    while(RE2::FindAndConsume(&input, *pattern, &s)) {
      results.insert(string_impl(s));
    }
    return results;

  }

  Vector<R_elem<double>> __standard_context::zeroVector(int i) {
    Vector<R_elem<double>> result;
    auto& c = result.getContainer();
    c.resize(i);
    for(int j = 0; j < i; j++) {
     c[j] = R_elem<double>{0.0};
    }
    return result;

  }

  // TODO -> Done
  // Elements must have random values in [0,1)
  Vector<R_elem<double>> __standard_context::randomVector(int i) {
    Vector<R_elem<double>> result;
    auto& c = result.getContainer();
    c.resize(i);
    for(int j = 0; j < i; j++) {
       srand(time(NULL));
       c[j] = R_elem<double>{(rand()/(RAND_MAX+ 1.))};
    }
    return result;
  }

  // Time:
  __time_context::__time_context() {}

  int __time_context::now_int(unit_t) {
    auto t = std::chrono::system_clock::now();
    auto elapsed =std::chrono::duration_cast<std::chrono::milliseconds>(t.time_since_epoch());
    return elapsed.count();
  }

  // String operations:
  __string_context::__string_context() {}
  string_impl __string_context::itos(int i) {
    return string_impl(to_string(i));
  }

  string_impl __string_context::rtos(double d) {
    return string_impl(to_string(d));
  }

  string_impl __string_context::atos(Address a) {
    return string_impl(addressAsString(a));
  }

  // Split a string by substrings
  Seq<R_elem<string_impl>> __string_context::splitString(string_impl s, const string_impl& splitter) {
    return s.splitString(splitter);
  }

  // Splitter is a single char for now
  string_impl __string_context::takeUntil(const string_impl& s, const string_impl& splitter) {
      char * pch;
      char delim = splitter.c_str()[0];
      const char* buf = s.c_str();
      if (!buf) {
        return string_impl();
      }
      int n = 0;
      while ((*buf != 0) && (*buf != delim)) {
        buf++;
        n++;
      }
      return string_impl(buf, n);

  }

  // Splitter is a single char for now
  int __string_context::countChar(const string_impl& s, const string_impl& splitter) {
      char * pch;
      char delim = splitter.c_str()[0];
      const char* buf = s.c_str();
      if (!buf) {
        return 0;
      }
      int n = 0;
      while ((*buf != 0)) {
        buf++;
        if (*buf == delim) {
          n++;
        }
      }
      return n;
  }
} // namespace K3
<commit_msg>builtins: corrected some 'non-void function' issues<commit_after>#include <functional>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <chrono>
#include <thread>

#include "Common.hpp"
#include "Engine.hpp"
#include "BaseTypes.hpp"
#include "dataspace/Dataspace.hpp"
#include "BaseCollections.hpp"
#include "Builtins.hpp"

namespace K3 {
  using std::endl;
  using std::to_string;

  // Standard context implementations
  __standard_context::__standard_context(Engine& __engine)
    : __k3_context(__engine)
  {}

  unit_t __tcmalloc_context::heapProfilerStart(const string_impl& s) {
    #ifdef MEMPROFILE
    HeapProfilerStart(s.c_str());
    #else
    std::cout << "heapProfilerStart: MEMPROFILE is not defined. not starting." << std::endl;
    #endif
    return unit_t {};
  }

  unit_t __tcmalloc_context::heapProfilerStop(unit_t) {
    #ifdef MEMPROFILE
    HeapProfilerDump("End of Program");
    HeapProfilerStop();
    #endif
    return unit_t {};
  }

  unit_t __standard_context::openBuiltin(string_impl ch_id, string_impl builtin_ch_id, string_impl fmt) {
    __engine.openBuiltin(ch_id, builtin_ch_id, fmt);
    return unit_t();
  }

  unit_t __standard_context::openFile(string_impl ch_id, string_impl path, string_impl fmt, string_impl mode) {
    IOMode iomode = __engine.ioMode(mode);
    __engine.openFile(ch_id, path, fmt, iomode);
    return unit_t();
  }

  unit_t __standard_context::openSocket(string_impl ch_id, Address a, string_impl fmt, string_impl mode) {
    IOMode iomode = __engine.ioMode(mode);
    __engine.openSocket(ch_id, a, fmt, iomode);
    return unit_t();
  }

  bool __standard_context::hasRead(string_impl ch_id) {
    return  __engine.hasRead(std::string(ch_id));
  }

  template<typename T>
  T __standard_context::doRead(string_impl ch_id) {
    shared_ptr<T> v = __engine.doReadExternal<T>(std::string(ch_id));
    if ( v ) { return *v; }
    T r;
    return r;
  }

  template<typename T>
  Collection<R_elem<T>> __standard_context::doReadBlock(string_impl ch_id, int block_size) {
    return  __engine.doReadExternalBlock<T>(std::string(ch_id), block_size);
  }

  bool __standard_context::hasWrite(string_impl ch_id) {
   return  __engine.hasWrite(std::string(ch_id));
  }

  template<typename T>
  unit_t  __standard_context::doWrite(string_impl ch_id, T& val) {
   __engine.doWriteExternal<T>(std::string(ch_id), val);
   return unit_t{};
  }

  unit_t __standard_context::close(string_impl chan_id) {
      __engine.close(chan_id);
      return unit_t();
  }

  int __standard_context::random(int n) {
    throw std::runtime_error("Not implemented: random");
  }

  double __standard_context::randomFraction(unit_t) {
    throw std::runtime_error("Not implemented: random");
  }

  unit_t __standard_context::print(string_impl message) {
    std::cout << message << endl;
    return unit_t();
  }

  unit_t __standard_context::haltEngine(unit_t) {
    __engine.forceTerminateEngine();
    return unit_t();
  }

  unit_t __standard_context::drainEngine(unit_t) {
    throw std::runtime_error("Not implemented: drainEngine");
  }

  unit_t __standard_context::sleep(int n) {
    std::this_thread::sleep_for(std::chrono::milliseconds(n));
    return unit_t();
  }

  __pcm_context::__pcm_context() {}

  __pcm_context::~__pcm_context() {}

  unit_t __pcm_context::cacheProfilerStart(unit_t) {
    #ifdef CACHEPROFILE
    instance = PCM::getInstance();
    if (instance->program() != PCM::Success) {
      std::cout << "PCM startup error!" << std::endl;
    }
    initial_state = std::make_shared<SystemCounterState>(getSystemCounterState());
    #else
    std::cout << "cacheProfileStart: CACHEPROFILE not set. not starting." << std::endl;
    #endif
    return unit_t();
  }

  unit_t __pcm_context::cacheProfilerStop(unit_t) {
    #ifdef CACHEPROFILE
    SystemCounterState after_sstate = getSystemCounterState();
    std::cout << "QPI Incoming: " << getAllIncomingQPILinkBytes(*initial_state, after_sstate) << std::endl;
    std::cout << "QPI Outgoing: " << getAllOutgoingQPILinkBytes(*initial_state, after_sstate) << std::endl;
    std::cout << "L2 cache hit ratio:" << getL2CacheHitRatio(*initial_state,after_sstate) << std::endl;
    std::cout << "L3 cache hit ratio:" << getL3CacheHitRatio(*initial_state,after_sstate) << std::endl;
    std::cout << "Instructions per clock:" << getIPC(*initial_state,after_sstate) << std::endl;
    instance->cleanup();
    #endif
    return unit_t();
  }

  // TODO fix copies related to base_str / std::sring conversion
  F<Collection<R_elem<string_impl>>(const string_impl &)> __string_context::regex_matcher(const string_impl& regex) {
    auto pattern = make_shared<RE2>(regex);
    return [pattern] (const string_impl& in_str) {
      std::string str = in_str;
      re2::StringPiece input(str);
      Collection<R_elem<string_impl>> results;
      std::string s;
      while(RE2::FindAndConsume(&input, *pattern, &s)) {
        results.insert(string_impl(s));
      }
      return results;
    };

  }

  Collection<R_elem<string_impl>> __string_context::regex_matcher_q4(const string_impl& in_str) {
    if (!pattern) {
      pattern = make_shared<RE2>("(?P<url>https?://[^\\s]+)");
    }
    std::string str = in_str;
    re2::StringPiece input(str);
    Collection<R_elem<string_impl>> results;
    std::string s;
    while(RE2::FindAndConsume(&input, *pattern, &s)) {
      results.insert(string_impl(s));
    }
    return results;

  }

  Vector<R_elem<double>> __standard_context::zeroVector(int i) {
    Vector<R_elem<double>> result;
    auto& c = result.getContainer();
    c.resize(i);
    for(int j = 0; j < i; j++) {
     c[j] = R_elem<double>{0.0};
    }
    return result;

  }

  // TODO -> Done
  // Elements must have random values in [0,1)
  Vector<R_elem<double>> __standard_context::randomVector(int i) {
    Vector<R_elem<double>> result;
    auto& c = result.getContainer();
    c.resize(i);
    for(int j = 0; j < i; j++) {
       srand(time(NULL));
       c[j] = R_elem<double>{(rand()/(RAND_MAX+ 1.))};
    }
    return result;
  }

  // Time:
  __time_context::__time_context() {}

  int __time_context::now_int(unit_t) {
    auto t = std::chrono::system_clock::now();
    auto elapsed =std::chrono::duration_cast<std::chrono::milliseconds>(t.time_since_epoch());
    return elapsed.count();
  }

  // String operations:
  __string_context::__string_context() {}
  string_impl __string_context::itos(int i) {
    return string_impl(to_string(i));
  }

  string_impl __string_context::rtos(double d) {
    return string_impl(to_string(d));
  }

  string_impl __string_context::atos(Address a) {
    return string_impl(addressAsString(a));
  }

  // Split a string by substrings
  Seq<R_elem<string_impl>> __string_context::splitString(string_impl s, const string_impl& splitter) {
    return s.splitString(splitter);
  }

  // Splitter is a single char for now
  string_impl __string_context::takeUntil(const string_impl& s, const string_impl& splitter) {
      char * pch;
      char delim = splitter.c_str()[0];
      const char* buf = s.c_str();
      if (!buf) {
        return string_impl();
      }
      int n = 0;
      while ((*buf != 0) && (*buf != delim)) {
        buf++;
        n++;
      }
      return string_impl(buf, n);

  }

  // Splitter is a single char for now
  int __string_context::countChar(const string_impl& s, const string_impl& splitter) {
      char * pch;
      char delim = splitter.c_str()[0];
      const char* buf = s.c_str();
      if (!buf) {
        return 0;
      }
      int n = 0;
      while ((*buf != 0)) {
        buf++;
        if (*buf == delim) {
          n++;
        }
      }
      return n;
  }
} // namespace K3
<|endoftext|>