<commit_before>#line 2 "togo/kvs.hpp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.

@file kvs.hpp
@brief KVS interface.
@ingroup kvs
*/

#pragma once

#include <togo/config.hpp>
#include <togo/types.hpp>
#include <togo/utility.hpp>
#include <togo/kvs_types.hpp>
#include <togo/assert.hpp>
#include <togo/hash.hpp>

namespace togo {

namespace kvs {

/**
	@addtogroup kvs
	@{
*/

namespace {
	static constexpr KVSType const type_mask_vector
		= KVSType::vec1
		| KVSType::vec2
		| KVSType::vec3
		| KVSType::vec4
	;
	/*static constexpr KVSType const type_mask_value
		= KVSType::integer
		| KVSType::decimal
		| KVSType::boolean
		| KVSType::string
		| type_mask_vector
	;
	static constexpr KVSType const type_mask_value_nullable
		= KVSType::null
		| type_mask_value
	;*/
	static constexpr KVSType const type_mask_collection
		= KVSType::array
		| KVSType::node
	;
} // anonymous namespace

/// Get type.
inline KVSType type(KVS const& kvs) {
	return kvs._type;
}

/// Check type equivalence.
inline bool is_type(KVS const& kvs, KVSType const type) {
	return kvs._type == type;
}

/// Check type by set.
inline bool is_type_any(KVS const& kvs, KVSType const type) {
	return enum_bool(kvs._type & type);
}

/// Check if type is KVSType::null.
inline bool is_null(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::null);
}

/// Check if type is KVSType::integer.
inline bool is_integer(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::integer);
}

/// Check if type is KVSType::decimal.
inline bool is_decimal(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::decimal);
}

/// Check if type is KVSType::boolean.
inline bool is_boolean(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::boolean);
}

/// Check if type is KVSType::string.
inline bool is_string(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::string);
}

/// Check if type is a vector type.
inline bool is_vector(KVS const& kvs) {
	return kvs::is_type_any(kvs, type_mask_vector);
}

/// Check if type is an array or node.
inline bool is_collection(KVS const& kvs) {
	return kvs::is_type_any(kvs, type_mask_collection);
}

/// Get name.
///
/// This will return nullptr if the KVS has no name.
inline char const* name(KVS const& kvs) {
	return kvs._name;
}

/// Get name size.
inline unsigned name_size(KVS const& kvs) {
	return kvs._name_size;
}

/// Get name hash.
inline hash64 name_hash(KVS const& kvs) {
	return kvs._name_hash;
}

/// Check if named.
inline bool is_named(KVS const& kvs) {
	return kvs._name;
}

/// Number of values in the collection.
inline unsigned size(KVS const& kvs) {
	return kvs::is_collection(kvs) ? kvs._value.collection.size : 0;
}

/// Returns true if there are any values in the collection.
inline bool any(KVS const& kvs) {
	return kvs::is_collection(kvs) ? kvs._value.collection.size : false;
}

/// Returns true if there are no values in the collection.
inline bool empty(KVS const& kvs) {
	return kvs::is_collection(kvs) ? kvs._value.collection.size == 0 : true;
}

/// Beginning iterator: [begin, end).
inline KVS* begin(KVS& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data
		: nullptr
	;
}
/// Beginning iterator: [begin, end).
inline KVS const* begin(KVS const& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data
		: nullptr
	;
}

/// Ending iterator: [begin, end).
inline KVS* end(KVS& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data + kvs._value.collection.size
		: nullptr
	;
}
/// Ending iterator: [begin, end).
inline KVS const* end(KVS const& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data + kvs._value.collection.size
		: nullptr
	;
}

/// Get integer value.
inline s64 integer(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::integer));
	return kvs._value.integer;
}

/// Get decimal value.
inline f64 decimal(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::decimal));
	return kvs._value.decimal;
}

/// Get boolean value.
inline bool boolean(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::boolean));
	return kvs._value.boolean;
}

/// Get string value.
inline char const* string(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::string));
	return kvs._value.string.data;
}

/// Get string value size.
inline unsigned string_size(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::string));
	return kvs._value.string.size;
}

/// Get 1-dimensional vector value.
inline Vec1 const& vec1(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec1));
	return kvs._value.vec1;
}

/// Get 2-dimensional vector value.
inline Vec2 const& vec2(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec2));
	return kvs._value.vec2;
}

/// Get 3-dimensional vector value.
inline Vec3 const& vec3(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec3));
	return kvs._value.vec3;
}

/// Get 4-dimensional vector value.
inline Vec4 const& vec4(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec4));
	return kvs._value.vec4;
}

/// Clear value (if dynamic) and change type iff type differs.
bool set_type(KVS& kvs, KVSType const type);

/// Set name.
void set_name(KVS& kvs, char const* const name, unsigned const size);

/// Set name.
template<unsigned N>
inline void set_name(KVS& kvs, char const (&name)[N]) {
	kvs::set_name(kvs, name, N);
}

/// Clear name.
void clear_name(KVS& kvs);

/// Clear value.
void clear(KVS& kvs);

/// Clear value (if dynamic) and change type to KVSType::null.
inline void nullify(KVS& kvs) {
	kvs::set_type(kvs, KVSType::null);
}

/// Set integer value.
inline void integer(KVS& kvs, s64 const value) {
	kvs::set_type(kvs, KVSType::integer);
	kvs._value.integer = value;
}

/// Set decimal value.
inline void decimal(KVS& kvs, f64 const value) {
	kvs::set_type(kvs, KVSType::decimal);
	kvs._value.decimal = value;
}

/// Set boolean value.
inline void boolean(KVS& kvs, bool const value) {
	kvs::set_type(kvs, KVSType::boolean);
	kvs._value.boolean = value;
}

/// Set string value.
void string(KVS& kvs, char const* const value, unsigned const size);

/// Set 1-dimensional vector value.
inline void vec1(KVS& kvs, Vec1 const& value) {
	kvs::set_type(kvs, KVSType::vec1);
	kvs._value.vec1 = value;
}

/// Set 2-dimensional vector value.
inline void vec2(KVS& kvs, Vec2 const& value) {
	kvs::set_type(kvs, KVSType::vec2);
	kvs._value.vec2 = value;
}

/// Set 3-dimensional vector value.
inline void vec3(KVS& kvs, Vec3 const& value) {
	kvs::set_type(kvs, KVSType::vec3);
	kvs._value.vec3 = value;
}

/// Set 4-dimensional vector value.
inline void vec4(KVS& kvs, Vec4 const& value) {
	kvs::set_type(kvs, KVSType::vec4);
	kvs._value.vec4 = value;
}

/** @} */ // end of doc-group kvs

} // namespace kvs

/// This will nullify the KVS.
inline KVS::~KVS() {
	kvs::nullify(*this);
	kvs::clear_name(*this);
}

/// Construct null KVS.
inline KVS::KVS()
	: KVS(KVSType::null)
{}

/// Construct with integer value.
inline KVS::KVS(s64 const value) : KVS(KVSType::integer) { _value.integer = value; }

/// Construct with decimal value.
inline KVS::KVS(f64 const value) : KVS(KVSType::decimal) { _value.decimal = value; }

/// Construct with boolean value.
inline KVS::KVS(bool const value) : KVS(KVSType::boolean) { _value.boolean = value; }

/// Construct with string value.
template<unsigned N>
inline KVS::KVS(char const (&value)[N]) : KVS(value, N) {}

/// Construct with 1-dimensional vector value.
inline KVS::KVS(Vec1 const& value) : KVS(KVSType::vec1) { _value.vec1 = value; }

/// Construct with 2-dimensional vector value.
inline KVS::KVS(Vec2 const& value) : KVS(KVSType::vec2) { _value.vec2 = value; }

/// Construct with 3-dimensional vector value.
inline KVS::KVS(Vec3 const& value) : KVS(KVSType::vec3) { _value.vec3 = value; }

/// Construct with 4-dimensional vector value.
inline KVS::KVS(Vec4 const& value) : KVS(KVSType::vec4) { _value.vec4 = value; }

inline KVS::KVS(KVSType const type)
	: _type(type)
	, _name(nullptr)
	, _name_size(0)
	, _name_hash(hash::IDENTITY64)
	, _value()
{}

/** @cond INTERNAL */

// ADL support

inline KVS* begin(KVS& kvs) { return kvs::begin(kvs); }
inline KVS const* begin(KVS const& kvs) { return kvs::begin(kvs); }

inline KVS* end(KVS& kvs) { return kvs::end(kvs); }
inline KVS const* end(KVS const& kvs) { return kvs::end(kvs); }

/** @endcond */ // INTERNAL

} // namespace togo
<commit_msg>kvs: ensure name() and string() always return a valid pointer.<commit_after>#line 2 "togo/kvs.hpp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.

@file kvs.hpp
@brief KVS interface.
@ingroup kvs
*/

#pragma once

#include <togo/config.hpp>
#include <togo/types.hpp>
#include <togo/utility.hpp>
#include <togo/kvs_types.hpp>
#include <togo/assert.hpp>
#include <togo/hash.hpp>

namespace togo {

namespace kvs {

/**
	@addtogroup kvs
	@{
*/

namespace {
	static constexpr KVSType const type_mask_vector
		= KVSType::vec1
		| KVSType::vec2
		| KVSType::vec3
		| KVSType::vec4
	;
	/*static constexpr KVSType const type_mask_value
		= KVSType::integer
		| KVSType::decimal
		| KVSType::boolean
		| KVSType::string
		| type_mask_vector
	;
	static constexpr KVSType const type_mask_value_nullable
		= KVSType::null
		| type_mask_value
	;*/
	static constexpr KVSType const type_mask_collection
		= KVSType::array
		| KVSType::node
	;
} // anonymous namespace

/// Get type.
inline KVSType type(KVS const& kvs) {
	return kvs._type;
}

/// Check type equivalence.
inline bool is_type(KVS const& kvs, KVSType const type) {
	return kvs._type == type;
}

/// Check type by set.
inline bool is_type_any(KVS const& kvs, KVSType const type) {
	return enum_bool(kvs._type & type);
}

/// Check if type is KVSType::null.
inline bool is_null(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::null);
}

/// Check if type is KVSType::integer.
inline bool is_integer(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::integer);
}

/// Check if type is KVSType::decimal.
inline bool is_decimal(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::decimal);
}

/// Check if type is KVSType::boolean.
inline bool is_boolean(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::boolean);
}

/// Check if type is KVSType::string.
inline bool is_string(KVS const& kvs) {
	return kvs::is_type(kvs, KVSType::string);
}

/// Check if type is a vector type.
inline bool is_vector(KVS const& kvs) {
	return kvs::is_type_any(kvs, type_mask_vector);
}

/// Check if type is an array or node.
inline bool is_collection(KVS const& kvs) {
	return kvs::is_type_any(kvs, type_mask_collection);
}

/// Get name (NUL-terminated).
inline char const* name(KVS const& kvs) {
	return kvs._name ? kvs._name : "";
}

/// Get name size.
///
/// This does not include the NUL terminator.
inline unsigned name_size(KVS const& kvs) {
	return kvs._name_size;
}

/// Get name hash.
inline hash64 name_hash(KVS const& kvs) {
	return kvs._name_hash;
}

/// Check if named.
inline bool is_named(KVS const& kvs) {
	return kvs._name;
}

/// Number of values in the collection.
inline unsigned size(KVS const& kvs) {
	return kvs::is_collection(kvs) ? kvs._value.collection.size : 0;
}

/// Returns true if there are any values in the collection.
inline bool any(KVS const& kvs) {
	return kvs::is_collection(kvs) ? kvs._value.collection.size : false;
}

