/*! \file common.h
 *  \brief Common defines
 *
 * Commong Engine defines, macros, enums, ...
 */

#ifndef TDE_ENGINE_COMMON_H
#define TDE_ENGINE_COMMON_H

#include "config.h"

#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <utility>      // std::rel_ops

#if defined(HAVE_STD_SHARED_PTR)
#include <memory>
#elif defined(HAVE_STD_TR1_SHARED_PTR)
#include <tr1/memory>
#elif defined(HAVE_BOOST_SHARED_PTR)
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#endif

#if defined(HAVE_BOOST_WEAK_PTR)
#include <boost/weak_ptr.hpp>
#endif

#if defined(HAVE_STD_FUNCTION)
#include <functional>
#elif defined(HAVE_STD_TR1_FUNCTION)
#include <tr1/functional>
#elif defined(HAVE_BOOST_FUNCTION)
#include <boost/function.hpp>
#include <boost/mem_fn.hpp>
#include <boost/bind.hpp>
#endif

#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
//#include <boost/interprocess/sync/scoped_lock.hpp>

#include <boost/chrono/chrono.hpp>

#if defined(HAVE_STD_TUPLE)
#include <tuple>
#elif defined(HAVE_STD_TR1_TUPLE)
#include <tr1/tuple>
#elif defined(HAVE_BOOST_TUPLE)
#include <boost/tuple/tuple.hpp>
#endif

#include <boost/optional/optional.hpp>

#include <boost/multiprecision/cpp_dec_float.hpp>

#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <memory.h>


/*!
 * \def SHARED_PTR
 * \brief Portable C++ shared pointer macro.
 *
 * Defines the SHARED_PTR macro to be the most
 * up-to-date shared pointer facility available
 * (one of C++11, TR1 or boost).
 */

#if defined(HAVE_STD_SHARED_PTR)
#define SHARED_PTR std::shared_ptr
#define ENABLE_SHARED_FROM_THIS std::enable_shared_from_this
#elif defined(HAVE_STD_TR1_SHARED_PTR)
#define SHARED_PTR std::tr1::shared_ptr
#define ENABLE_SHARED_FROM_THIS std::tr1::enable_shared_from_this
#elif defined(HAVE_BOOST_SHARED_PTR)
#define SHARED_PTR boost::shared_ptr
#define ENABLE_SHARED_FROM_THIS boost::enable_shared_from_this
#endif

#if defined(HAVE_STD_WEAK_PTR)
#define WEAK_PTR std::weak_ptr
#elif defined(HAVE_STD_TR1_WEAK_PTR)
#define WEAK_PTR std::tr1::weak_ptr
#elif defined(HAVE_BOOST_WEAK_PTR)
#define WEAK_PTR boost::weak_ptr
#endif

#if defined(HAVE_STD_FUNCTION)
#define F_FUNCTION std::function
#define F_MEM_FN std::mem_fn
#define F_BIND std::bind
#elif defined(HAVE_STD_TR1_FUNCTION)
#define F_FUNCTION std::tr1::function
#define F_MEM_FN std::tr1::mem_fn
#define F_BIND std::tr1::bind
#elif defined(HAVE_BOOST_FUNCTION)
#define F_FUNCTION boost::function
#define F_MEM_FN boost::mem_fn
#define F_BIND boost::bind
#endif

#if defined(HAVE_STD_TUPLE)
#define TUPLE std::tuple
#define MAKE_TUPLE std::make_tuple
#define TUPLE_GET std::get
#define TUPLE_TIE std::tie
#elif defined(HAVE_STD_TR1_TUPLE)
#define TUPLE std::tr1::tuple
#define MAKE_TUPLE std::tr1::make_tuple
#define TUPLE_GET std::tr1::get
#define TUPLE_TIE std::tr1::tie
#elif defined(HAVE_BOOST_TUPLE)
#define TUPLE boost::tuple
#define MAKE_TUPLE boost::make_tuple
#define TUPLE_GET boost::get
#define TUPLE_TIE boost::tie
#endif

#include "exceptions.h"

namespace TDE {


namespace mp = boost::multiprecision;

typedef uint32_t plc_word_t;
typedef float plc_float_t;
typedef mp::cpp_dec_float_50 plc_decimal_t;

typedef enum {
	PLC_UNKNOWN,
	PLC_BOOL,
	PLC_U8, PLC_I8,
	PLC_U16, PLC_I16,
	PLC_U32, PLC_I32,
	PLC_FLOAT,
	PLC_STRING
} plc_kind_t;


typedef enum {
	PLC_NO_STRING,
	PLC_ID_STRING,
	PLC_CSTRING,
	PLC_ZSTRING
} plc_string_kind_t;


} /* end of namespace TDE */

#endif /* TDE_ENGINE_COMMON_H */