/// Returns true if there are no values in the collection.
inline bool empty(KVS const& kvs) {
	return kvs::is_collection(kvs) ? kvs._value.collection.size == 0 : true;
}

/// Beginning iterator: [begin, end).
inline KVS* begin(KVS& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data
		: nullptr
	;
}
/// Beginning iterator: [begin, end).
inline KVS const* begin(KVS const& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data
		: nullptr
	;
}

/// Ending iterator: [begin, end).
inline KVS* end(KVS& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data + kvs._value.collection.size
		: nullptr
	;
}
/// Ending iterator: [begin, end).
inline KVS const* end(KVS const& kvs) {
	return
		kvs::is_collection(kvs)
		? kvs._value.collection.data + kvs._value.collection.size
		: nullptr
	;
}

/// Get integer value.
inline s64 integer(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::integer));
	return kvs._value.integer;
}

/// Get decimal value.
inline f64 decimal(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::decimal));
	return kvs._value.decimal;
}

/// Get boolean value.
inline bool boolean(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::boolean));
	return kvs._value.boolean;
}

/// Get string value (NUL-terminated).
inline char const* string(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::string));
	return kvs._value.string.data ? kvs._value.string.data : "";
}

/// Get string value size.
///
/// This does not include the NUL terminator.
inline unsigned string_size(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::string));
	return kvs._value.string.size;
}

/// Get 1-dimensional vector value.
inline Vec1 const& vec1(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec1));
	return kvs._value.vec1;
}

/// Get 2-dimensional vector value.
inline Vec2 const& vec2(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec2));
	return kvs._value.vec2;
}

/// Get 3-dimensional vector value.
inline Vec3 const& vec3(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec3));
	return kvs._value.vec3;
}

/// Get 4-dimensional vector value.
inline Vec4 const& vec4(KVS const& kvs) {
	TOGO_ASSERTE(kvs::is_type(kvs, KVSType::vec4));
	return kvs._value.vec4;
}

/// Clear value (if dynamic) and change type iff type differs.
bool set_type(KVS& kvs, KVSType const type);

/// Set name.
void set_name(KVS& kvs, char const* const name, unsigned const size);

/// Set name.
template<unsigned N>
inline void set_name(KVS& kvs, char const (&name)[N]) {
	kvs::set_name(kvs, name, N);
}

/// Clear name.
void clear_name(KVS& kvs);

/// Clear value.
void clear(KVS& kvs);

/// Clear value (if dynamic) and change type to KVSType::null.
inline void nullify(KVS& kvs) {
	kvs::set_type(kvs, KVSType::null);
}

/// Set integer value.
inline void integer(KVS& kvs, s64 const value) {
	kvs::set_type(kvs, KVSType::integer);
	kvs._value.integer = value;
}

/// Set decimal value.
inline void decimal(KVS& kvs, f64 const value) {
	kvs::set_type(kvs, KVSType::decimal);
	kvs._value.decimal = value;
}

/// Set boolean value.
inline void boolean(KVS& kvs, bool const value) {
	kvs::set_type(kvs, KVSType::boolean);
	kvs._value.boolean = value;
}

/// Set string value.
void string(KVS& kvs, char const* const value, unsigned const size);

/// Set 1-dimensional vector value.
inline void vec1(KVS& kvs, Vec1 const& value) {
	kvs::set_type(kvs, KVSType::vec1);
	kvs._value.vec1 = value;
}

/// Set 2-dimensional vector value.
inline void vec2(KVS& kvs, Vec2 const& value) {
	kvs::set_type(kvs, KVSType::vec2);
	kvs._value.vec2 = value;
}

/// Set 3-dimensional vector value.
inline void vec3(KVS& kvs, Vec3 const& value) {
	kvs::set_type(kvs, KVSType::vec3);
	kvs._value.vec3 = value;
}

/// Set 4-dimensional vector value.
inline void vec4(KVS& kvs, Vec4 const& value) {
	kvs::set_type(kvs, KVSType::vec4);
	kvs._value.vec4 = value;
}

/** @} */ // end of doc-group kvs

} // namespace kvs

/// This will nullify the KVS.
inline KVS::~KVS() {
	kvs::nullify(*this);
	kvs::clear_name(*this);
}

/// Construct null KVS.
inline KVS::KVS()
	: KVS(KVSType::null)
{}

/// Construct with integer value.
inline KVS::KVS(s64 const value) : KVS(KVSType::integer) { _value.integer = value; }

/// Construct with decimal value.
inline KVS::KVS(f64 const value) : KVS(KVSType::decimal) { _value.decimal = value; }

/// Construct with boolean value.
inline KVS::KVS(bool const value) : KVS(KVSType::boolean) { _value.boolean = value; }

/// Construct with string value.
template<unsigned N>
inline KVS::KVS(char const (&value)[N]) : KVS(value, N) {}

/// Construct with 1-dimensional vector value.
inline KVS::KVS(Vec1 const& value) : KVS(KVSType::vec1) { _value.vec1 = value; }

/// Construct with 2-dimensional vector value.
inline KVS::KVS(Vec2 const& value) : KVS(KVSType::vec2) { _value.vec2 = value; }

/// Construct with 3-dimensional vector value.
inline KVS::KVS(Vec3 const& value) : KVS(KVSType::vec3) { _value.vec3 = value; }

/// Construct with 4-dimensional vector value.
inline KVS::KVS(Vec4 const& value) : KVS(KVSType::vec4) { _value.vec4 = value; }

inline KVS::KVS(KVSType const type)
	: _type(type)
	, _name(nullptr)
	, _name_size(0)
	, _name_hash(hash::IDENTITY64)
	, _value()
{}

/** @cond INTERNAL */

// ADL support

inline KVS* begin(KVS& kvs) { return kvs::begin(kvs); }
inline KVS const* begin(KVS const& kvs) { return kvs::begin(kvs); }

inline KVS* end(KVS& kvs) { return kvs::end(kvs); }
inline KVS const* end(KVS const& kvs) { return kvs::end(kvs); }

/** @endcond */ // INTERNAL

} // namespace togo
<|endoftext|>


<commit_before>#pragma once
#include <cybozu/inttype.hpp>

namespace cybozu {

template<class T>
uint32_t hash32(const T *x, size_t n, uint32_t v = 0)
{
	if (v == 0) v = 2166136261U;
	for (size_t i = 0; i < n; i++) {
		v ^= x[i];
		v *= 16777619;
	}
	return v;
}
template<class T>
uint64_t hash64(const T *x, size_t n, uint64_t v = 0)
{
	if (v == 0) v = 14695981039346656037ULL;
	for (size_t i = 0; i < n; i++) {
		v ^= x[i];
		v *= 1099511628211ULL;
	}
	v ^= v >> 32;
	return v;
}

} // cybozu

namespace boost {

template<class T>
struct hash;

} // boost

namespace std { CYBOZU_NAMESPACE_TR1_BEGIN

#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable : 4099) // missmatch class and struct
#endif
template<class T>
struct hash;
#ifdef _MSC_VER
	#pragma warning(pop)
#endif

CYBOZU_NAMESPACE_TR1_END } // std
<commit_msg>accept any container for hash<commit_after>#pragma once
#include <cybozu/inttype.hpp>

namespace cybozu {

template<class Iter>
uint32_t hash32(Iter begin, Iter end, uint32_t v = 0)
{
	if (v == 0) v = 2166136261U;
	while (begin != end) {
		v ^= *begin++;
		v *= 16777619;
	}
	return v;
}
template<class Iter>
uint64_t hash64(Iter begin, Iter end, uint64_t v = 0)
{
	if (v == 0) v = 14695981039346656037ULL;
	while (begin != end) {
		v ^= *begin++;
		v *= 1099511628211ULL;
	}
	v ^= v >> 32;
	return v;
}
template<class T>
uint32_t hash32(const T *x, size_t n, uint32_t v = 0)
{
	return hash32(x, x + n, v);
}
template<class T>
uint64_t hash64(const T *x, size_t n, uint64_t v = 0)
{
	return hash64(x, x + n, v);
}

} // cybozu

namespace boost {

template<class T>
struct hash;

} // boost

namespace std { CYBOZU_NAMESPACE_TR1_BEGIN

#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable : 4099) // missmatch class and struct
#endif
template<class T>
struct hash;
#ifdef _MSC_VER
	#pragma warning(pop)
#endif

CYBOZU_NAMESPACE_TR1_END } // std
<|endoftext|>


<commit_before>#ifndef ENUM_CLASS_FLAGS_HPP
#define ENUM_CLASS_FLAGS_HPP

#include "allow_flags.hpp"
#include "iterator.hpp"

#include <bitset>
#include <initializer_list>
#include <numeric>
#include <utility>

namespace flags {

constexpr struct empty_t{} empty;

template <class E> struct flags {
public:
  static_assert(is_flags<E>::value,
                "flags::flags is disallowed for this type; "
                "use ALLOW_FLAGS_FOR_ENUM macro.");

  using enum_type = typename std::decay<E>::type;
  using underlying_type = typename std::underlying_type<enum_type>::type;
  using impl_type = typename std::make_unsigned<underlying_type>::type;

  using iterator = FlagsIterator<enum_type>;
  using const_iterator = iterator;
  using value_type = typename iterator::value_type;
  using reference = typename iterator::reference;
  using const_reference = typename iterator::reference;
  using pointer = enum_type *;
  using const_pointer = const enum_type *;
  using size_type = std::size_t;
  using difference_type = typename iterator::difference_type;

  constexpr static std::size_t bit_size() { return sizeof(impl_type) * 8; }

private:
  template <class T, class Res = std::nullptr_t>
  using convertible = std::enable_if<std::is_convertible<T, enum_type>::value,
                                     Res>;

public:
  flags() noexcept = default;
  flags(const flags &fl) noexcept = default;
  flags &operator=(const flags &fl) noexcept = default;
  flags(flags &&fl) noexcept = default;
  flags &operator=(flags &&fl) noexcept= default;

  explicit constexpr flags(empty_t) noexcept : val_(0) {}

#ifdef ENUM_CLASS_FLAGS_FORBID_IMPLICT_CONVERSION
  explicit
#endif
  constexpr flags(enum_type e) noexcept
  : val_(static_cast<impl_type>(e)) {}

  flags &operator=(enum_type e) noexcept {
    val_ = static_cast<impl_type>(e);
    return *this;
  }

  flags(std::initializer_list<enum_type> il) noexcept : val_(0) { insert(il); }

  flags &operator=(std::initializer_list<enum_type> il) noexcept {
    clear();
    insert(il);
    return *this;
  }

  template <class ... Args>
  flags(enum_type e, Args ... args) noexcept : flags{e, args...} {}

  template <class FwIter>
  flags(FwIter b, FwIter e,
        typename convertible<decltype(*b)>::type = nullptr)
  noexcept(noexcept(std::declval<flags>().insert(std::declval<FwIter>(),
                                                 std::declval<FwIter>())))
  : val_(0)
  { insert(b, e); }

  constexpr explicit operator bool() const noexcept { return val_; }

  constexpr bool operator!() const noexcept { return !val_; }

  flags operator~() const noexcept { return flags(~val_); }

  flags &operator|=(const flags &fl) noexcept {
    val_ |= fl.val_;
    return *this;
  }

  flags &operator&=(const flags &fl) noexcept {
    val_ &= fl.val_;
    return *this;
  }

  flags &operator^=(const flags &fl) noexcept {
    val_ ^= fl.val_;
    return *this;
  }

  flags &operator|=(enum_type e) noexcept {
    val_ |= static_cast<impl_type>(e);
    return *this;
  }

  flags &operator&=(enum_type e) noexcept {
    val_ &= static_cast<impl_type>(e);
    return *this;
  }

  flags &operator^=(enum_type e) noexcept {
    val_ ^= static_cast<impl_type>(e);
    return *this;
  }

  void swap(flags &fl) noexcept { std::swap(val_, fl.val_); }

  constexpr underlying_type underlying_value() const noexcept {
    return static_cast<underlying_type>(val_);
  }

  void set_underlying_value(underlying_type newval) noexcept {
    val_ = static_cast<impl_type>(newval);
  }

  constexpr explicit operator std::bitset<bit_size()>() const noexcept {
    return to_bitset();
  }

  constexpr std::bitset<bit_size()> to_bitset() const noexcept {
    return {val_};
  }

  bool empty() const noexcept { return !val_; }

  size_type size() const noexcept {
    return std::distance(this->begin(), this->end());
  }

  constexpr size_type max_size() const noexcept { return bit_size(); }

  iterator begin() const noexcept { return cbegin(); }
  iterator cbegin() const noexcept { return iterator{val_}; }

  iterator end() const noexcept { return cend(); }
  iterator cend() const noexcept { return {}; }

  iterator find(enum_type e) const noexcept { return {val_, e}; }

  size_type count(enum_type e) const noexcept {
    return find(e) != end() ? 1 : 0;
  }

  std::pair<iterator, iterator> equal_range(enum_type e) const noexcept {
    auto i = find(e);
    auto j = i;
    return {i, ++j};
  }

  template <class... Args>
  std::pair<iterator, bool> emplace(Args && ... args) noexcept {
    return insert(enum_type{args...});
  }

  template <class... Args>
  iterator emplace_hint(iterator, Args && ... args) noexcept {
    return emplace(args...).first;
  }

  std::pair<iterator, bool> insert(enum_type e) noexcept {
    auto i = find(e);
    if (i == end()) {
      i.mask_ = static_cast<impl_type>(e);
      val_ |= i.mask_;
      update_uvalue(i);
      return {i, true};
    }
    return {i, false};
  }

  std::pair<iterator, bool> insert(iterator, enum_type e) noexcept {
    return insert(e);
  }

  template <class FwIter>
  auto insert(FwIter i1, FwIter i2)
  noexcept(noexcept(++i1) && noexcept(*i1) && noexcept(i1 == i2))
  -> typename convertible<decltype(*i1), void>::type {
    val_ |= std::accumulate(i1, i2, impl_type{0}, [](impl_type i, enum_type e) {
      return i | static_cast<impl_type>(e);
    });
  }

  template <class Container>
  auto insert(const Container &ctn) noexcept
  -> decltype(std::begin(ctn), std::end(ctn), void()) {
    insert(std::begin(ctn), std::end(ctn));
  }

  iterator erase(iterator i) noexcept {
    val_ ^= i.mask_;
    update_uvalue(i);
    return ++i;
  }

  size_type erase(enum_type e) noexcept {
    auto e_count = count(e);
    val_ ^= static_cast<impl_type>(e);
    return e_count;
  }

  iterator erase(iterator i1, iterator i2) noexcept {
    val_ ^= flags(i1, i2).val_;
    update_uvalue(i2);
    return ++i2;
  }

  void clear() noexcept { val_ = 0; }

private:
  constexpr explicit flags(impl_type val) noexcept : val_(val) {}

  void update_uvalue(iterator &it) const noexcept { it.uvalue_ = val_; }

  impl_type val_;
};

template <class E>
constexpr flags<E> operator|(flags<E> f1, flags<E> f2) noexcept {
    return f1 |= f2;
}

template <class E>
constexpr flags<E> operator|(flags<E> f, E e) noexcept {
    return f |= e;
}

template <class E>
constexpr flags<E> operator|(E e, flags<E> f) noexcept {
    return f |= e;
}

template <class E>
constexpr flags<E> operator&(flags<E> f1, flags<E> f2) noexcept {
    return f1 &= f2;
}

template <class E>
constexpr flags<E> operator&(flags<E> f, E e) noexcept {
    return f &= e;
}

template <class E>
constexpr flags<E> operator&(E e, flags<E> f) noexcept {;
    return f &= e;
}

template <class E>
constexpr flags<E> operator^(flags<E> f1, flags<E> f2) noexcept {
    return f1 ^= f2;
}

template <class E>
constexpr flags<E> operator^(flags<E> f, E e) noexcept {
    return f ^= e;
}

template <class E>
constexpr flags<E> operator^(E e, flags<E> f) noexcept {
  return f ^= e;
}

template <class E>
constexpr bool operator==(const flags<E> &fl1, const flags<E> &fl2) noexcept {
  return fl1.underlying_value() == fl2.underlying_value();
}

template <class E>
constexpr bool operator!=(const flags<E> &fl1, const flags<E> &fl2) noexcept {
  return fl1.underlying_value() != fl2.underlying_value();
}

template <class E>
constexpr void swap(flags<E> &fl1, flags<E> &fl2) noexcept { fl1.swap(fl2); }

} // namespace flags

template <class E>
constexpr auto operator|(E e1, E e2) noexcept
-> typename std::enable_if<flags::is_flags<E>::value,
                           flags::flags<E>>::type {
  return flags::flags<E>{e1} |= e2;
}

template <class E>
constexpr auto operator&(E e1, E e2) noexcept
-> typename std::enable_if<flags::is_flags<E>::value,
                           flags::flags<E>>::type {
  return flags::flags<E>{e1} &= e2;
}

template <class E>
constexpr auto operator^(E e1, E e2) noexcept
-> typename std::enable_if<flags::is_flags<E>::value,
                           flags::flags<E>>::type {
  return flags::flags<E>{e1} ^= e2;
}

#endif // ENUM_CLASS_FLAGS_HPP
<commit_msg>fix constexps struct with user defined constructor<commit_after>#ifndef ENUM_CLASS_FLAGS_HPP
#define ENUM_CLASS_FLAGS_HPP

#include "allow_flags.hpp"
#include "iterator.hpp"

#include <bitset>
#include <initializer_list>
#include <numeric>
#include <utility>

namespace flags {

constexpr struct empty_t {
    constexpr empty_t() noexcept {}
} empty;

template <class E> struct flags {
public:
  static_assert(is_flags<E>::value,
                "flags::flags is disallowed for this type; "
                "use ALLOW_FLAGS_FOR_ENUM macro.");

  using enum_type = typename std::decay<E>::type;
  using underlying_type = typename std::underlying_type<enum_type>::type;
  using impl_type = typename std::make_unsigned<underlying_type>::type;

  using iterator = FlagsIterator<enum_type>;
  using const_iterator = iterator;
  using value_type = typename iterator::value_type;
  using reference = typename iterator::reference;
  using const_reference = typename iterator::reference;
  using pointer = enum_type *;
  using const_pointer = const enum_type *;
  using size_type = std::size_t;
  using difference_type = typename iterator::difference_type;

  constexpr static std::size_t bit_size() { return sizeof(impl_type) * 8; }

private:
  template <class T, class Res = std::nullptr_t>
  using convertible = std::enable_if<std::is_convertible<T, enum_type>::value,
                                     Res>;

public:
  flags() noexcept = default;
  flags(const flags &fl) noexcept = default;
  flags &operator=(const flags &fl) noexcept = default;
  flags(flags &&fl) noexcept = default;
  flags &operator=(flags &&fl) noexcept= default;

  explicit constexpr flags(empty_t) noexcept : val_(0) {}

#ifdef ENUM_CLASS_FLAGS_FORBID_IMPLICT_CONVERSION
  explicit
#endif
  constexpr flags(enum_type e) noexcept
  : val_(static_cast<impl_type>(e)) {}

  flags &operator=(enum_type e) noexcept {
    val_ = static_cast<impl_type>(e);
    return *this;
  }

  flags(std::initializer_list<enum_type> il) noexcept : val_(0) { insert(il); }

  flags &operator=(std::initializer_list<enum_type> il) noexcept {
    clear();
    insert(il);
    return *this;
  }

  template <class ... Args>
  flags(enum_type e, Args ... args) noexcept : flags{e, args...} {}

  template <class FwIter>
  flags(FwIter b, FwIter e,
        typename convertible<decltype(*b)>::type = nullptr)
  noexcept(noexcept(std::declval<flags>().insert(std::declval<FwIter>(),
                                                 std::declval<FwIter>())))
  : val_(0)
  { insert(b, e); }

  constexpr explicit operator bool() const noexcept { return val_; }

  constexpr bool operator!() const noexcept { return !val_; }

  flags operator~() const noexcept { return flags(~val_); }

  flags &operator|=(const flags &fl) noexcept {
    val_ |= fl.val_;
    return *this;
  }

  flags &operator&=(const flags &fl) noexcept {
    val_ &= fl.val_;
    return *this;
  }

  flags &operator^=(const flags &fl) noexcept {
    val_ ^= fl.val_;
    return *this;
  }

  flags &operator|=(enum_type e) noexcept {
    val_ |= static_cast<impl_type>(e);
    return *this;
  }

  flags &operator&=(enum_type e) noexcept {
    val_ &= static_cast<impl_type>(e);
    return *this;
  }

  flags &operator^=(enum_type e) noexcept {
    val_ ^= static_cast<impl_type>(e);
    return *this;
  }

  void swap(flags &fl) noexcept { std::swap(val_, fl.val_); }

  constexpr underlying_type underlying_value() const noexcept {
    return static_cast<underlying_type>(val_);
  }

  void set_underlying_value(underlying_type newval) noexcept {
    val_ = static_cast<impl_type>(newval);
  }

  constexpr explicit operator std::bitset<bit_size()>() const noexcept {
    return to_bitset();
  }

  constexpr std::bitset<bit_size()> to_bitset() const noexcept {
    return {val_};
  }

  bool empty() const noexcept { return !val_; }

  size_type size() const noexcept {
    return std::distance(this->begin(), this->end());
  }

  constexpr size_type max_size() const noexcept { return bit_size(); }

  iterator begin() const noexcept { return cbegin(); }
  iterator cbegin() const noexcept { return iterator{val_}; }

  iterator end() const noexcept { return cend(); }
  iterator cend() const noexcept { return {}; }

  iterator find(enum_type e) const noexcept { return {val_, e}; }

  size_type count(enum_type e) const noexcept {
    return find(e) != end() ? 1 : 0;
  }

  std::pair<iterator, iterator> equal_range(enum_type e) const noexcept {
    auto i = find(e);
    auto j = i;
    return {i, ++j};
  }

  template <class... Args>
  std::pair<iterator, bool> emplace(Args && ... args) noexcept {
    return insert(enum_type{args...});
  }

  template <class... Args>
  iterator emplace_hint(iterator, Args && ... args) noexcept {
    return emplace(args...).first;
  }

  std::pair<iterator, bool> insert(enum_type e) noexcept {
    auto i = find(e);
    if (i == end()) {
      i.mask_ = static_cast<impl_type>(e);
      val_ |= i.mask_;
      update_uvalue(i);
      return {i, true};
    }
    return {i, false};
  }

  std::pair<iterator, bool> insert(iterator, enum_type e) noexcept {
    return insert(e);
  }

  template <class FwIter>
  auto insert(FwIter i1, FwIter i2)
  noexcept(noexcept(++i1) && noexcept(*i1) && noexcept(i1 == i2))
  -> typename convertible<decltype(*i1), void>::type {
    val_ |= std::accumulate(i1, i2, impl_type{0}, [](impl_type i, enum_type e) {
      return i | static_cast<impl_type>(e);
    });
  }

  template <class Container>
  auto insert(const Container &ctn) noexcept
  -> decltype(std::begin(ctn), std::end(ctn), void()) {
    insert(std::begin(ctn), std::end(ctn));
  }

  iterator erase(iterator i) noexcept {
    val_ ^= i.mask_;
    update_uvalue(i);
    return ++i;
  }

  size_type erase(enum_type e) noexcept {
    auto e_count = count(e);
    val_ ^= static_cast<impl_type>(e);
    return e_count;
  }

  iterator erase(iterator i1, iterator i2) noexcept {
    val_ ^= flags(i1, i2).val_;
    update_uvalue(i2);
    return ++i2;
  }

  void clear() noexcept { val_ = 0; }

private:
  constexpr explicit flags(impl_type val) noexcept : val_(val) {}

  void update_uvalue(iterator &it) const noexcept { it.uvalue_ = val_; }

  impl_type val_;
};

template <class E>
constexpr flags<E> operator|(flags<E> f1, flags<E> f2) noexcept {
    return f1 |= f2;
}

template <class E>
constexpr flags<E> operator|(flags<E> f, E e) noexcept {
    return f |= e;
}

template <class E>
constexpr flags<E> operator|(E e, flags<E> f) noexcept {
    return f |= e;
}

template <class E>
constexpr flags<E> operator&(flags<E> f1, flags<E> f2) noexcept {
    return f1 &= f2;
}

template <class E>
constexpr flags<E> operator&(flags<E> f, E e) noexcept {
    return f &= e;
}

template <class E>
constexpr flags<E> operator&(E e, flags<E> f) noexcept {;
    return f &= e;
}

template <class E>
constexpr flags<E> operator^(flags<E> f1, flags<E> f2) noexcept {
    return f1 ^= f2;
}

template <class E>
constexpr flags<E> operator^(flags<E> f, E e) noexcept {
    return f ^= e;
}

template <class E>
constexpr flags<E> operator^(E e, flags<E> f) noexcept {
  return f ^= e;
}

template <class E>
constexpr bool operator==(const flags<E> &fl1, const flags<E> &fl2) noexcept {
  return fl1.underlying_value() == fl2.underlying_value();
}

template <class E>
constexpr bool operator!=(const flags<E> &fl1, const flags<E> &fl2) noexcept {
  return fl1.underlying_value() != fl2.underlying_value();
}

template <class E>
constexpr void swap(flags<E> &fl1, flags<E> &fl2) noexcept { fl1.swap(fl2); }

} // namespace flags

template <class E>
constexpr auto operator|(E e1, E e2) noexcept
-> typename std::enable_if<flags::is_flags<E>::value,
                           flags::flags<E>>::type {
  return flags::flags<E>{e1} |= e2;
}

template <class E>
constexpr auto operator&(E e1, E e2) noexcept
-> typename std::enable_if<flags::is_flags<E>::value,
                           flags::flags<E>>::type {
  return flags::flags<E>{e1} &= e2;
}

template <class E>
constexpr auto operator^(E e1, E e2) noexcept
-> typename std::enable_if<flags::is_flags<E>::value,
                           flags::flags<E>>::type {
  return flags::flags<E>{e1} ^= e2;
}

#endif // ENUM_CLASS_FLAGS_HPP
<|endoftext|>


<commit_before>#ifndef LIBICS3_ICS3_EEPROM_H_
#define LIBICS3_ICS3_EEPROM_H_

#include"ics3/eepparam.hpp"

#include<algorithm>

namespace ics {
  class ICS3;

  class EepRom {
  public:
    friend ICS3; // for ICS3::getRom()
    EepParam get(EepParam) const;
    void set(const EepParam&) noexcept;
    template<typename Iter> void write(Iter&&) const noexcept;
  private:
    explicit EepRom(const std::array<uint8_t, 64>&);

    std::array<uint8_t, 64> data;
  };

  inline ics::EepParam ics::EepRom::get(EepParam place) const {
    place.read(data);
    return place;
  }

  inline void EepRom::set(const EepParam& param) noexcept {
    param.write(data);
  }

  template<typename Iter> inline void EepRom::write(Iter&& dest) const noexcept {
    std::copy(data.begin(), data.end(), dest);
  }

  inline EepRom::EepRom(const std::array<uint8_t, 64>& src)
  : data {}
  {
    std::copy(src.begin(), src.end(), data.begin());
  }
}

#endif // LIBICS3_ICS3_EEPROM_H_
<commit_msg>Update interface<commit_after>#ifndef LIBICS3_ICS3_EEPROM_H_
#define LIBICS3_ICS3_EEPROM_H_

#include"ics3/eepparam.hpp"

#include<algorithm>

namespace ics {
  class ICS3;

  class EepRom {
  public:
    friend ICS3; // for ICS3::getRom()
    EepParam get(EepParam) const;
    void set(const EepParam&) noexcept;
    template<typename Iter> void write(Iter&&) const;
  private:
    explicit EepRom(const std::array<uint8_t, 64>&);

    std::array<uint8_t, 64> data;
  };

  inline ics::EepParam ics::EepRom::get(EepParam place) const {
    place.read(data); // throw std::out_of_range
    return place;
  }

  inline void EepRom::set(const EepParam& param) noexcept {
    param.write(data);
  }

  template<typename Iter> inline void EepRom::write(Iter&& dest) const {
    std::copy(data.begin(), data.end(), dest);
  }

  inline EepRom::EepRom(const std::array<uint8_t, 64>& src)
  : data {}
  {
    std::copy(src.begin(), src.end(), data.begin());
  }
}

#endif // LIBICS3_ICS3_EEPROM_H_
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

// Network API based on boost::asio
#ifndef LIBPORT_ASIO_HH
# define LIBPORT_ASIO_HH

# include <libport/config.h>
# include <libport/sys/socket.h>
# include <libport/iostream>

// At least on OS X, many symbols are not available where we expect
// them.  And it is clearly connected to our using
// -fvisibility=hidden.  I (AD) could not exactly pinpoint the
// problem, but at least I know one cure: do not play dirty visibility
// tricks with Asio.
# if ! defined WIN32
#  pragma GCC visibility push(default)
# endif
# include <boost/asio.hpp>
# if defined LIBPORT_ENABLE_SSL
#   include <boost/asio/ssl.hpp>
# endif
# if ! defined WIN32
#  pragma GCC visibility pop
# endif

# include <boost/function.hpp>

# include <libport/destructible.hh>
# include <libport/export.hh>
# include <libport/finally.hh>
# include <libport/utime.hh>

# include <boost/version.hpp>
# if BOOST_VERSION >= 103600
#  include <libport/rs232.hh>
# endif

namespace libport
{
  class LIBPORT_API AsioDestructible: public Destructible
  {
    protected:
      virtual void doDestroy();
  };

  //FIXME: extend to provide a way to ensure workerThread not started.
  /** Get the io_service handling all asynchronous operations.
   *
   * \param startWorkerThread create a thread in which to run the io_service.
   * If \b startWorkerThread is false on \b first invocation, the user
   * is responsible for calling the work or poll methods of the io_service.
   */
  LIBPORT_API boost::asio::io_service&
  get_io_service(bool startWorkerThread = true);

  /** BaseSocket class.
   *
   * This class has a callback-based API: onReadFunc() and onErrorFunc().
   */
  class LIBPORT_API BaseSocket: public AsioDestructible
  {
  public:
    virtual ~BaseSocket(){}
    libport::Finally deletor;
    /// Write data asynchronously to the socket.
    virtual void write(const void* data, unsigned int length) = 0;
    /// Alias on write() for API compatibility.
    void send(const void* addr, size_t len)
    {
      write(addr, len);
    }
    /// Alias on close() for API compatibility.
    void disconnect()
    {
      close();
    }
    /// Return if the socket is connected to a remote host.
    virtual bool isConnected() const = 0;
    /// Disconnect the socket from the remote host, calls onError.
    virtual void close() = 0;
    /// Get port of remote endpoint
    virtual unsigned short getRemotePort() const = 0;
    /// Get IP address of remote endpoint
    virtual std::string getRemoteHost() const = 0;
    /// Get port of local endpoint
    virtual unsigned short getLocalPort() const = 0;
    /// Get IP address of local endpoint
    virtual std::string getLocalHost() const = 0;
    virtual int stealFD() = 0;
    virtual int getFD() = 0;
    /// Callback function called each time new data is available.
    boost::function1<bool, boost::asio::streambuf&> onReadFunc;
    /// Callback function called in case of error on the socket.
    boost::function1<void, boost::system::error_code> onErrorFunc;
    /// Mutex to protect access to the above callbacks.
    Lockable callbackLock;
  };

  /// Endpoint on an UDP socket.
  class LIBPORT_API UDPLink
  {
  public:
    virtual ~UDPLink()
    {}
    virtual void reply(const void* data, size_t length) = 0;
    void reply(const std::string& s)
    {
      reply(s.c_str(), s.length());
    }
  };

  /** Socket class with a higher API.
   *
   * It is recommended that you always asynchronously destroy Socket instances
   * by calling the destroy() method. If you want to put instances in the stack,
   * or explicitly call delete for whatever reason, you must in your destructor:
   * - call close()
   * - call wasDestroyed()
   * - call waitForDestructionPermission(), if the io_service is running in
   *   another thread(the default behavior).
   */
  class LIBPORT_API Socket: public AsioDestructible
  {
  public:
    Socket(boost::asio::io_service& io = libport::get_io_service())
      : base_(0)
      , io_(io)
    {}
    virtual ~Socket();
    /** Set underlying BaseSocket object, setup its callbacks to call our virtual functions.
     */
    virtual void setBase(BaseSocket*);

    /** Called each time new data is received.
     *   \return the number of bytes used in buffer. The remaining data will
     *   be passed again to this function as soon as at least an extra byte
     *   is available.
     */
    virtual int onRead(const void*, size_t length)
    {
      return length;
    }

    /** Called in case of error on the socket. By default, do nothing.
     */
    virtual void onError(boost::system::error_code);

    /** Called on socket connection
     */
    virtual void onConnect()
    {}

    /// Ask for the asynchronous destruction of this object.
    virtual void destroy();

    void write(const void* data, unsigned int length)
    {
      base_->write(data, length);
    }
    /// Alias on write() for API compatibility.
    void send(const void* addr, size_t len)
    {
      write(addr, len);
    }
    void send(const std::string& s)
    {
      write(s.c_str(), s.length());
    }
    void close()
    {
      if (base_)
        base_->close();
    }

    unsigned short getRemotePort() const { return base_->getRemotePort();}
    std::string getRemoteHost() const    { return base_->getRemoteHost();}
    unsigned short getLocalPort() const  { return base_->getLocalPort();}
    std::string getLocalHost() const     { return base_->getLocalHost();}
    bool isConnected() const      {return base_ ? base_->isConnected() : false;}

    /** Connect to a remote host.
     * \param host hostname to connect to.
     * \param port port to connect to, as a service name or an int.
     * \param usTimeout timeout in microseconds, 0 meaning none.
     * \param asynchronous make an asynchronous attempt. The function will
     *    return immediately, and either onConnect will be called when the
     *    connection succeeds, or onError() will be called.
     * \return an error code if the connection failed.
     *
     */
    boost::system::error_code connect(const std::string& host,
                                      const std::string& port,
                                      bool udp=false, utime_t usTimeout = 0,
                                      bool asynchronous = false);

    boost::system::error_code connect(const std::string& host,
                                      unsigned port,
                                      bool udp=false, utime_t usTimeout = 0,
                                      bool asynchronous = false);

# if BOOST_VERSION >= 103600

    boost::system::error_code open_serial(const std::string& device,
                                          unsigned int rate);

# endif

    /** Make an asynchronous connection attempt to a remote host.
     *  This API garantees that either the onConnect() or the onError() function
     *  will be called.
     * \param host hostname to connect to.
     * \param port port to connect to, as a service name or an int.
     * \param usTimeout timeout in microseconds, 0 meaning none.
     */
    void async_connect(const std::string& host,
                       const std::string& port,
                       bool udp=false, utime_t usTimeout = 0)
    {
      connect(host, port, udp, usTimeout, true);
    }

    typedef void* Handle;
    typedef boost::function0<Socket*> SocketFactory;
    /** Listen using udp.
     * Call onRead(data, length, link) for each new packet. Link can be used
     * to reply to the sender through its UDPLink::reply() method.
     */
    static Handle listenUDP(const std::string& host, const std::string& port,
                            boost::function3<void, const void*, int,
                            boost::shared_ptr<UDPLink> > onRead,
                            boost::system::error_code& erc);

    /** Listen using TCP or UDP.
     *
     * \param f a socket factory. For each new connection the function will
     * be called and the resulting socket object bound to the new connection.
     */
    boost::system::error_code listen(SocketFactory f, const std::string& host,
                                     const std::string& port, bool udp = false);
    boost::system::error_code listen(SocketFactory f, const std::string& host,
                                     unsigned port, bool udp = false);

#if defined LIBPORT_ENABLE_SSL
    boost::system::error_code
    listenSSL(SocketFactory f,
              const std::string& host,
              const std::string& port,
              boost::asio::ssl::context_base::method ctx
                = boost::asio::ssl::context::sslv23_server,
              boost::asio::ssl::context::options options
                = boost::asio::ssl::context::verify_none,
              const std::string& privateKeyFile = "",
              const std::string& certChainFile = "",
              const std::string& tmpDHFile = "" ,
              const std::string& cipherList = "");
#endif

    /// Steal file descriptor from Socket. Return the file descriptor.
    int stealFD();
    /// Get file descriptor from Socket.
    int getFD();
    /// Set file descriptor
    template<class Sock>
    void setFD(int fd, typename Sock::protocol_type proto);
    /** Sleep for specified amount of time, polling if current thread is
     * the asio worker thread
     */
    static void sleep(utime_t duration);
    boost::asio::io_service& get_io_service();
  protected:
    bool onRead_(boost::asio::streambuf&);
    std::string buffer;
    BaseSocket* base_;
  private:
    template<typename Proto, typename BaseFactory> boost::system::error_code
    listenProto(SocketFactory f, const std::string& host,
                const std::string&port, BaseFactory bf);
    template<typename Proto, typename BaseFactory> boost::system::error_code
    connectProto(const std::string& host, const std::string& port,
                 utime_t timeout, bool async, BaseFactory bf);
    boost::asio::io_service& io_;
  };

  /** Wrapper of libport::Socket to be able to use Socket without inherit from
   *  it.
   */
  class LIBPORT_API ConcreteSocket: public Socket
  {
  public:
    typedef boost::function2<int, const void*, size_t> onread_type;
    typedef boost::function1<void, boost::system::error_code> onerror_type;
    typedef boost::function0<void> onconnect_type;
    typedef Socket super_type;

    ConcreteSocket(boost::asio::io_service& io = libport::get_io_service())
      : Socket(io)
      , onconnect_(boost::bind(&super_type::onConnect, this))
      , onerror_(boost::bind(&super_type::onError, this, _1))
      , onread_(boost::bind(&super_type::onRead, this, _1, _2))
      {}

    ConcreteSocket& onConnect(onconnect_type cb)
    {
      onconnect_ = cb;
      return *this;
    }

    ConcreteSocket& onError(onerror_type cb)
    {
      onerror_ = cb;
      return *this;
    }

    ConcreteSocket& onRead(onread_type cb)
    {
      onread_ = cb;
      return *this;
    }

    virtual void onConnect()
    {
      onconnect_();
    }
    virtual void onError(boost::system::error_code erc)
    {
      onerror_(erc);
    }
    virtual int onRead(const void* data, size_t length)
    {
      return onread_(data, length);
    }

  private:
    onconnect_type onconnect_;
    onerror_type onerror_;
    onread_type onread_;
  };

  LIBPORT_API bool
  isPollThread();

  /** Poll on an io_service for given duration in microseconds.
   *  @param duration max duration for which to poll in microseconds
   *  @param once process at most one handler before returning if true
   */
  LIBPORT_API void
  pollFor(utime_t duration, bool once = false,
          boost::asio::io_service& io = get_io_service());

  typedef boost::shared_ptr<boost::asio::deadline_timer> AsyncCallHandler;
  /** Call \b callback() in \b usDelay microseconds.
   *  If the method cancel() of the returned timer object is invoked before
   *  expiration of the delay, the call is aborted and callback() is not
   *  called.
   */
  AsyncCallHandler
  asyncCall(boost::function0<void> callback, utime_t usDelay,
            boost::asio::io_service& io = get_io_service());
}

# include "libport/asio.hxx"

#endif
<commit_msg>80 columns.<commit_after>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

// Network API based on boost::asio
#ifndef LIBPORT_ASIO_HH
# define LIBPORT_ASIO_HH

# include <libport/config.h>
# include <libport/sys/socket.h>
# include <libport/iostream>

// At least on OS X, many symbols are not available where we expect
// them.  And it is clearly connected to our using
// -fvisibility=hidden.  I (AD) could not exactly pinpoint the
// problem, but at least I know one cure: do not play dirty visibility
// tricks with Asio.
# if ! defined WIN32
#  pragma GCC visibility push(default)
# endif
# include <boost/asio.hpp>
# if defined LIBPORT_ENABLE_SSL
#   include <boost/asio/ssl.hpp>
# endif
# if ! defined WIN32
#  pragma GCC visibility pop
# endif

# include <boost/function.hpp>

# include <libport/destructible.hh>
# include <libport/export.hh>
# include <libport/finally.hh>
# include <libport/utime.hh>

# include <boost/version.hpp>
# if BOOST_VERSION >= 103600
#  include <libport/rs232.hh>
# endif

namespace libport
{
  class LIBPORT_API AsioDestructible: public Destructible
  {
    protected:
      virtual void doDestroy();
  };

  //FIXME: extend to provide a way to ensure workerThread not started.
  /** Get the io_service handling all asynchronous operations.
   *
   * \param startWorkerThread create a thread in which to run the io_service.
   * If \b startWorkerThread is false on \b first invocation, the user
   * is responsible for calling the work or poll methods of the io_service.
   */
  LIBPORT_API boost::asio::io_service&
  get_io_service(bool startWorkerThread = true);

  /** BaseSocket class.
   *
   * This class has a callback-based API: onReadFunc() and onErrorFunc().
   */
  class LIBPORT_API BaseSocket: public AsioDestructible
  {
  public:
    virtual ~BaseSocket(){}
    libport::Finally deletor;
    /// Write data asynchronously to the socket.
    virtual void write(const void* data, unsigned int length) = 0;
    /// Alias on write() for API compatibility.
    void send(const void* addr, size_t len)
    {
      write(addr, len);
    }
    /// Alias on close() for API compatibility.
    void disconnect()
    {
      close();
    }
    /// Return if the socket is connected to a remote host.
    virtual bool isConnected() const = 0;
    /// Disconnect the socket from the remote host, calls onError.
    virtual void close() = 0;
    /// Get port of remote endpoint
    virtual unsigned short getRemotePort() const = 0;
    /// Get IP address of remote endpoint
    virtual std::string getRemoteHost() const = 0;
    /// Get port of local endpoint
    virtual unsigned short getLocalPort() const = 0;
    /// Get IP address of local endpoint
    virtual std::string getLocalHost() const = 0;
    virtual int stealFD() = 0;
    virtual int getFD() = 0;
    /// Callback function called each time new data is available.
    boost::function1<bool, boost::asio::streambuf&> onReadFunc;
    /// Callback function called in case of error on the socket.
    boost::function1<void, boost::system::error_code> onErrorFunc;
    /// Mutex to protect access to the above callbacks.
    Lockable callbackLock;
  };

  /// Endpoint on an UDP socket.
  class LIBPORT_API UDPLink
  {
  public:
    virtual ~UDPLink()
    {}
    virtual void reply(const void* data, size_t length) = 0;
    void reply(const std::string& s)
    {
      reply(s.c_str(), s.length());
    }
  };

  /** Socket class with a higher API.
   *
   * It is recommended that you always asynchronously destroy Socket instances
   * by calling the destroy() method. If you want to put instances in the stack,
   * or explicitly call delete for whatever reason, you must in your destructor:
   * - call close()
   * - call wasDestroyed()
   * - call waitForDestructionPermission(), if the io_service is running in
   *   another thread(the default behavior).
   */
  class LIBPORT_API Socket: public AsioDestructible
  {
  public:
    Socket(boost::asio::io_service& io = libport::get_io_service())
      : base_(0)
      , io_(io)
    {}
    virtual ~Socket();
    /* Set underlying BaseSocket object, setup its callbacks to call
     * our virtual functions.
     */
    virtual void setBase(BaseSocket*);

    /** Called each time new data is received.
     *   \return the number of bytes used in buffer. The remaining data will
     *   be passed again to this function as soon as at least an extra byte
     *   is available.
     */
    virtual int onRead(const void*, size_t length)
    {
      return length;
    }

    /** Called in case of error on the socket. By default, do nothing.
     */
    virtual void onError(boost::system::error_code);

    /** Called on socket connection
     */
    virtual void onConnect()
    {}

    /// Ask for the asynchronous destruction of this object.
    virtual void destroy();

    void write(const void* data, unsigned int length)
    {
      base_->write(data, length);
    }
    /// Alias on write() for API compatibility.
    void send(const void* addr, size_t len)
    {
      write(addr, len);
    }
    void send(const std::string& s)
    {
      write(s.c_str(), s.length());
    }
    void close()
    {
      if (base_)
        base_->close();
    }

    unsigned short getRemotePort() const { return base_->getRemotePort();}
    std::string getRemoteHost() const    { return base_->getRemoteHost();}
    unsigned short getLocalPort() const  { return base_->getLocalPort();}
    std::string getLocalHost() const     { return base_->getLocalHost();}
    bool isConnected() const      {return base_ ? base_->isConnected() : false;}

    /** Connect to a remote host.
     * \param host hostname to connect to.
     * \param port port to connect to, as a service name or an int.
     * \param usTimeout timeout in microseconds, 0 meaning none.
     * \param asynchronous make an asynchronous attempt. The function will
     *    return immediately, and either onConnect will be called when the
     *    connection succeeds, or onError() will be called.
     * \return an error code if the connection failed.
     *
     */
    boost::system::error_code connect(const std::string& host,
                                      const std::string& port,
                                      bool udp=false, utime_t usTimeout = 0,
                                      bool asynchronous = false);

    boost::system::error_code connect(const std::string& host,
                                      unsigned port,
                                      bool udp=false, utime_t usTimeout = 0,
                                      bool asynchronous = false);

# if BOOST_VERSION >= 103600

    boost::system::error_code open_serial(const std::string& device,
                                          unsigned int rate);

# endif

    /** Make an asynchronous connection attempt to a remote host.
     *  This API garantees that either the onConnect() or the onError() function
     *  will be called.
     * \param host hostname to connect to.
     * \param port port to connect to, as a service name or an int.
     * \param usTimeout timeout in microseconds, 0 meaning none.
     */
    void async_connect(const std::string& host,
                       const std::string& port,
                       bool udp=false, utime_t usTimeout = 0)
    {
      connect(host, port, udp, usTimeout, true);
    }

    typedef void* Handle;
    typedef boost::function0<Socket*> SocketFactory;
    /** Listen using udp.
     * Call onRead(data, length, link) for each new packet. Link can be used
     * to reply to the sender through its UDPLink::reply() method.
     */
    static Handle listenUDP(const std::string& host, const std::string& port,
                            boost::function3<void, const void*, int,
                            boost::shared_ptr<UDPLink> > onRead,
                            boost::system::error_code& erc);

    /** Listen using TCP or UDP.
     *
     * \param f a socket factory. For each new connection the function will
     * be called and the resulting socket object bound to the new connection.
     */
    boost::system::error_code listen(SocketFactory f, const std::string& host,
                                     const std::string& port, bool udp = false);
    boost::system::error_code listen(SocketFactory f, const std::string& host,
                                     unsigned port, bool udp = false);

#if defined LIBPORT_ENABLE_SSL
    boost::system::error_code
    listenSSL(SocketFactory f,
              const std::string& host,
              const std::string& port,
              boost::asio::ssl::context_base::method ctx
                = boost::asio::ssl::context::sslv23_server,
              boost::asio::ssl::context::options options
                = boost::asio::ssl::context::verify_none,
              const std::string& privateKeyFile = "",
              const std::string& certChainFile = "",
              const std::string& tmpDHFile = "" ,
              const std::string& cipherList = "");
#endif

    /// Steal file descriptor from Socket. Return the file descriptor.
    int stealFD();
    /// Get file descriptor from Socket.
    int getFD();
    /// Set file descriptor
    template<class Sock>
    void setFD(int fd, typename Sock::protocol_type proto);
    /** Sleep for specified amount of time, polling if current thread is
     * the asio worker thread
     */
    static void sleep(utime_t duration);
    boost::asio::io_service& get_io_service();
  protected:
    bool onRead_(boost::asio::streambuf&);
    std::string buffer;
    BaseSocket* base_;
  private:
    template<typename Proto, typename BaseFactory> boost::system::error_code
    listenProto(SocketFactory f, const std::string& host,
                const std::string&port, BaseFactory bf);
    template<typename Proto, typename BaseFactory> boost::system::error_code
    connectProto(const std::string& host, const std::string& port,
                 utime_t timeout, bool async, BaseFactory bf);
    boost::asio::io_service& io_;
  };

  /** Wrapper of libport::Socket to be able to use Socket without inherit from
   *  it.
   */
  class LIBPORT_API ConcreteSocket: public Socket
  {
  public:
    typedef boost::function2<int, const void*, size_t> onread_type;
    typedef boost::function1<void, boost::system::error_code> onerror_type;
    typedef boost::function0<void> onconnect_type;
    typedef Socket super_type;

    ConcreteSocket(boost::asio::io_service& io = libport::get_io_service())
      : Socket(io)
      , onconnect_(boost::bind(&super_type::onConnect, this))
      , onerror_(boost::bind(&super_type::onError, this, _1))
      , onread_(boost::bind(&super_type::onRead, this, _1, _2))
      {}

    ConcreteSocket& onConnect(onconnect_type cb)
    {
      onconnect_ = cb;
      return *this;
    }

    ConcreteSocket& onError(onerror_type cb)
    {
      onerror_ = cb;
      return *this;
    }

    ConcreteSocket& onRead(onread_type cb)
    {
      onread_ = cb;
      return *this;
    }

    virtual void onConnect()
    {
      onconnect_();
    }
    virtual void onError(boost::system::error_code erc)
    {
      onerror_(erc);
    }
    virtual int onRead(const void* data, size_t length)
    {
      return onread_(data, length);
    }

  private:
    onconnect_type onconnect_;
    onerror_type onerror_;
    onread_type onread_;
  };

  LIBPORT_API bool
  isPollThread();

  /** Poll on an io_service for given duration in microseconds.
   *  @param duration max duration for which to poll in microseconds
   *  @param once process at most one handler before returning if true
   */
  LIBPORT_API void
  pollFor(utime_t duration, bool once = false,
          boost::asio::io_service& io = get_io_service());

  typedef boost::shared_ptr<boost::asio::deadline_timer> AsyncCallHandler;
  /** Call \b callback() in \b usDelay microseconds.
   *  If the method cancel() of the returned timer object is invoked before
   *  expiration of the delay, the call is aborted and callback() is not
   *  called.
   */
  AsyncCallHandler
  asyncCall(boost::function0<void> callback, utime_t usDelay,
            boost::asio::io_service& io = get_io_service());
}

# include "libport/asio.hxx"

#endif
<|endoftext|>


<commit_before>/* This file is part of the yazpp toolkit.
 * Copyright (C) 1998-2013 Index Data and Mike Taylor
 * See the file LICENSE for details.
 */

#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <yazpp/z-query.h>

using namespace yazpp_1;

void tst1(const char *query_str_in, const char *query_expected)
{
    Yaz_Z_Query q;

    q = query_str_in;

    Yaz_Z_Query q2;

    q2 = q;

    char query_str_out[100];
    q2.print(query_str_out, sizeof(query_str_out)-1);

    if (strcmp(query_str_out, query_expected))
    {
	fprintf(stderr, "tstquery: query mismatch out=%s expected=%s\n",
		query_str_out, query_expected);
	exit(1);
    }
}

int main(int argc, char **argv)
{
    tst1("", "");
    tst1("x", "RPN @attrset Bib-1 x");
    tst1("@and a b", "RPN @attrset Bib-1 @and a b");
}

/*
 * Local variables:
 * c-basic-offset: 4
 * c-file-style: "Stroustrup"
 * indent-tabs-mode: nil
 * End:
 * vim: shiftwidth=4 tabstop=8 expandtab
 */

<commit_msg>tstquery using YAZ check<commit_after>/* This file is part of the yazpp toolkit.
 * Copyright (C) 1998-2013 Index Data and Mike Taylor
 * See the file LICENSE for details.
 */

#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <yazpp/z-query.h>
#include <yaz/test.h>
#include <yaz/log.h>

using namespace yazpp_1;

int tst1(const char *query_str_in, const char *query_expected)
{
    Yaz_Z_Query q;

    q = query_str_in;

    Yaz_Z_Query q2;

    q2 = q;

    char query_str_out[100];
    q2.print(query_str_out, sizeof(query_str_out)-1);

    if (strcmp(query_str_out, query_expected))
    {
	yaz_log(YLOG_LOG, "query mismatch out=%s expected=%s",
		query_str_out, query_expected);
        return 0;
    }
    return 1;
}

int main(int argc, char **argv)
{
    YAZ_CHECK_INIT(argc, argv);
    YAZ_CHECK(tst1("", ""));
    YAZ_CHECK(tst1("x", "RPN @attrset Bib-1 x"));
    YAZ_CHECK(tst1("@and a b", "RPN @attrset Bib-1 @and a b"));
    YAZ_CHECK_TERM;
}

/*
 * Local variables:
 * c-basic-offset: 4
 * c-file-style: "Stroustrup"
 * indent-tabs-mode: nil
 * End:
 * vim: shiftwidth=4 tabstop=8 expandtab
 */

<|endoftext|>


<commit_before>#include "osl/state/numEffectState.h"
#include "osl/effect_util/effectUtil.h"
#include "osl/container/moveVector.h"
#include "osl/record/csa.h"
#include "osl/record/csaIOError.h"
#include "osl/move_generator/legalMoves.h"
#include <boost/random/mersenne_twister.hpp>
#include <string>
#include <sys/time.h>

namespace osl {
  void
  showState(const NumEffectState& state)
  {
    std::cout << state << std::endl;
  }

  Move
  selectMove(const NumEffectState& state, const MoveVector& moves)
  {
    static boost::mt11213b generator(random());
    return moves[generator() % moves.size()];
  }

  bool
  isMated(const NumEffectState& state)
  {
    return state.inCheck(alt(state.turn()));
  }

  bool
  computerOperate(NumEffectState& state)
  {
    MoveVector moves;
    LegalMoves::generate(state, moves);
    if (moves.empty()) {
      std::cout << "You Win!" << std::endl;
      return true;
    }
    const Move my_move = selectMove(state, moves);
    assert(state.isValidMove(my_move));
    state.makeMove(my_move);

    showState(state);
    csaShow(std::cout, my_move);
    std::cout << "\n";

    if (isMated(state)) {
      std::cout << "You Lose..." << std::endl;
      return true;
    }

    return false;
  }

  bool
  playerOperate(NumEffectState& state, std::string line)
  {
    Move op_move;
    if (line.length() == 4) {
      MoveVector moves;
      LegalMoves::generate(state, moves);
      int i;
      for (i = 0; i < moves.size(); i++) {
        Move m = moves[i];
        Square from = m.from();
        Square to = m.to();
        if (((int)line[0] - (int)'0') == from.x() &&
            ((int)line[1] - (int)'0') == from.y() &&
            ((int)line[2] - (int)'0') == to.x() &&
            ((int)line[3] - (int)'0') == to.y()) {
          op_move = m;
          break;
        }
      }
    } else if (line.length() != 7) {
      std::cout << "error: invalid format." << std::endl;
      return true;
    } else {
    try {
      op_move = record::csa::strToMove(line, state);
    } catch (const std::runtime_error& e) {
      std::cout << e.what() << std::endl;
      return true;
    }
    }

    if (! state.isValidMove(op_move)) {
      return true;
    }

    state.makeMove(op_move);

    showState(state);
    csaShow(std::cout, op_move);
    std::cout << "\n";

    return false;
  }

  std::string
  inputLine(void)
  {
    std::string line;
    if (! std::getline(std::cin, line)) {
      return NULL;
    }
    return line;
  }
}

int
main()
{
  using namespace osl;

  srandom(time(0));

  NumEffectState state((SimpleState(HIRATE)));
  while (true) {
    bool ended = computerOperate(state);
    if (ended) {
      break;
    }

    std::string line = inputLine();
    bool failed = playerOperate(state, line);
    if (failed) {
      break;
    }
  }
}
<commit_msg>Indent<commit_after>#include "osl/state/numEffectState.h"
#include "osl/effect_util/effectUtil.h"
#include "osl/container/moveVector.h"
#include "osl/record/csa.h"
#include "osl/record/csaIOError.h"
#include "osl/move_generator/legalMoves.h"
#include <boost/random/mersenne_twister.hpp>
#include <string>
#include <sys/time.h>

namespace osl {
  void
  showState(const NumEffectState& state)
  {
    std::cout << state << std::endl;
  }

  Move
  selectMove(const NumEffectState& state, const MoveVector& moves)
  {
    static boost::mt11213b generator(random());
    return moves[generator() % moves.size()];
  }

  bool
  isMated(const NumEffectState& state)
  {
    return state.inCheck(alt(state.turn()));
  }

  bool
  computerOperate(NumEffectState& state)
  {
    MoveVector moves;
    LegalMoves::generate(state, moves);
    if (moves.empty()) {
      std::cout << "You Win!" << std::endl;
      return true;
    }
    const Move my_move = selectMove(state, moves);
    assert(state.isValidMove(my_move));
    state.makeMove(my_move);

    showState(state);
    csaShow(std::cout, my_move);
    std::cout << "\n";

    if (isMated(state)) {
      std::cout << "You Lose..." << std::endl;
      return true;
    }

    return false;
  }

  bool
  playerOperate(NumEffectState& state, std::string line)
  {
    Move op_move;
    if (line.length() == 4) {
      MoveVector moves;
      LegalMoves::generate(state, moves);
      int i;
      for (i = 0; i < moves.size(); i++) {
        Move m = moves[i];
        Square from = m.from();
        Square to = m.to();
        if (((int)line[0] - (int)'0') == from.x() &&
            ((int)line[1] - (int)'0') == from.y() &&
            ((int)line[2] - (int)'0') == to.x() &&
            ((int)line[3] - (int)'0') == to.y()) {
          op_move = m;
          break;
        }
      }
    } else if (line.length() != 7) {
      std::cout << "error: invalid format." << std::endl;
      return true;
    } else {
      try {
        op_move = record::csa::strToMove(line, state);
      } catch (const std::runtime_error& e) {
        std::cout << e.what() << std::endl;
        return true;
      }
    }

    if (! state.isValidMove(op_move)) {
      return true;
    }

    state.makeMove(op_move);

    showState(state);
    csaShow(std::cout, op_move);
    std::cout << "\n";

    return false;
  }

  std::string
  inputLine(void)
  {
    std::string line;
    if (! std::getline(std::cin, line)) {
      return NULL;
    }
    return line;
  }
}

int
main()
{
  using namespace osl;

  srandom(time(0));

  NumEffectState state((SimpleState(HIRATE)));
  while (true) {
    bool ended = computerOperate(state);
    if (ended) {
      break;
    }

    std::string line = inputLine();
    bool failed = playerOperate(state, line);
    if (failed) {
      break;
    }
  }
}
<|endoftext|>


<commit_before>//
//  peglint.cc
//
//  Copyright (c) 2015 Yuji Hirose. All rights reserved.
//  MIT License
//

#include <peglib.h>
#include <fstream>

using namespace std;

bool read_file(const char* path, vector<char>& buff)
{
    ifstream ifs(path, ios::in | ios::binary);
    if (ifs.fail()) {
        return false;
    }

    buff.resize(static_cast<unsigned int>(ifs.seekg(0, ios::end).tellg()));
    if (!buff.empty()) {
        ifs.seekg(0, ios::beg).read(&buff[0], static_cast<streamsize>(buff.size()));
    }
    return true;
}

int main(int argc, const char** argv)
{
    auto opt_ast = false;
    auto opt_optimize_ast_nodes = false;
    auto opt_help = false;
    vector<const char*> path_list;

    auto argi = 1;
    while (argi < argc) {
        auto arg = argv[argi++];
        if (string("--help") == arg) {
            opt_help = true;
        } else if (string("--ast") == arg) {
            opt_ast = true;
        } else if (string("--optimize_ast_nodes") == arg || string("--opt") == arg) {
            opt_optimize_ast_nodes = true;
        } else {
            path_list.push_back(arg);
        }
    }

    if (path_list.empty() || opt_help) {
        cerr << "usage: peglint [--ast] [--optimize_ast_nodes|--opt] [grammar file path] [source file path]" << endl;
        return 1;
    }

    // Check PEG grammar
    auto syntax_path = path_list[0];

    vector<char> syntax;
    if (!read_file(syntax_path, syntax)) {
        cerr << "can't open the grammar file." << endl;
        return -1;
    }

    peglib::peg peg;

    peg.log = [&](auto ln, auto col, const auto& msg) {
        cerr << syntax_path << ":" << ln << ":" << col << ": " << msg << endl;
    };

    if (!peg.load_grammar(syntax.data(), syntax.size())) {
        return -1;
    }

    if (path_list.size() < 2) {
        return 0;
    }

    // Check source
    auto source_path = path_list[1];

    vector<char> source;
    if (!read_file(source_path, source)) {
       auto beg = source_path;
       auto end = source_path + strlen(source_path);
       source.assign(beg, end);
       source_path = "[commendline]";
    }

    peg.log = [&](auto ln, auto col, const auto& msg) {
        cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl;
    };

    if (opt_ast) {
	    peg.enable_ast(opt_optimize_ast_nodes);

	    std::shared_ptr<peglib::Ast> ast;
	    if (!peg.parse_n(source.data(), source.size(), ast)) {
	        return -1;
	    }

	    peglib::AstPrint().print(*ast);
    } else {
	    if (!peg.parse_n(source.data(), source.size())) {
	        return -1;
	    }
    }

    return 0;
}

// vim: et ts=4 sw=4 cin cino={1s ff=unix
<commit_msg>Fixed source code format.<commit_after>//
//  peglint.cc
//
//  Copyright (c) 2015 Yuji Hirose. All rights reserved.
//  MIT License
//

#include <peglib.h>
#include <fstream>

using namespace std;

bool read_file(const char* path, vector<char>& buff)
{
    ifstream ifs(path, ios::in | ios::binary);
    if (ifs.fail()) {
        return false;
    }

    buff.resize(static_cast<unsigned int>(ifs.seekg(0, ios::end).tellg()));
    if (!buff.empty()) {
        ifs.seekg(0, ios::beg).read(&buff[0], static_cast<streamsize>(buff.size()));
    }
    return true;
}

int main(int argc, const char** argv)
{
    auto opt_ast = false;
    auto opt_optimize_ast_nodes = false;
    auto opt_help = false;
    vector<const char*> path_list;

    auto argi = 1;
    while (argi < argc) {
        auto arg = argv[argi++];
        if (string("--help") == arg) {
            opt_help = true;
        } else if (string("--ast") == arg) {
            opt_ast = true;
        } else if (string("--optimize_ast_nodes") == arg || string("--opt") == arg) {
            opt_optimize_ast_nodes = true;
        } else {
            path_list.push_back(arg);
        }
    }

    if (path_list.empty() || opt_help) {
        cerr << "usage: peglint [--ast] [--optimize_ast_nodes|--opt] [grammar file path] [source file path]" << endl;
        return 1;
    }

    // Check PEG grammar
    auto syntax_path = path_list[0];

    vector<char> syntax;
    if (!read_file(syntax_path, syntax)) {
        cerr << "can't open the grammar file." << endl;
        return -1;
    }

    peglib::peg peg;

    peg.log = [&](auto ln, auto col, const auto& msg) {
        cerr << syntax_path << ":" << ln << ":" << col << ": " << msg << endl;
    };

    if (!peg.load_grammar(syntax.data(), syntax.size())) {
        return -1;
    }

    if (path_list.size() < 2) {
        return 0;
    }

    // Check source
    auto source_path = path_list[1];

    vector<char> source;
    if (!read_file(source_path, source)) {
        auto beg = source_path;
        auto end = source_path + strlen(source_path);
        source.assign(beg, end);
        source_path = "[commendline]";
    }

    peg.log = [&](auto ln, auto col, const auto& msg) {
        cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl;
    };

    if (opt_ast) {
	    peg.enable_ast(opt_optimize_ast_nodes);

	    std::shared_ptr<peglib::Ast> ast;
	    if (!peg.parse_n(source.data(), source.size(), ast)) {
	        return -1;
	    }

	    peglib::AstPrint().print(*ast);
    } else {
	    if (!peg.parse_n(source.data(), source.size())) {
	        return -1;
	    }
    }

    return 0;
}

// vim: et ts=4 sw=4 cin cino={1s ff=unix
<|endoftext|>


<commit_before>/*** tws_util.cpp -- common utils
 *
 * Copyright (C) 2010, 2011 Ruediger Meier
 *
 * Author:  Ruediger Meier <sweet_f_a@gmx.de>
 *
 * This file is part of atem.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the author nor the names of any contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ***/

#include "tws_util.h"
#include "debug.h"

// from global installed twsapi
#include "twsapi/EWrapper.h" //IB::TickType
#include "twsapi/Execution.h"
#include "twsapi/Contract.h"

#include <string.h>
#include <sys/time.h>
#include <time.h>

int64_t nowInMsecs()
{
	timeval tv;
	int err = gettimeofday( &tv, NULL );
	assert( err == 0 );

	const int64_t now_ms = (int64_t)(tv.tv_sec*1000ULL) + (int64_t)(tv.tv_usec/1000ULL);
	return now_ms;
}

std::string msecs_to_string( int64_t msecs )
{
	const time_t s = msecs / 1000;
	const uint ms = msecs % 1000;
	char buf[ 19 + 4 + 1 ]; // "yyyy-mm-dd hh:mm:ss.zzz"
	const struct tm *tmp_tm = localtime( &s );
	size_t tmp_sz;

	tmp_sz = strftime(buf, 19+1 , "%F %T", tmp_tm);
	assert( tmp_sz == 19);
	tmp_sz = snprintf( buf+19, 4+1, ".%03u", ms );
	assert( tmp_sz == 4);

	return std::string(buf);
}

/**
 * Convert IB style date or date time string to struct tm.
 * Return 0 on success or -1 on error;
 */
int ib_strptime( struct tm *tm, const std::string &ib_datetime )
{
	char *tmp;

	memset(tm, 0, sizeof(struct tm));
	tmp = strptime( ib_datetime.c_str(), "%Y%m%d", tm);
	if( tmp != NULL && *tmp == '\0' ) {
		return 0;
	}

	memset(tm, 0, sizeof(struct tm));
	tmp = strptime( ib_datetime.c_str(), "%Y%m%d%t%H:%M:%S", tm);
	if(  tmp != NULL && *tmp == '\0' ) {
		return 0;
	}
	return -1;
}

std::string ib_date2iso( const std::string &ibDate )
{
	struct tm tm;
	char buf[255];
	char *tmp;

	memset(&tm, 0, sizeof(struct tm));
	tmp = strptime( ibDate.c_str(), "%Y%m%d", &tm);
	if( tmp != NULL && *tmp == '\0' ) {
		strftime(buf, sizeof(buf), "%F", &tm);
		return buf;
	}

	memset(&tm, 0, sizeof(struct tm));
	tmp = strptime( ibDate.c_str(), "%Y%m%d%t%H:%M:%S", &tm);
	if(  tmp != NULL && *tmp == '\0' ) {
		strftime(buf, sizeof(buf), "%F %T", &tm);
		return buf;
	}

	return "";
}

std::string ibToString( int tickType) {
	switch ( tickType) {
		case IB::BID_SIZE:                    return "bidSize";
		case IB::BID:                         return "bidPrice";
		case IB::ASK:                         return "askPrice";
		case IB::ASK_SIZE:                    return "askSize";
		case IB::LAST:                        return "lastPrice";
		case IB::LAST_SIZE:                   return "lastSize";
		case IB::HIGH:                        return "high";
		case IB::LOW:                         return "low";
		case IB::VOLUME:                      return "volume";
		case IB::CLOSE:                       return "close";
		case IB::BID_OPTION_COMPUTATION:      return "bidOptComp";
		case IB::ASK_OPTION_COMPUTATION:      return "askOptComp";
		case IB::LAST_OPTION_COMPUTATION:     return "lastOptComp";
		case IB::MODEL_OPTION:                return "modelOptComp";
		case IB::OPEN:                        return "open";
		case IB::LOW_13_WEEK:                 return "13WeekLow";
		case IB::HIGH_13_WEEK:                return "13WeekHigh";
		case IB::LOW_26_WEEK:                 return "26WeekLow";
		case IB::HIGH_26_WEEK:                return "26WeekHigh";
		case IB::LOW_52_WEEK:                 return "52WeekLow";
		case IB::HIGH_52_WEEK:                return "52WeekHigh";
		case IB::AVG_VOLUME:                  return "AvgVolume";
		case IB::OPEN_INTEREST:               return "OpenInterest";
		case IB::OPTION_HISTORICAL_VOL:       return "OptionHistoricalVolatility";
		case IB::OPTION_IMPLIED_VOL:          return "OptionImpliedVolatility";
		case IB::OPTION_BID_EXCH:             return "OptionBidExchStr";
		case IB::OPTION_ASK_EXCH:             return "OptionAskExchStr";
		case IB::OPTION_CALL_OPEN_INTEREST:   return "OptionCallOpenInterest";
		case IB::OPTION_PUT_OPEN_INTEREST:    return "OptionPutOpenInterest";
		case IB::OPTION_CALL_VOLUME:          return "OptionCallVolume";
		case IB::OPTION_PUT_VOLUME:           return "OptionPutVolume";
		case IB::INDEX_FUTURE_PREMIUM:        return "IndexFuturePremium";
		case IB::BID_EXCH:                    return "bidExch";
		case IB::ASK_EXCH:                    return "askExch";
		case IB::AUCTION_VOLUME:              return "auctionVolume";
		case IB::AUCTION_PRICE:               return "auctionPrice";
		case IB::AUCTION_IMBALANCE:           return "auctionImbalance";
		case IB::MARK_PRICE:                  return "markPrice";
		case IB::BID_EFP_COMPUTATION:         return "bidEFP";
		case IB::ASK_EFP_COMPUTATION:         return "askEFP";
		case IB::LAST_EFP_COMPUTATION:        return "lastEFP";
		case IB::OPEN_EFP_COMPUTATION:        return "openEFP";
		case IB::HIGH_EFP_COMPUTATION:        return "highEFP";
		case IB::LOW_EFP_COMPUTATION:         return "lowEFP";
		case IB::CLOSE_EFP_COMPUTATION:       return "closeEFP";
		case IB::LAST_TIMESTAMP:              return "lastTimestamp";
		case IB::SHORTABLE:                   return "shortable";
		case IB::FUNDAMENTAL_RATIOS:          return "fundamentals";
		case IB::RT_VOLUME:                   return "rtVolume";
		case IB::HALTED:                      return "halted";
		default:                          return "unknown";
	}
}

std::string ibToString( const IB::Execution& ex )
{
	char buf[1024];
	snprintf( buf, sizeof(buf), "orderId:%ld: clientId:%ld, execId:%s, "
		"time:%s, acctNumber:%s, exchange:%s, side:%s, shares:%d, price:%g, "
		"permId:%d, liquidation:%d, cumQty:%d, avgPrice:%g",
		ex.orderId, ex.clientId, ex.execId.c_str(), ex.time.c_str(),
		ex.acctNumber.c_str(), ex.exchange.c_str(), ex.side.c_str(),
		ex.shares, ex.price, ex.permId, ex.liquidation, ex.cumQty, ex.avgPrice);
	return std::string(buf);
}

std::string ibToString( const IB::Contract &c, bool showFields )
{
	char buf[1024];
	const char *fmt;

	if( showFields ) {
		fmt = "conId:%ld, symbol:%s, secType:%s, expiry:%s, strike:%g, "
		"right:%s, multiplier:%s, exchange:%s, currency:%s, localSymbol:%s";
	} else {
		fmt = "%ld,%s,%s,%s,%g,%s,%s,%s,%s,%s";
	}
	snprintf( buf, sizeof(buf), fmt,
		c.conId, c.symbol.c_str(), c.secType.c_str(),
		c.expiry.c_str(), c.strike, c.right.c_str(),
		c.multiplier.c_str(), c.exchange.c_str(), c.currency.c_str(),
		c.localSymbol.c_str() );

	return std::string(buf);
}

<commit_msg>ib_date2iso(), add comment and avoid magic buf length<commit_after>/*** tws_util.cpp -- common utils
 *
 * Copyright (C) 2010, 2011 Ruediger Meier
 *
 * Author:  Ruediger Meier <sweet_f_a@gmx.de>
 *
 * This file is part of atem.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the author nor the names of any contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ***/

#include "tws_util.h"
#include "debug.h"

// from global installed twsapi
#include "twsapi/EWrapper.h" //IB::TickType
#include "twsapi/Execution.h"
#include "twsapi/Contract.h"

#include <string.h>
#include <sys/time.h>
#include <time.h>

int64_t nowInMsecs()
{
	timeval tv;
	int err = gettimeofday( &tv, NULL );
	assert( err == 0 );

	const int64_t now_ms = (int64_t)(tv.tv_sec*1000ULL) + (int64_t)(tv.tv_usec/1000ULL);
	return now_ms;
}

std::string msecs_to_string( int64_t msecs )
{
	const time_t s = msecs / 1000;
	const uint ms = msecs % 1000;
	char buf[ 19 + 4 + 1 ]; // "yyyy-mm-dd hh:mm:ss.zzz"
	const struct tm *tmp_tm = localtime( &s );
	size_t tmp_sz;

	tmp_sz = strftime(buf, 19+1 , "%F %T", tmp_tm);
	assert( tmp_sz == 19);
	tmp_sz = snprintf( buf+19, 4+1, ".%03u", ms );
	assert( tmp_sz == 4);

	return std::string(buf);
}

/**
 * Convert IB style date or date time string to struct tm.
 * Return 0 on success or -1 on error;
 */
int ib_strptime( struct tm *tm, const std::string &ib_datetime )
{
	char *tmp;

	memset(tm, 0, sizeof(struct tm));
	tmp = strptime( ib_datetime.c_str(), "%Y%m%d", tm);
	if( tmp != NULL && *tmp == '\0' ) {
		return 0;
	}

	memset(tm, 0, sizeof(struct tm));
	tmp = strptime( ib_datetime.c_str(), "%Y%m%d%t%H:%M:%S", tm);
	if(  tmp != NULL && *tmp == '\0' ) {
		return 0;
	}
	return -1;
}

/**
 * Convert IB style date or date time string to standard format "%F" or "%F %T".
 * The converted string is always a valid date.
 * Return empty string on parse errors or invalid dates.
 */
std::string ib_date2iso( const std::string &ibDate )
{
	struct tm tm;
	char buf[sizeof("yyyy-mm-dd HH:MM:SS")];
	char *tmp;

	memset(&tm, 0, sizeof(struct tm));
	tmp = strptime( ibDate.c_str(), "%Y%m%d", &tm);
	if( tmp != NULL && *tmp == '\0' ) {
		strftime(buf, sizeof(buf), "%F", &tm);
		return buf;
	}

	memset(&tm, 0, sizeof(struct tm));
	tmp = strptime( ibDate.c_str(), "%Y%m%d%t%H:%M:%S", &tm);
	if(  tmp != NULL && *tmp == '\0' ) {
		strftime(buf, sizeof(buf), "%F %T", &tm);
		return buf;
	}

	return "";
}

std::string ibToString( int tickType) {
	switch ( tickType) {
		case IB::BID_SIZE:                    return "bidSize";
		case IB::BID:                         return "bidPrice";
		case IB::ASK:                         return "askPrice";
		case IB::ASK_SIZE:                    return "askSize";
		case IB::LAST:                        return "lastPrice";
		case IB::LAST_SIZE:                   return "lastSize";
		case IB::HIGH:                        return "high";
		case IB::LOW:                         return "low";
		case IB::VOLUME:                      return "volume";
		case IB::CLOSE:                       return "close";
		case IB::BID_OPTION_COMPUTATION:      return "bidOptComp";
		case IB::ASK_OPTION_COMPUTATION:      return "askOptComp";
		case IB::LAST_OPTION_COMPUTATION:     return "lastOptComp";
		case IB::MODEL_OPTION:                return "modelOptComp";
		case IB::OPEN:                        return "open";
		case IB::LOW_13_WEEK:                 return "13WeekLow";
		case IB::HIGH_13_WEEK:                return "13WeekHigh";
		case IB::LOW_26_WEEK:                 return "26WeekLow";
		case IB::HIGH_26_WEEK:                return "26WeekHigh";
		case IB::LOW_52_WEEK:                 return "52WeekLow";
		case IB::HIGH_52_WEEK:                return "52WeekHigh";
		case IB::AVG_VOLUME:                  return "AvgVolume";
		case IB::OPEN_INTEREST:               return "OpenInterest";
		case IB::OPTION_HISTORICAL_VOL:       return "OptionHistoricalVolatility";
		case IB::OPTION_IMPLIED_VOL:          return "OptionImpliedVolatility";
		case IB::OPTION_BID_EXCH:             return "OptionBidExchStr";
		case IB::OPTION_ASK_EXCH:             return "OptionAskExchStr";
		case IB::OPTION_CALL_OPEN_INTEREST:   return "OptionCallOpenInterest";
		case IB::OPTION_PUT_OPEN_INTEREST:    return "OptionPutOpenInterest";
		case IB::OPTION_CALL_VOLUME:          return "OptionCallVolume";
		case IB::OPTION_PUT_VOLUME:           return "OptionPutVolume";
		case IB::INDEX_FUTURE_PREMIUM:        return "IndexFuturePremium";
		case IB::BID_EXCH:                    return "bidExch";
		case IB::ASK_EXCH:                    return "askExch";
		case IB::AUCTION_VOLUME:              return "auctionVolume";
		case IB::AUCTION_PRICE:               return "auctionPrice";
		case IB::AUCTION_IMBALANCE:           return "auctionImbalance";
		case IB::MARK_PRICE:                  return "markPrice";
		case IB::BID_EFP_COMPUTATION:         return "bidEFP";
		case IB::ASK_EFP_COMPUTATION:         return "askEFP";
		case IB::LAST_EFP_COMPUTATION:        return "lastEFP";
		case IB::OPEN_EFP_COMPUTATION:        return "openEFP";
		case IB::HIGH_EFP_COMPUTATION:        return "highEFP";
		case IB::LOW_EFP_COMPUTATION:         return "lowEFP";
		case IB::CLOSE_EFP_COMPUTATION:       return "closeEFP";
		case IB::LAST_TIMESTAMP:              return "lastTimestamp";
		case IB::SHORTABLE:                   return "shortable";
		case IB::FUNDAMENTAL_RATIOS:          return "fundamentals";
		case IB::RT_VOLUME:                   return "rtVolume";
		case IB::HALTED:                      return "halted";
		default:                          return "unknown";
	}
}

std::string ibToString( const IB::Execution& ex )
{
	char buf[1024];
	snprintf( buf, sizeof(buf), "orderId:%ld: clientId:%ld, execId:%s, "
		"time:%s, acctNumber:%s, exchange:%s, side:%s, shares:%d, price:%g, "
		"permId:%d, liquidation:%d, cumQty:%d, avgPrice:%g",
		ex.orderId, ex.clientId, ex.execId.c_str(), ex.time.c_str(),
		ex.acctNumber.c_str(), ex.exchange.c_str(), ex.side.c_str(),
		ex.shares, ex.price, ex.permId, ex.liquidation, ex.cumQty, ex.avgPrice);
	return std::string(buf);
}

std::string ibToString( const IB::Contract &c, bool showFields )
{
	char buf[1024];
	const char *fmt;

	if( showFields ) {
		fmt = "conId:%ld, symbol:%s, secType:%s, expiry:%s, strike:%g, "
		"right:%s, multiplier:%s, exchange:%s, currency:%s, localSymbol:%s";
	} else {
		fmt = "%ld,%s,%s,%s,%g,%s,%s,%s,%s,%s";
	}
	snprintf( buf, sizeof(buf), fmt,
		c.conId, c.symbol.c_str(), c.secType.c_str(),
		c.expiry.c_str(), c.strike, c.right.c_str(),
		c.multiplier.c_str(), c.exchange.c_str(), c.currency.c_str(),
		c.localSymbol.c_str() );

	return std::string(buf);
}

<|endoftext|>