<commit_before>#pragma once

#if defined(__x86_64__)
#include <immintrin.h>
#endif

namespace pthash::util {

template <typename T>
inline void prefetch(T const* ptr) {
#if defined(__x86_64__)
    _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0);
#endif
}

inline uint8_t msb(uint64_t x) {
    assert(x);
    unsigned long ret = -1U;
    if (x) { ret = (unsigned long)(63 - __builtin_clzll(x)); }
    return (uint8_t)ret;
}

inline bool bsr64(unsigned long* const index, const uint64_t mask) {
    if (mask) {
        *index = (unsigned long)(63 - __builtin_clzll(mask));
        return true;
    } else {
        return false;
    }
}

inline uint8_t msb(uint64_t x, unsigned long& ret) {
    return bsr64(&ret, x);
}

inline uint8_t lsb(uint64_t x, unsigned long& ret) {
    if (x) {
        ret = (unsigned long)__builtin_ctzll(x);
        return true;
    }
    return false;
}

inline uint8_t lsb(uint64_t x) {
    assert(x);
    unsigned long ret = -1U;
    lsb(x, ret);
    return (uint8_t)ret;
}

inline uint64_t popcount(uint64_t x) {
#ifdef __SSE4_2__
    return static_cast<uint64_t>(_mm_popcnt_u64(x));
#else
    return std::popcount(x);
#endif
}

inline uint64_t select64(uint64_t x, uint64_t k) {
#ifndef __BMI2__
    // Modified from: Bit Twiddling Hacks
    // https://graphics.stanford.edu/~seander/bithacks.html#SelectPosFromMSBRank
    unsigned int s;      // Output: Resulting position of bit with rank r [1-64]
    uint64_t a, b, c, d; // Intermediate temporaries for bit count.
    unsigned int t;      // Bit count temporary.
    k = popcount(x) - k;

    a =  x - ((x >> 1) & ~0UL/3);
    b = (a & ~0UL/5) + ((a >> 2) & ~0UL/5);
    c = (b + (b >> 4)) & ~0UL/0x11;
    d = (c + (c >> 8)) & ~0UL/0x101;
    t = (d >> 32) + (d >> 48);
    s  = 64;
    s -= ((t - k) & 256) >> 3; k -= (t & ((t - k) >> 8));
    t  = (d >> (s - 16)) & 0xff;
    s -= ((t - k) & 256) >> 4; k -= (t & ((t - k) >> 8));
    t  = (c >> (s - 8)) & 0xf;
    s -= ((t - k) & 256) >> 5; k -= (t & ((t - k) >> 8));
    t  = (b >> (s - 4)) & 0x7;
    s -= ((t - k) & 256) >> 6; k -= (t & ((t - k) >> 8));
    t  = (a >> (s - 2)) & 0x3;
    s -= ((t - k) & 256) >> 7; k -= (t & ((t - k) >> 8));
    t  = (x >> (s - 1)) & 0x1;
    s -= ((t - k) & 256) >> 8;
    return s - 1;
#else
    uint64_t i = 1ULL << k;
    asm("pdep %[x], %[mask], %[x]" : [x] "+r"(x) : [mask] "r"(i));
    asm("tzcnt %[bit], %[index]" : [index] "=r"(i) : [bit] "g"(x) : "cc");
    return i;
#endif
}

inline uint64_t select_in_word(const uint64_t x, const uint64_t k) {
    assert(k < popcount(x));
    return select64(x, k);
}

}  // namespace pthash::util<commit_msg>popcount defaults to __builtin_popcountll for ARM processors without c++ 2020<commit_after>#pragma once

#if defined(__x86_64__)
#include <immintrin.h>
#endif

namespace pthash::util {

template <typename T>
inline void prefetch(T const* ptr) {
#if defined(__x86_64__)
    _mm_prefetch(reinterpret_cast<const char*>(ptr), _MM_HINT_T0);
#endif
}

inline uint8_t msb(uint64_t x) {
    assert(x);
    unsigned long ret = -1U;
    if (x) { ret = (unsigned long)(63 - __builtin_clzll(x)); }
    return (uint8_t)ret;
}

inline bool bsr64(unsigned long* const index, const uint64_t mask) {
    if (mask) {
        *index = (unsigned long)(63 - __builtin_clzll(mask));
        return true;
    } else {
        return false;
    }
}

inline uint8_t msb(uint64_t x, unsigned long& ret) {
    return bsr64(&ret, x);
}

inline uint8_t lsb(uint64_t x, unsigned long& ret) {
    if (x) {
        ret = (unsigned long)__builtin_ctzll(x);
        return true;
    }
    return false;
}

inline uint8_t lsb(uint64_t x) {
    assert(x);
    unsigned long ret = -1U;
    lsb(x, ret);
    return (uint8_t)ret;
}

inline uint64_t popcount(uint64_t x) {
#ifdef __SSE4_2__
    return static_cast<uint64_t>(_mm_popcnt_u64(x));
#elif __cplusplus >= 202002L
    return std::popcount(x);
#else
    return static_cast<uint64_t>(__builtin_popcountll(x));
#endif
}

inline uint64_t select64(uint64_t x, uint64_t k) {
#ifndef __BMI2__
    // Modified from: Bit Twiddling Hacks
    // https://graphics.stanford.edu/~seander/bithacks.html#SelectPosFromMSBRank
    unsigned int s;       // Output: Resulting position of bit with rank r [1-64]
    uint64_t a, b, c, d;  // Intermediate temporaries for bit count.
    unsigned int t;       // Bit count temporary.
    k = popcount(x) - k;

    a = x - ((x >> 1) & ~0UL / 3);
    b = (a & ~0UL / 5) + ((a >> 2) & ~0UL / 5);
    c = (b + (b >> 4)) & ~0UL / 0x11;
    d = (c + (c >> 8)) & ~0UL / 0x101;
    t = (d >> 32) + (d >> 48);
    s = 64;
    s -= ((t - k) & 256) >> 3;
    k -= (t & ((t - k) >> 8));
    t = (d >> (s - 16)) & 0xff;
    s -= ((t - k) & 256) >> 4;
    k -= (t & ((t - k) >> 8));
    t = (c >> (s - 8)) & 0xf;
    s -= ((t - k) & 256) >> 5;
    k -= (t & ((t - k) >> 8));
    t = (b >> (s - 4)) & 0x7;
    s -= ((t - k) & 256) >> 6;
    k -= (t & ((t - k) >> 8));
    t = (a >> (s - 2)) & 0x3;
    s -= ((t - k) & 256) >> 7;
    k -= (t & ((t - k) >> 8));
    t = (x >> (s - 1)) & 0x1;
    s -= ((t - k) & 256) >> 8;
    return s - 1;
#else
    uint64_t i = 1ULL << k;
    asm("pdep %[x], %[mask], %[x]" : [ x ] "+r"(x) : [ mask ] "r"(i));
    asm("tzcnt %[bit], %[index]" : [ index ] "=r"(i) : [ bit ] "g"(x) : "cc");
    return i;
#endif
}

inline uint64_t select_in_word(const uint64_t x, const uint64_t k) {
    assert(k < popcount(x));
    return select64(x, k);
}

}  // namespace pthash::util<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file types.hpp
 * \date June 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__UTIL__TYPES_HPP
#define FL__UTIL__TYPES_HPP

#include <Eigen/Dense>

namespace fl
{

#if defined(fl_USE_FLOAT)
    typedef float FloatingPoint;
#elif defined(fl_USE_DOUBLE)
    typedef double FloatingPoint;
#elif defined(fl_USE_LONG_DOUBLE)
    typedef long double FloatingPoint;
#else
    typedef double FloatingPoint;
#endif

/**
 * \ingroup types
 * \brief Common floating point type. The default type of Real is \c double.
 *        This type is used throughout the entire ::fl library.
 *
 * In order or use other basic floating point types please compile with one of
 * the following defines:
 *
 *  - \c FL_USE_FLOAT:       defines fl::Real as \c float
 *  - \c FL_USE_DOUBLE:      defines fl::Real as \c double (default)
 *  - \c FL_USE_LONG_DOUBLE: defines fl::Real as \c long double
 */
typedef FloatingPoint Real;

/**
 * \ingroup types
 */
template <typename Model_> struct Additive
{
    typedef Model_ Model;
};

/**
 * \ingroup types
 */
template <typename Model_> struct AdditiveUncorrelated
{
    typedef Model_ Model;
};

/**
 * \ingroup types
 */
template <typename Model_> struct NonAdditive
{
    typedef Model_ Model;
};

/**
 * \internal
 */
namespace internal
{

/**
 * \internal
 * \ingroup types
 *
 * \brief Observation model type identifier
 */
struct ObsrvModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Process model type identifier
 */
struct ProcessModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Adaptive model type identifier
 */
struct AdaptiveModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Represents the base type of any model with additive noise term
 * \f$ x_{t+1} = f(x_t) + v_t\f$ while \f$v_t\f$ is the additive noise.
 */
struct AdditiveModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Represents the base type of any model with additive uncorrelated
 * Gaussian white noise term in \f$ x_{t+1} = f(x_t) + v_t\f$ while \f$v_t\f$ is
 * the additive noise with \f$v_t \sim {\cal N}(v_t; 0, Q_t)\f$. Here, the
 * covariance matrix has a diagonal form \f$Q_t = \text{diag}(q_1, q_2, \ldots,
 * q_n)\f$ and \f$n\f$ is the dimension of \f$v_t \in \mathbb{R}^n\f$.
 */
struct AdditiveUncorrelatedModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Represents the base type of any model with non-additive noise term
 * \f$ x_{t+1} = f(x_t, v_t) \f$ while \f$v_t\f$ is the additive noise.
 */
struct NonAdditiveModelType { };

}

}

#endif
<commit_msg>Added LinearModel type identifier<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file types.hpp
 * \date June 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__UTIL__TYPES_HPP
#define FL__UTIL__TYPES_HPP

#include <Eigen/Dense>

namespace fl
{

#if defined(fl_USE_FLOAT)
    typedef float FloatingPoint;
#elif defined(fl_USE_DOUBLE)
    typedef double FloatingPoint;
#elif defined(fl_USE_LONG_DOUBLE)
    typedef long double FloatingPoint;
#else
    typedef double FloatingPoint;
#endif

/**
 * \ingroup types
 * \brief Common floating point type. The default type of Real is \c double.
 *        This type is used throughout the entire ::fl library.
 *
 * In order or use other basic floating point types please compile with one of
 * the following defines:
 *
 *  - \c FL_USE_FLOAT:       defines fl::Real as \c float
 *  - \c FL_USE_DOUBLE:      defines fl::Real as \c double (default)
 *  - \c FL_USE_LONG_DOUBLE: defines fl::Real as \c long double
 */
typedef FloatingPoint Real;

/**
 * \ingroup types
 */
template <typename Model_> struct Additive
{
    typedef Model_ Model;
};

/**
 * \ingroup types
 */
template <typename Model_> struct AdditiveUncorrelated
{
    typedef Model_ Model;
};

/**
 * \ingroup types
 */
template <typename Model_> struct NonAdditive
{
    typedef Model_ Model;
};

/**
 * \internal
 */
namespace internal
{

/**
 * \internal
 * \ingroup types
 *
 * \brief Linear model type identifier
 */
struct LinearModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Observation model type identifier
 */
struct ObsrvModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Process model type identifier
 */
struct ProcessModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Adaptive model type identifier
 */
struct AdaptiveModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Represents the base type of any model with additive noise term
 * \f$ x_{t+1} = f(x_t) + v_t\f$ while \f$v_t\f$ is the additive noise.
 */
struct AdditiveNoiseModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Represents the base type of any model with additive uncorrelated
 * Gaussian white noise term in \f$ x_{t+1} = f(x_t) + v_t\f$ while \f$v_t\f$ is
 * the additive noise with \f$v_t \sim {\cal N}(v_t; 0, Q_t)\f$. Here, the
 * covariance matrix has a diagonal form \f$Q_t = \text{diag}(q_1, q_2, \ldots,
 * q_n)\f$ and \f$n\f$ is the dimension of \f$v_t \in \mathbb{R}^n\f$.
 */
struct AdditiveUncorrelatedNoiseModelType { };

/**
 * \internal
 * \ingroup types
 *
 * \brief Represents the base type of any model with non-additive noise term
 * \f$ x_{t+1} = f(x_t, v_t) \f$ while \f$v_t\f$ is the additive noise.
 */
struct NonAdditiveNoiseModelType { };

}

}

#endif
<|endoftext|>


<commit_before>/*
===============================================================================

  FILE:  laszip.hpp

  CONTENTS:

    Contains LASitem and LASchunk structs as well as the IDs of the currently
    supported entropy coding scheme

  PROGRAMMERS:

    martin.isenburg@gmail.com

  COPYRIGHT:

    (c) 2007-2011, Martin Isenburg, LASSO - tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    6 October 2011 -- large file support, ability to read with missing chunk table
    23 June 2011 -- turned on LASzip version 2.0 compressor with chunking
    8 May 2011 -- added an option for variable chunking via chunk()
    23 April 2011 -- changed interface for simplicity and chunking support
    20 March 2011 -- incrementing LASZIP_VERSION to 1.2 for improved compression
    10 January 2011 -- licensing change for LGPL release and liblas integration
    12 December 2010 -- refactored from lasdefinitions after movies with silke

===============================================================================
*/
#ifndef LASZIP_HPP
#define LASZIP_HPP

#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define LZ_WIN32_VC6
typedef __int64   SIGNED_INT64;
#else
typedef long long SIGNED_INT64;
#endif

#if defined(_MSC_VER) && \
    (_MSC_FULL_VER >= 150000000)
#define LASCopyString _strdup
#else
#define LASCopyString strdup
#endif

#define LASZIP_VERSION_MAJOR    2
#define LASZIP_VERSION_MINOR    0
#define LASZIP_VERSION_REVISION 2

#define LASZIP_COMPRESSOR_NONE              0
#define LASZIP_COMPRESSOR_POINTWISE         1
#define LASZIP_COMPRESSOR_POINTWISE_CHUNKED 2
#define LASZIP_COMPRESSOR_TOTAL_NUMBER_OF   3

#define LASZIP_COMPRESSOR_CHUNKED LASZIP_COMPRESSOR_POINTWISE_CHUNKED
#define LASZIP_COMPRESSOR_NOT_CHUNKED LASZIP_COMPRESSOR_POINTWISE

#define LASZIP_COMPRESSOR_DEFAULT LASZIP_COMPRESSOR_CHUNKED

#define LASZIP_CODER_ARITHMETIC             0
#define LASZIP_CODER_TOTAL_NUMBER_OF        1

#define LASZIP_CHUNK_SIZE_DEFAULT           50000

#include "laszipexport.hpp"

class LASitem
{
public:
  enum Type { BYTE = 0, SHORT, INT, LONG, FLOAT, DOUBLE, POINT10, GPSTIME11, RGB12, WAVEPACKET13 } type;
  unsigned short size;
  unsigned short version;
  bool is_type(LASitem::Type t) const;
  const char* get_name() const;
};

class LASZIP_DLL LASzip
{
public:

  // supported version control
  bool check_compressor(const unsigned short compressor);
  bool check_coder(const unsigned short coder);
  bool check_item(const LASitem* item);
  bool check_items(const unsigned short num_items, const LASitem* items);
  bool check();

  // go back and forth between item array and point type & size
  bool setup(unsigned short* num_items, LASitem** items, const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_NONE);
  bool is_standard(const unsigned short num_items, const LASitem* items, unsigned char* point_type=0, unsigned short* record_length=0);
  bool is_standard(unsigned char* point_type=0, unsigned short* record_length=0);

  // pack to and unpack from VLR
  unsigned char* bytes;
  bool unpack(const unsigned char* bytes, const int num);
  bool pack(unsigned char*& bytes, int& num);

  // setup
  bool setup(const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
  bool setup(const unsigned short num_items, const LASitem* items, const unsigned short compressor);
  bool set_chunk_size(const unsigned int chunk_size);             /* for compressor only */
  bool request_version(const unsigned short requested_version);   /* for compressor only */

  // in case a function returns false this string describes the problem
  const char* get_error() const;

  // stored in LASzip VLR data section
  unsigned short compressor;
  unsigned short coder;
  unsigned char version_major;
  unsigned char version_minor;
  unsigned short version_revision;
  unsigned int options;
  unsigned int chunk_size;
  SIGNED_INT64 num_points;  /* not mandatory ... -1 if unknown */
  SIGNED_INT64 num_bytes;   /* not mandatory ... -1 if unknown */
  unsigned short num_items;
  LASitem* items;

  LASzip();
  ~LASzip();

private:
  bool return_error(const char* err);
  char* error_string;
};

#endif
<commit_msg>win32 dll fix<commit_after>/*
===============================================================================

  FILE:  laszip.hpp

  CONTENTS:

    Contains LASitem and LASchunk structs as well as the IDs of the currently
    supported entropy coding scheme

  PROGRAMMERS:

    martin.isenburg@gmail.com

  COPYRIGHT:

    (c) 2007-2011, Martin Isenburg, LASSO - tools to catch reality

    This is free software; you can redistribute and/or modify it under the
    terms of the GNU Lesser General Licence as published by the Free Software
    Foundation. See the COPYING file for more information.

    This software is distributed WITHOUT ANY WARRANTY and without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  CHANGE HISTORY:

    6 October 2011 -- large file support, ability to read with missing chunk table
    23 June 2011 -- turned on LASzip version 2.0 compressor with chunking
    8 May 2011 -- added an option for variable chunking via chunk()
    23 April 2011 -- changed interface for simplicity and chunking support
    20 March 2011 -- incrementing LASZIP_VERSION to 1.2 for improved compression
    10 January 2011 -- licensing change for LGPL release and liblas integration
    12 December 2010 -- refactored from lasdefinitions after movies with silke

===============================================================================
*/
#ifndef LASZIP_HPP
#define LASZIP_HPP

#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define LZ_WIN32_VC6
typedef __int64   SIGNED_INT64;
#else
typedef long long SIGNED_INT64;
#endif

#if defined(_MSC_VER) && \
    (_MSC_FULL_VER >= 150000000)
#define LASCopyString _strdup
#else
#define LASCopyString strdup
#endif

#define LASZIP_VERSION_MAJOR    2
#define LASZIP_VERSION_MINOR    0
#define LASZIP_VERSION_REVISION 2

#define LASZIP_COMPRESSOR_NONE              0
#define LASZIP_COMPRESSOR_POINTWISE         1
#define LASZIP_COMPRESSOR_POINTWISE_CHUNKED 2
#define LASZIP_COMPRESSOR_TOTAL_NUMBER_OF   3

#define LASZIP_COMPRESSOR_CHUNKED LASZIP_COMPRESSOR_POINTWISE_CHUNKED
#define LASZIP_COMPRESSOR_NOT_CHUNKED LASZIP_COMPRESSOR_POINTWISE

#define LASZIP_COMPRESSOR_DEFAULT LASZIP_COMPRESSOR_CHUNKED

#define LASZIP_CODER_ARITHMETIC             0
#define LASZIP_CODER_TOTAL_NUMBER_OF        1

#define LASZIP_CHUNK_SIZE_DEFAULT           50000

#include "laszipexport.hpp"

class LASZIP_DLL LASitem
{
public:
  enum Type { BYTE = 0, SHORT, INT, LONG, FLOAT, DOUBLE, POINT10, GPSTIME11, RGB12, WAVEPACKET13 } type;
  unsigned short size;
  unsigned short version;
  bool is_type(LASitem::Type t) const;
  const char* get_name() const;
};

class LASZIP_DLL LASzip
{
public:

  // supported version control
  bool check_compressor(const unsigned short compressor);
  bool check_coder(const unsigned short coder);
  bool check_item(const LASitem* item);
  bool check_items(const unsigned short num_items, const LASitem* items);
  bool check();

  // go back and forth between item array and point type & size
  bool setup(unsigned short* num_items, LASitem** items, const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_NONE);
  bool is_standard(const unsigned short num_items, const LASitem* items, unsigned char* point_type=0, unsigned short* record_length=0);
  bool is_standard(unsigned char* point_type=0, unsigned short* record_length=0);

  // pack to and unpack from VLR
  unsigned char* bytes;
  bool unpack(const unsigned char* bytes, const int num);
  bool pack(unsigned char*& bytes, int& num);

  // setup
  bool setup(const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
  bool setup(const unsigned short num_items, const LASitem* items, const unsigned short compressor);
  bool set_chunk_size(const unsigned int chunk_size);             /* for compressor only */
  bool request_version(const unsigned short requested_version);   /* for compressor only */

  // in case a function returns false this string describes the problem
  const char* get_error() const;

  // stored in LASzip VLR data section
  unsigned short compressor;
  unsigned short coder;
  unsigned char version_major;
  unsigned char version_minor;
  unsigned short version_revision;
  unsigned int options;
  unsigned int chunk_size;
  SIGNED_INT64 num_points;  /* not mandatory ... -1 if unknown */
  SIGNED_INT64 num_bytes;   /* not mandatory ... -1 if unknown */
  unsigned short num_items;
  LASitem* items;

  LASzip();
  ~LASzip();

private:
  bool return_error(const char* err);
  char* error_string;
};

#endif
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <iostream>
#include <memory>
#include <array>
#include <fstream>
#include <sstream>
#include "SDL.h"
#include "proxy_sqrat.hpp"
#include "types.hpp"

namespace Oddlib
{
    class IStream
    {
    public:
        static inline void RegisterScriptBindings();

        enum class ReadMode
        {
            ReadOnly,
            ReadWrite
        };

        static std::vector<u8> ReadAll(IStream& stream)
        {
            const auto oldPos = stream.Pos();
            stream.Seek(0);
            const auto size = stream.Size();

            std::vector<u8> allStreamBytes(size);
            stream.ReadBytes(allStreamBytes.data(), allStreamBytes.size());
            stream.Seek(oldPos);
            return allStreamBytes;
        }

        // Read any fundamental type
        template<class T>
        void Read(T& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only read fundamental types");
            ReadBytes(reinterpret_cast<u8*>(&type), sizeof(type));
        }

        // Read a string
        void Read(std::string& type)
        {
            ReadBytes(reinterpret_cast<u8*>(&type[0]), type.size());
        }

        // Read any vector of fundamental type
        template<class T>
        void Read(std::vector<T>& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only read vectors of fundamental types");
            ReadBytes(reinterpret_cast<u8*>(type.data()), sizeof(T)*type.size());
        }

        // Read any std::array of fundamental type
        template<class T, std::size_t count>
        void Read(std::array<T, count>& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only read vectors of fundamental types");
            ReadBytes(reinterpret_cast<u8*>(type.data()), sizeof(T)*type.size());
        }

        // Read any fixed array of fundamental type
        template<typename T, std::size_t count>
        void Read(T(&value)[count])
        {
            static_assert(std::is_fundamental<T>::value, "Can only read fundamental types");
            ReadBytes(reinterpret_cast<u8*>(&value[0]), sizeof(T)* count);
        }

        // Write any fundamental type
        template<class T>
        void Write(const T& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only write fundamental types");
            WriteBytes(reinterpret_cast<const u8*>(&type), sizeof(type));
        }

        // Write vector of any fundamental type
        template<class T>
        void Write(std::vector<T>& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only write vectors of fundamental types");
            WriteBytes(reinterpret_cast<u8*>(type.data()), sizeof(T)*type.size());
        }

        // Write a string
        void Write(const std::string& type)
        {
            WriteBytes(reinterpret_cast<const u8*>(&type[0]), type.size());
        }

        virtual ~IStream() = default;
        virtual IStream* Clone() = 0;
        virtual IStream* Clone(u32 start, u32 size) = 0;
        virtual void ReadBytes(u8* pDest, size_t destSize) = 0;
        virtual void WriteBytes(const u8* pSrc, size_t srcSize) = 0;
        virtual void Seek(size_t pos) = 0;
        virtual size_t Pos() const = 0;
        virtual size_t Size() const = 0;
        virtual bool AtEnd() const = 0;
        virtual const std::string& Name() const = 0;
        virtual std::string LoadAllToString() = 0;

        // Debug helper to write all of the stream to a file as a binary blob
        bool BinaryDump(const std::string& fileName)
        {
            std::ofstream s;
            s.open(fileName.c_str(), std::ios::binary);
            if (!s.is_open())
            {
                return false;
            }

            auto allStreamBytes = ReadAll(*this);
            s.write(reinterpret_cast<const char*>(allStreamBytes.data()), allStreamBytes.size());
            return true;
        }
    };

    inline u16 ReadU16(IStream& stream)
    {
        u16 ret = 0;
        stream.Read(ret);
        return ret;
    }

    inline u32 ReadU32(IStream& stream)
    {
        u32 ret = 0;
        stream.Read(ret);
        return ret;
    }

    inline u8 ReadU8(IStream& stream)
    {
        u8 ret = 0;
        stream.Read(ret);
        return ret;
    }

    /*static*/ inline void IStream::RegisterScriptBindings()
    {
        Sqrat::Class<IStream, Sqrat::NoConstructor<IStream>> c(Sqrat::DefaultVM::Get(), "IStream");
        c.StaticFunc("ReadU32", &ReadU32);
        c.StaticFunc("ReadU16", &ReadU16);
        Sqrat::RootTable().Bind("IStream", c);
    }

    template<class T = std::ifstream>
    class Stream : public IStream
    {
    public:
        virtual IStream* Clone(u32 start, u32 size) override;
        virtual void ReadBytes(u8* pDest, size_t destSize) override;
        virtual void WriteBytes(const u8* pDest, size_t destSize) override;
        virtual void Seek(size_t pos) override;
        virtual size_t Pos() const override;
        virtual size_t Size() const override;
        virtual bool AtEnd() const override;
        virtual const std::string& Name() const override { return mName; }
        virtual std::string LoadAllToString() override;
    protected:
        Stream() = default;
        mutable std::unique_ptr<T> mStream;
        size_t mSize = 0;
        std::string mName;
    };

    class MemoryStream : public Stream<std::stringstream>
    {
    public:
        explicit MemoryStream(std::vector<u8>&& data);
        virtual IStream* Clone() override;
        virtual IStream* Clone(u32 start, u32 size) override { return Stream<std::stringstream>::Clone(start, size); }
    };

    class FileStream :public Stream<std::fstream>
    {
    public:
        explicit FileStream(const std::string& fileName, ReadMode mode);
        virtual IStream* Clone() override;
        virtual IStream* Clone(u32 start, u32 size) override { return Stream<std::fstream>::Clone(start, size); }
    private:
        ReadMode mMode = IStream::ReadMode::ReadOnly;
    };
}
<commit_msg>allow scripts to call ReadU8<commit_after>#pragma once

#include <vector>
#include <iostream>
#include <memory>
#include <array>
#include <fstream>
#include <sstream>
#include "SDL.h"
#include "proxy_sqrat.hpp"
#include "types.hpp"

namespace Oddlib
{
    class IStream
    {
    public:
        static inline void RegisterScriptBindings();

        enum class ReadMode
        {
            ReadOnly,
            ReadWrite
        };

        static std::vector<u8> ReadAll(IStream& stream)
        {
            const auto oldPos = stream.Pos();
            stream.Seek(0);
            const auto size = stream.Size();

            std::vector<u8> allStreamBytes(size);
            stream.ReadBytes(allStreamBytes.data(), allStreamBytes.size());
            stream.Seek(oldPos);
            return allStreamBytes;
        }

        // Read any fundamental type
        template<class T>
        void Read(T& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only read fundamental types");
            ReadBytes(reinterpret_cast<u8*>(&type), sizeof(type));
        }

        // Read a string
        void Read(std::string& type)
        {
            ReadBytes(reinterpret_cast<u8*>(&type[0]), type.size());
        }

        // Read any vector of fundamental type
        template<class T>
        void Read(std::vector<T>& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only read vectors of fundamental types");
            ReadBytes(reinterpret_cast<u8*>(type.data()), sizeof(T)*type.size());
        }

        // Read any std::array of fundamental type
        template<class T, std::size_t count>
        void Read(std::array<T, count>& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only read vectors of fundamental types");
            ReadBytes(reinterpret_cast<u8*>(type.data()), sizeof(T)*type.size());
        }

        // Read any fixed array of fundamental type
        template<typename T, std::size_t count>
        void Read(T(&value)[count])
        {
            static_assert(std::is_fundamental<T>::value, "Can only read fundamental types");
            ReadBytes(reinterpret_cast<u8*>(&value[0]), sizeof(T)* count);
        }

        // Write any fundamental type
        template<class T>
        void Write(const T& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only write fundamental types");
            WriteBytes(reinterpret_cast<const u8*>(&type), sizeof(type));
        }

        // Write vector of any fundamental type
        template<class T>
        void Write(std::vector<T>& type)
        {
            static_assert(std::is_fundamental<T>::value, "Can only write vectors of fundamental types");
            WriteBytes(reinterpret_cast<u8*>(type.data()), sizeof(T)*type.size());
        }

        // Write a string
        void Write(const std::string& type)
        {
            WriteBytes(reinterpret_cast<const u8*>(&type[0]), type.size());
        }

        virtual ~IStream() = default;
        virtual IStream* Clone() = 0;
        virtual IStream* Clone(u32 start, u32 size) = 0;
        virtual void ReadBytes(u8* pDest, size_t destSize) = 0;
        virtual void WriteBytes(const u8* pSrc, size_t srcSize) = 0;
        virtual void Seek(size_t pos) = 0;
        virtual size_t Pos() const = 0;
        virtual size_t Size() const = 0;
        virtual bool AtEnd() const = 0;
        virtual const std::string& Name() const = 0;
        virtual std::string LoadAllToString() = 0;

        // Debug helper to write all of the stream to a file as a binary blob
        bool BinaryDump(const std::string& fileName)
        {
            std::ofstream s;
            s.open(fileName.c_str(), std::ios::binary);
            if (!s.is_open())
            {
                return false;
            }

            auto allStreamBytes = ReadAll(*this);
            s.write(reinterpret_cast<const char*>(allStreamBytes.data()), allStreamBytes.size());
            return true;
        }
    };

    inline u8 ReadU8(IStream& stream)
    {
        u8 ret = 0;
        stream.Read(ret);
        return ret;
    }

    inline u16 ReadU16(IStream& stream)
    {
        u16 ret = 0;
        stream.Read(ret);
        return ret;
    }

    inline u32 ReadU32(IStream& stream)
    {
        u32 ret = 0;
        stream.Read(ret);
        return ret;
    }

    /*static*/ inline void IStream::RegisterScriptBindings()
    {
        Sqrat::Class<IStream, Sqrat::NoConstructor<IStream>> c(Sqrat::DefaultVM::Get(), "IStream");
        c.StaticFunc("ReadU8", &ReadU8);
        c.StaticFunc("ReadU16", &ReadU16);
        c.StaticFunc("ReadU32", &ReadU32);
        Sqrat::RootTable().Bind("IStream", c);
    }

    template<class T = std::ifstream>
    class Stream : public IStream
    {
    public:
        virtual IStream* Clone(u32 start, u32 size) override;
        virtual void ReadBytes(u8* pDest, size_t destSize) override;
        virtual void WriteBytes(const u8* pDest, size_t destSize) override;
        virtual void Seek(size_t pos) override;
        virtual size_t Pos() const override;
        virtual size_t Size() const override;
        virtual bool AtEnd() const override;
        virtual const std::string& Name() const override { return mName; }
        virtual std::string LoadAllToString() override;
    protected:
        Stream() = default;
        mutable std::unique_ptr<T> mStream;
        size_t mSize = 0;
        std::string mName;
    };

    class MemoryStream : public Stream<std::stringstream>
    {
    public:
        explicit MemoryStream(std::vector<u8>&& data);
        virtual IStream* Clone() override;
        virtual IStream* Clone(u32 start, u32 size) override { return Stream<std::stringstream>::Clone(start, size); }
    };

    class FileStream :public Stream<std::fstream>
    {
    public:
        explicit FileStream(const std::string& fileName, ReadMode mode);
        virtual IStream* Clone() override;
        virtual IStream* Clone(u32 start, u32 size) override { return Stream<std::fstream>::Clone(start, size); }
    private:
        ReadMode mMode = IStream::ReadMode::ReadOnly;
    };
}
<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "games.h"

HiLoGame gHiLo;

const float WIN_INIT=0.05;
bool HiLoGame::enter(const TBeing *ch)
{
  if(inuse){
    ch->sendTo("This table is already in use.\n\r");
    return false;
  }

  inuse = true;
  hilo_shuffle(ch);
  bet = 0;
  name=ch->name;

  return true;
}

void HiLoGame::hilo_shuffle(const TBeing *ch)
{
  act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_CHAR);
  act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_ROOM);

  shuffle();
  deck_inx = 0;
}

bool TBeing::checkHiLo(bool inGame = false) const
{
  if (in_room == ROOM_HILO && (inGame || (gHiLo.index(this) > -1)))
    return true;
  else
    return false;
}

void HiLoGame::BetHi(TBeing *ch, int new_card)
{
  sstring buf;

  if(CARD_NUM_ACEHI(new_card) > CARD_NUM_ACEHI(card)){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);
  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::BetLo(TBeing *ch, int new_card)
{
  sstring buf;

  if(CARD_NUM_ACEHI(new_card) < CARD_NUM_ACEHI(card)){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);
  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::stay(TBeing *ch)
{
  if(win_perc==WIN_INIT){
    ch->sendTo("You just started, you can't quit now!\n\r");
    return;
  }

  ch->sendTo("You give up and cash out your winnings.\n\r");
  act("$n gives up and cashes out $s winnings.",
      TRUE, ch, 0, 0, TO_ROOM);

  int next_card=deck[deck_inx++];
  sstring buf;
  ch->sendTo(COLOR_BASIC, "The next card was the %s.\n\r", pretty_card_printout(ch, next_card).c_str());
  ssprintf(buf, "The next card was the %s.", pretty_card_printout(ch, next_card).c_str());
  act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);

  payout(ch, (int)((double)bet * (1.0 + win_perc)));
  bet = 0;
  card = 0;
  observerReaction(ch, GAMBLER_WON);
}

void HiLoGame::Bet(TBeing *ch, const sstring &arg)
{
  int inx, new_card;
  sstring coin_str;
  sstring log_msg;
  sstring buf;
  TObj *chip;

  if (ch->checkHiLo()) {
    inx = index(ch);
    if (inx < 0) {
      ch->sendTo("You are not sitting at the table yet.\n\r");
      return;
    }
    if (bet > 0) {
      if(arg=="hi" || arg=="lo"){
	if (deck_inx > 10)
	  hilo_shuffle(ch);

	new_card=deck[deck_inx++];

	ssprintf(buf, "$n bets %s.", arg.c_str());
	act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);

	ssprintf(log_msg, "You are dealt:\n\r%s\n\r", pretty_card_printout(ch, new_card).c_str());
	ch->sendTo(COLOR_BASIC, log_msg.c_str());

	ssprintf(log_msg, "$n is dealt:\n\r%s", pretty_card_printout(ch, new_card).c_str());
	act(log_msg.c_str(), TRUE, ch, 0, 0, TO_ROOM);

	if(arg=="hi"){
	  BetHi(ch, new_card);
	} else if(arg=="lo"){
	  BetLo(ch, new_card);
	}
	card=new_card;
	return;
      } else {
	ch->sendTo("You can't change your bet now.\n\r");
	ch->sendTo("You must either bet 'hi' or 'lo' for the next card.\n\r");
	return;
      }
    }
    argument_parser(arg, coin_str);
    if (coin_str.empty()){
      ch->sendTo("Bet which chip?\n\r");
      return;
    }

    if(!(chip=find_chip(ch, coin_str))){
      ch->sendTo("You don't have that chip!\n\r");
      return;
    }

    bet = chip->obj_flags.cost;
    ch->doSave(SILENT_YES);

    sstring buf;
    ssprintf(buf, "$n bets %s.", chip->getName());
    act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);
    ssprintf(buf, "You bet %s.", chip->getName());
    act(buf.c_str(), TRUE, ch, 0, 0, TO_CHAR);

    (*chip)--;
    delete chip;

    win_perc=WIN_INIT;
    card=0;
    if (deck_inx > 10)
      hilo_shuffle(ch);

    card = deck[deck_inx++];

    ssprintf(log_msg, "You are dealt:\n\r%s\n\r", pretty_card_printout(ch, card).c_str());
    ch->sendTo(COLOR_BASIC, log_msg.c_str());

    ssprintf(log_msg, "$n is dealt:\n\r%s\n\r", pretty_card_printout(ch, card).c_str());
    act(log_msg.c_str(), TRUE, ch, 0, 0, TO_ROOM);

    observerReaction(ch, GAMBLER_HILO_BET);
  }
}

void HiLoGame::peek(const TBeing *ch) const
{
  sstring log_msg;

  if (index(ch) < 0) {
    ch->sendTo("You are not sitting at the table yet.\n\r");
    return;
  }
  if (!bet) {
    ch->sendTo("You are not playing a game.\n\r");
    return;
  }
  ssprintf(log_msg, "You peek at your hand:\n\r%s\n\r", pretty_card_printout(ch, card).c_str());
  ch->sendTo(COLOR_BASIC, log_msg.c_str());
}

int HiLoGame::exitGame(const TBeing *ch)
{
  int inx;

  if ((inx = index(ch)) < 0) {
    forceCrash("%s left a table he was not at!", ch->name);
    return FALSE;
  }
  inuse = FALSE;
  name="";
  deck_inx = 0;
  bet = 0;
  card = 0;
  win_perc=0;
  setup_deck();
  ch->sendTo("You leave the hi-lo table.\n\r");
  return TRUE;
}

int HiLoGame::index(const TBeing *ch) const
{
  if(ch->name == name)
    return 0;

  return -1;
}
<commit_msg>limited winnings on hi-lo<commit_after>#include "stdsneezy.h"
#include "games.h"

HiLoGame gHiLo;

const float WIN_INIT=0.05;
bool HiLoGame::enter(const TBeing *ch)
{
  if(inuse){
    ch->sendTo("This table is already in use.\n\r");
    return false;
  }

  inuse = true;
  hilo_shuffle(ch);
  bet = 0;
  name=ch->name;

  return true;
}

void HiLoGame::hilo_shuffle(const TBeing *ch)
{
  act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_CHAR);
  act("The dealer shuffles the deck.",FALSE, ch, 0, 0, TO_ROOM);

  shuffle();
  deck_inx = 0;
}

bool TBeing::checkHiLo(bool inGame = false) const
{
  if (in_room == ROOM_HILO && (inGame || (gHiLo.index(this) > -1)))
    return true;
  else
    return false;
}

void HiLoGame::BetHi(TBeing *ch, int new_card)
{
  sstring buf;

  if(CARD_NUM_ACEHI(new_card) > CARD_NUM_ACEHI(card)){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);

    if(win_perc > 10){
      ch->sendTo("You've reach the win limit.\n\r");
      stay(ch);
    }

  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::BetLo(TBeing *ch, int new_card)
{
  sstring buf;

  if(CARD_NUM_ACEHI(new_card) < CARD_NUM_ACEHI(card)){
    win_perc*=2;
    ch->sendTo("You win!  Your winnings are now at %i talens.\n\r",
	       (int)((float)bet * (1.0 + win_perc)));
    ssprintf(buf, "$n wins!  $n's winnings are now at %i talens.",
	       (int)((float)bet * (1.0 + win_perc)));
    act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_HILO_BET);

    if(win_perc > 10){
      ch->sendTo("You've reach the win limit.\n\r");
      stay(ch);
    }

  } else {
    ch->sendTo("You lose!\n\r");
    act("$n loses!", TRUE, ch, 0, 0, TO_ROOM);
    observerReaction(ch, GAMBLER_LOST);
    bet = 0;
    card = 0;
  }
}

void HiLoGame::stay(TBeing *ch)
{
  if(win_perc==WIN_INIT){
    ch->sendTo("You just started, you can't quit now!\n\r");
    return;
  }

  ch->sendTo("You give up and cash out your winnings.\n\r");
  act("$n gives up and cashes out $s winnings.",
      TRUE, ch, 0, 0, TO_ROOM);

  int next_card=deck[deck_inx++];
  sstring buf;
  ch->sendTo(COLOR_BASIC, "The next card was the %s.\n\r", pretty_card_printout(ch, next_card).c_str());
  ssprintf(buf, "The next card was the %s.", pretty_card_printout(ch, next_card).c_str());
  act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);

  payout(ch, (int)((double)bet * (1.0 + win_perc)));
  bet = 0;
  card = 0;
  observerReaction(ch, GAMBLER_WON);
}

void HiLoGame::Bet(TBeing *ch, const sstring &arg)
{
  int inx, new_card;
  sstring coin_str;
  sstring log_msg;
  sstring buf;
  TObj *chip;

  if (ch->checkHiLo()) {
    inx = index(ch);
    if (inx < 0) {
      ch->sendTo("You are not sitting at the table yet.\n\r");
      return;
    }
    if (bet > 0) {
      if(arg=="hi" || arg=="lo"){
	if (deck_inx > 10)
	  hilo_shuffle(ch);

	new_card=deck[deck_inx++];

	ssprintf(buf, "$n bets %s.", arg.c_str());
	act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);

	ssprintf(log_msg, "You are dealt:\n\r%s\n\r", pretty_card_printout(ch, new_card).c_str());
	ch->sendTo(COLOR_BASIC, log_msg.c_str());

	ssprintf(log_msg, "$n is dealt:\n\r%s", pretty_card_printout(ch, new_card).c_str());
	act(log_msg.c_str(), TRUE, ch, 0, 0, TO_ROOM);

	if(arg=="hi"){
	  BetHi(ch, new_card);
	} else if(arg=="lo"){
	  BetLo(ch, new_card);
	}
	card=new_card;
	return;
      } else {
	ch->sendTo("You can't change your bet now.\n\r");
	ch->sendTo("You must either bet 'hi' or 'lo' for the next card.\n\r");
	return;
      }
    }
    argument_parser(arg, coin_str);
    if (coin_str.empty()){
      ch->sendTo("Bet which chip?\n\r");
      return;
    }

    if(!(chip=find_chip(ch, coin_str))){
      ch->sendTo("You don't have that chip!\n\r");
      return;
    }

    bet = chip->obj_flags.cost;
    ch->doSave(SILENT_YES);

    sstring buf;
    ssprintf(buf, "$n bets %s.", chip->getName());
    act(buf.c_str(), TRUE, ch, 0, 0, TO_ROOM);
    ssprintf(buf, "You bet %s.", chip->getName());
    act(buf.c_str(), TRUE, ch, 0, 0, TO_CHAR);

    (*chip)--;
    delete chip;

    win_perc=WIN_INIT;
    card=0;
    if (deck_inx > 10)
      hilo_shuffle(ch);

    card = deck[deck_inx++];

    ssprintf(log_msg, "You are dealt:\n\r%s\n\r", pretty_card_printout(ch, card).c_str());
    ch->sendTo(COLOR_BASIC, log_msg.c_str());

    ssprintf(log_msg, "$n is dealt:\n\r%s\n\r", pretty_card_printout(ch, card).c_str());
    act(log_msg.c_str(), TRUE, ch, 0, 0, TO_ROOM);

    observerReaction(ch, GAMBLER_HILO_BET);
  }
}

void HiLoGame::peek(const TBeing *ch) const
{
  sstring log_msg;

  if (index(ch) < 0) {
    ch->sendTo("You are not sitting at the table yet.\n\r");
    return;
  }
  if (!bet) {
    ch->sendTo("You are not playing a game.\n\r");
    return;
  }
  ssprintf(log_msg, "You peek at your hand:\n\r%s\n\r", pretty_card_printout(ch, card).c_str());
  ch->sendTo(COLOR_BASIC, log_msg.c_str());
}

int HiLoGame::exitGame(const TBeing *ch)
{
  int inx;

  if ((inx = index(ch)) < 0) {
    forceCrash("%s left a table he was not at!", ch->name);
    return FALSE;
  }
  inuse = FALSE;
  name="";
  deck_inx = 0;
  bet = 0;
  card = 0;
  win_perc=0;
  setup_deck();
  ch->sendTo("You leave the hi-lo table.\n\r");
  return TRUE;
}

int HiLoGame::index(const TBeing *ch) const
{
  if(ch->name == name)
    return 0;

  return -1;
}
<|endoftext|>


<commit_before>// RUN: clang-cc -fsyntax-only -verify %s

template<typename T> class A;

extern "C++" {
  template<typename T> class B;
}

namespace N {
  template<typename T> class C;
}

extern "C" {
  template<typename T> class D; // expected-error{{templates must have C++ linkage}}
}

template<class U> class A; // expected-note{{previous template declaration is here}}

template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}

template<int N> class NonTypeTemplateParm;

typedef int INT;

template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}

template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}

template<template<typename T> class X> class TemplateTemplateParm;

template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
      // expected-note{{previous template template parameter is here}}

template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}

template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}

template<typename T>
struct test {}; // expected-note{{previous definition}}

template<typename T>
struct test : T {}; // expected-error{{redefinition}}

#if 0
// FIXME: parse template declarations in these scopes, so that we can
// complain about the one at function scope.
class X {
public:
  template<typename T> class C;
};

void f() {
  template<typename T> class X;
}
#endif
<commit_msg>De-FIXME a test<commit_after>// RUN: clang-cc -fsyntax-only -verify %s

template<typename T> class A;

extern "C++" {
  template<typename T> class B;
}

namespace N {
  template<typename T> class C;
}

extern "C" {
  template<typename T> class D; // expected-error{{templates must have C++ linkage}}
}

template<class U> class A; // expected-note{{previous template declaration is here}}

template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}

template<int N> class NonTypeTemplateParm;

typedef int INT;

template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}

template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}

template<template<typename T> class X> class TemplateTemplateParm;

template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
      // expected-note{{previous template template parameter is here}}

template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}

template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}

template<typename T>
struct test {}; // expected-note{{previous definition}}

template<typename T>
struct test : T {}; // expected-error{{redefinition}}

class X {
public:
  template<typename T> class C;
};

void f() {
  template<typename T> class X; // expected-error{{expression}}
}
<|endoftext|>


<commit_before>#define OROCOS_TARGET gnulinux
#include <rtt/types/TypekitPlugin.hpp>
#include <rtt/typekit/RealTimeTypekit.hpp>
#include "Types.hpp"
#include "Plugin.hpp"
#include "opaque.h"

#ifdef WITH_CORBA
#include <omniORB4/CORBA.h>
#include <rtt/transports/corba/CorbaLib.hpp>
#include <rtt/transports/corba/CorbaTypeTransporter.hpp>
#include "build/.orogen/typekit/transports/corba/opaqueTypesC.h"
#include ".orogen/typekit/transports/corba/TransportPlugin.hpp"
#endif

#ifdef WITH_TYPELIB
#include "transports/typelib/TransportPlugin.hpp"
#include ".orogen/typekit/transports/typelib/TypelibMarshallerBase.hpp"
#endif

#include ".orogen/typekit/OpaqueConvertions.hpp"

#include <rtt/os/main.h>
#include <rtt/types/Types.hpp>
#include <rtt/PropertyBag.hpp>
#include <rtt/Property.hpp>
#include <rtt/internal/DataSource.hpp>
#include <rtt/types/PropertyDecomposition.hpp>
#include <rtt/marsh/PropertyMarshaller.hpp>
#include <rtt/marsh/PropertyDemarshaller.hpp>
#include <iostream>
#include <fstream>
#include <typeinfo>
#include <stdexcept>

using namespace RTT;
using namespace RTT::types;
using namespace RTT::internal;
using namespace RTT::marsh;
using namespace opaque;
using std::cerr;
using std::endl;

namespace TestOpaque {
    inline std::ostream& operator << (std::ostream& io, Position_m const& data) {
        io << "{ .timestamp = " << data.timestamp << ", .p.x" << data.p.x << ", .p.y" << data.p.y << "}";
        return io;
    }
}
namespace std {
    extern std::ostream& operator << (std::ostream& io, std::vector<float> const& data);
    extern std::ostream& operator << (std::ostream& io, std::vector<int> const& data);
}
template<typename T>
T identity(T const& value) { return value; }

#ifdef WITH_TYPELIB
template<typename OrocosType, typename TypelibType>
void from_intermediate(OrocosType& orocos_value, TypelibType& typelib_value)
{
    ValueDataSource<OrocosType>* data_source
        = new ValueDataSource<OrocosType>();
    data_source->ref();

    TypeInfo const* type = data_source->getTypeInfo();
    orogen_transports::TypelibMarshallerBase* transport =
        dynamic_cast<orogen_transports::TypelibMarshallerBase*>(type->getProtocol(orogen_transports::TYPELIB_MARSHALLER_ID));

    orogen_transports::TypelibMarshallerBase::Handle* handle =
        transport->createSample();
    transport->setTypelibSample(handle, reinterpret_cast<uint8_t*>(&typelib_value));
    transport->writeDataSource(*data_source, handle);
    orocos_value = data_source->get();

    transport->deleteHandle(handle);
    data_source->deref();
}

template<typename T, typename Getter>
bool generic_typelib_test(T const& testValue, TypeInfo const& ti, Getter get_test_value)
{
    cerr << "- testing Typelib marshalling/unmarshalling ..." << endl;
    ConstantDataSource<T>* source
        = new ConstantDataSource<T>(testValue);
    source->ref();

    orogen_transports::TypelibMarshallerBase* transport =
        dynamic_cast<orogen_transports::TypelibMarshallerBase*>(ti.getProtocol(orogen_transports::TYPELIB_MARSHALLER_ID));

    std::vector<uint8_t> buffer;
    orogen_transports::TypelibMarshallerBase::Handle* handle =
        transport->createSample();
    transport->readDataSource(*source, handle);
    transport->marshal(buffer, handle);
    transport->deleteHandle(handle);
    source->deref();

    handle = transport->createSample();
    transport->unmarshal(buffer, handle);
    ValueDataSource<T> unmarshalled;
    transport->writeDataSource(unmarshalled, handle);
    transport->deleteHandle(handle);

    if (!(get_test_value(unmarshalled.get()) == get_test_value(testValue)))
    {
        cerr << "unmarshalled Typelib data does not match original data" << endl;
        return false;
    }
    return true;
}
#endif

/* This is a generic test of type handling.
 * - it marshals the type into a XML file. This file can then be compared
 *   with an expected content by the Ruby test case.
 * - it does the same with a CPF file
 * - it unmarshals the CPF file and checks that both values are equal
 * - if the test is done with CORBA, it also converts to/from any and compares
 *   the two values.
 */
template<typename T, typename Getter>
bool generic_type_handling_test(std::string const& name, T const& testValue, TypeInfo const& ti,
        Getter get_test_value)
{
    ConstantDataSource<T>* source
        = new ConstantDataSource<T>(testValue);
    source->ref();

    std::cerr << "disabled XML decomposition/recomposition test" << std::endl;

    //PropertyBag bag;
    //ti.decomposeType(source, bag);

    //// First, save it into XML. The Ruby test case will compare that to an
    //// expected XML document
    //std::ofstream xml_file((name + ".xml").c_str());
    //XMLMarshaller<std::ostream> xml_output(xml_file);
    //xml_output.serialize(bag);

    //// Now, marshal it to the standard Orocos format, reload it and compare
    //// the result
    //PropertyMarshaller cpf_output(name + ".cpf");
    //cpf_output.serialize(bag);
    //cpf_output.flush();

    //PropertyBag input_bag;
    //PropertyDemarshaller cpf_input(name + ".cpf");
    //cpf_input.deserialize(input_bag);

    //cerr << "Testing PropertyBag composition" << endl;
    //{ ValueDataSource<T>* reader = new ValueDataSource<T>();
    //    reader->ref();
    //    Property<PropertyBag> bag("", "", input_bag);
    //    if (!ti.composeType(bag.getDataSource(), reader))
    //    {
    //        cerr << "cannot recompose type" << endl;
    //        return false;
    //    }

    //    T value = reader->get();
    //    if (!(get_test_value(value) == get_test_value(testValue)))
    //    {
    //        cerr << "error. Expected\n\n" << get_test_value(testValue) <<
    //            "\n\nand got\n\n" << get_test_value(value) << endl;
    //    }
    //    reader->deref();
    //}

#ifdef WITH_CORBA
    std::cerr << "Testing CORBA marshalling/unmarshalling ..." << std::endl;
    { RTT::corba::CorbaTypeTransporter* transport =
            dynamic_cast<RTT::corba::CorbaTypeTransporter*>(ti.getProtocol(ORO_CORBA_PROTOCOL_ID));

        CORBA::Any* result = transport->createAny(source);

        ValueDataSource<T>* reader = new ValueDataSource<T>();
        reader->ref();
        transport->updateFromAny(result, reader);

        T value = reader->get();
        if (!(get_test_value(value) == get_test_value(testValue)))
        {
            cerr << "error in CORBA marshalling/demarshalling" << endl;
            return false;
        }
        delete result;
        reader->deref();
    }
#endif

#ifdef WITH_TYPELIB
    if (!generic_typelib_test(testValue, ti, get_test_value))
        return false;
#endif

    source->deref();
    return true;
}

bool test_plain_opaque()
{
    cerr << "\n======== Testing plain opaque handling ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/NotOrogenCompatible/Point2D");
    if (! type)
    {
	cerr << "cannot find /NotOrogenCompatible/Point2D in the type info repository" << endl;
	return false;
    }

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        TestOpaque::Point2D testValue = { 100, 20, 30 };
        NotOrogenCompatible::Point2D p(0, 0);
        from_intermediate(p, testValue);

        if (testValue.x != p.x() || testValue.y != p.y())
        {
            cerr << "error in Typelib marshalling" << endl;
            return false;
        }
    }

    NotOrogenCompatible::Point2D testValue(10, 20);
    if (!generic_type_handling_test("opaque", testValue, *type, &::identity<NotOrogenCompatible::Point2D> ))
        return false;

    return true;
}

bool test_composed_opaque()
{
    cerr << "\n======== Testing opaque field in struct ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/TestOpaque/Position");
    if (! type)
    {
	cerr << "cannot find /TestOpaque/Position in the type info repository" << endl;
	return 1;
    }

    TestOpaque::Position testValue;
    testValue.timestamp = 10;
    testValue.p.x() = 20;
    testValue.p.y() = 30;

    generic_type_handling_test("composed_opaque", testValue, *type, &::identity<TestOpaque::Position> );

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        TestOpaque::Position_m testValue = { 100, 20, 30 };
        TestOpaque::Position p;
        memset(&p, 0, sizeof(p));
        from_intermediate(p, testValue);

        if (testValue.timestamp != p.timestamp || testValue.p.x != p.p.x() || testValue.p.y != p.p.y())
        {
            cerr << "error in Typelib marshalling" << endl;
            return false;
        }
    }

    return true;
}

template<typename T>
T get_ptr_content(boost::shared_ptr<T> const& left)
{ return *left; }

template<typename T>
T get_ro_ptr_content(RTT::extras::ReadOnlyPointer<T> const& left)
{ return *left; }

bool test_shared_pointer()
{
    cerr << "\n======== Testing shared pointer ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/boost/shared_ptr</std/vector</float>>");
    if (! type)
    {
	cerr << "cannot find /boost/shared_ptr</std/vector</float>> in the type info repository" << endl;
	return 1;
    }

    boost::shared_ptr< std::vector<float> > testValue( new std::vector<float> );
    std::vector<float>& data = *testValue;

    for (int i = 0; i < 10; ++i)
        data.push_back(i);

    generic_type_handling_test("shared_ptr__opaque_type", testValue, *type, &get_ptr_content< std::vector<float> >);

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        boost::shared_ptr< std::vector<float> > result;
        from_intermediate(result, *testValue);

        for (int i = 0; i < data.size(); ++i)
            if ((*result)[i] != (*testValue)[i])
            {
                cerr << "error in type initialization from an intermediate" << endl;
                return false;
            }
    }

    return true;
}

bool test_shared_ptr_shortcut()
{
    cerr << "\n======== Testing shared pointer (from #shared_ptr) ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/boost/shared_ptr</std/vector</int>>");
    if (! type)
    {
	cerr << "cannot find /boost/shared_ptr</std/vector</int>> in the type info repository" << endl;
	return 1;
    }

    boost::shared_ptr< std::vector<int> > testValue( new std::vector<int> );
    std::vector<int>& data = *testValue;

    for (int i = 0; i < 10; ++i)
        data.push_back(i);

    generic_type_handling_test("shared_ptr__shared_ptr", testValue, *type, &get_ptr_content< std::vector<int> >);

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        boost::shared_ptr< std::vector<int> > result;
        from_intermediate(result, data);

        for (int i = 0; i < data.size(); ++i)
            if ((*result)[i] != (*testValue)[i])
            {
                cerr << "error in type initialization from an intermediate" << endl;
                return false;
            }
    }

    return true;
}

bool test_ro_ptr()
{
    cerr << "\n======== Testing ReadOnlyPointer (from #ro_ptr) ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/RTT/extras/ReadOnlyPointer</std/vector</int>>");
    if (! type)
    {
	cerr << "cannot find /RTT/extras/ReadOnlyPointer</std/vector</int>> in the type info repository" << endl;
	return 1;
    }

    std::vector<int>* data = new std::vector<int>();
    for (int i = 0; i < 10; ++i)
        data->push_back(i);

    RTT::extras::ReadOnlyPointer< std::vector<int> > testValue(data);

    generic_type_handling_test("readonlypointer", testValue, *type, &get_ro_ptr_content< std::vector<int> >);

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        RTT::extras::ReadOnlyPointer< std::vector<int> > result;
        from_intermediate(result, *data);

        for (int i = 0; i < data->size(); ++i)
            if ((*result)[i] != (*testValue)[i])
            {
                cerr << "error in type initialization from an intermediate" << endl;
                return false;
            }
    }

    return true;
}

int ORO_main(int argc, char** argv)
{
    log().setLogLevel( Logger::Debug );
    RTT::types::TypekitRepository::Import( new RTT::types::RealTimeTypekitPlugin );
    RTT::types::TypekitRepository::Import( new orogen_typekits::opaqueTypekitPlugin );
#ifdef WITH_CORBA
    RTT::types::TypekitRepository::Import( new orogen_typekits::opaqueCorbaTransportPlugin );
#endif
#ifdef WITH_TYPELIB
    RTT::types::TypekitRepository::Import( new orogen_typekits::opaqueTypelibTransportPlugin );
#endif

    if (!test_plain_opaque())
    {
        cerr << "plain_opaque failed" << endl;
        return 1;
    }
    if (!test_composed_opaque())
    {
        cerr << "composed_opaque failed" << endl;
        return 1;
    }
    if (!test_shared_pointer())
    {
        cerr << "shared_ptr failed" << endl;
        return 1;
    }
    if (!test_shared_ptr_shortcut())
    {
        cerr << "shared_ptr (from #shared_ptr) failed" << endl;
        return 1;
    }
    if (!test_ro_ptr())
    {
        cerr << "ReadOnlyPointer failed" << endl;
        return 1;
    }

    return 0;
}

<commit_msg>opaque.h does not exist anymore<commit_after>#define OROCOS_TARGET gnulinux
#include <rtt/types/TypekitPlugin.hpp>
#include <rtt/typekit/RealTimeTypekit.hpp>
#include "Types.hpp"
#include "Plugin.hpp"

#ifdef WITH_CORBA
#include <omniORB4/CORBA.h>
#include <rtt/transports/corba/CorbaLib.hpp>
#include <rtt/transports/corba/CorbaTypeTransporter.hpp>
#include "build/.orogen/typekit/transports/corba/opaqueTypesC.h"
#include ".orogen/typekit/transports/corba/TransportPlugin.hpp"
#endif

#ifdef WITH_TYPELIB
#include "transports/typelib/TransportPlugin.hpp"
#include ".orogen/typekit/transports/typelib/TypelibMarshallerBase.hpp"
#endif

#include ".orogen/typekit/OpaqueConvertions.hpp"

#include <rtt/os/main.h>
#include <rtt/types/Types.hpp>
#include <rtt/PropertyBag.hpp>
#include <rtt/Property.hpp>
#include <rtt/internal/DataSource.hpp>
#include <rtt/types/PropertyDecomposition.hpp>
#include <rtt/marsh/PropertyMarshaller.hpp>
#include <rtt/marsh/PropertyDemarshaller.hpp>
#include <iostream>
#include <fstream>
#include <typeinfo>
#include <stdexcept>

using namespace RTT;
using namespace RTT::types;
using namespace RTT::internal;
using namespace RTT::marsh;
using namespace opaque;
using std::cerr;
using std::endl;

namespace TestOpaque {
    inline std::ostream& operator << (std::ostream& io, Position_m const& data) {
        io << "{ .timestamp = " << data.timestamp << ", .p.x" << data.p.x << ", .p.y" << data.p.y << "}";
        return io;
    }
}
namespace std {
    extern std::ostream& operator << (std::ostream& io, std::vector<float> const& data);
    extern std::ostream& operator << (std::ostream& io, std::vector<int> const& data);
}
template<typename T>
T identity(T const& value) { return value; }

#ifdef WITH_TYPELIB
template<typename OrocosType, typename TypelibType>
void from_intermediate(OrocosType& orocos_value, TypelibType& typelib_value)
{
    ValueDataSource<OrocosType>* data_source
        = new ValueDataSource<OrocosType>();
    data_source->ref();

    TypeInfo const* type = data_source->getTypeInfo();
    orogen_transports::TypelibMarshallerBase* transport =
        dynamic_cast<orogen_transports::TypelibMarshallerBase*>(type->getProtocol(orogen_transports::TYPELIB_MARSHALLER_ID));

    orogen_transports::TypelibMarshallerBase::Handle* handle =
        transport->createSample();
    transport->setTypelibSample(handle, reinterpret_cast<uint8_t*>(&typelib_value));
    transport->writeDataSource(*data_source, handle);
    orocos_value = data_source->get();

    transport->deleteHandle(handle);
    data_source->deref();
}

template<typename T, typename Getter>
bool generic_typelib_test(T const& testValue, TypeInfo const& ti, Getter get_test_value)
{
    cerr << "- testing Typelib marshalling/unmarshalling ..." << endl;
    ConstantDataSource<T>* source
        = new ConstantDataSource<T>(testValue);
    source->ref();

    orogen_transports::TypelibMarshallerBase* transport =
        dynamic_cast<orogen_transports::TypelibMarshallerBase*>(ti.getProtocol(orogen_transports::TYPELIB_MARSHALLER_ID));

    std::vector<uint8_t> buffer;
    orogen_transports::TypelibMarshallerBase::Handle* handle =
        transport->createSample();
    transport->readDataSource(*source, handle);
    transport->marshal(buffer, handle);
    transport->deleteHandle(handle);
    source->deref();

    handle = transport->createSample();
    transport->unmarshal(buffer, handle);
    ValueDataSource<T> unmarshalled;
    transport->writeDataSource(unmarshalled, handle);
    transport->deleteHandle(handle);

    if (!(get_test_value(unmarshalled.get()) == get_test_value(testValue)))
    {
        cerr << "unmarshalled Typelib data does not match original data" << endl;
        return false;
    }
    return true;
}
#endif

/* This is a generic test of type handling.
 * - it marshals the type into a XML file. This file can then be compared
 *   with an expected content by the Ruby test case.
 * - it does the same with a CPF file
 * - it unmarshals the CPF file and checks that both values are equal
 * - if the test is done with CORBA, it also converts to/from any and compares
 *   the two values.
 */
template<typename T, typename Getter>
bool generic_type_handling_test(std::string const& name, T const& testValue, TypeInfo const& ti,
        Getter get_test_value)
{
    ConstantDataSource<T>* source
        = new ConstantDataSource<T>(testValue);
    source->ref();

    std::cerr << "disabled XML decomposition/recomposition test" << std::endl;

    //PropertyBag bag;
    //ti.decomposeType(source, bag);

    //// First, save it into XML. The Ruby test case will compare that to an
    //// expected XML document
    //std::ofstream xml_file((name + ".xml").c_str());
    //XMLMarshaller<std::ostream> xml_output(xml_file);
    //xml_output.serialize(bag);

    //// Now, marshal it to the standard Orocos format, reload it and compare
    //// the result
    //PropertyMarshaller cpf_output(name + ".cpf");
    //cpf_output.serialize(bag);
    //cpf_output.flush();

    //PropertyBag input_bag;
    //PropertyDemarshaller cpf_input(name + ".cpf");
    //cpf_input.deserialize(input_bag);

    //cerr << "Testing PropertyBag composition" << endl;
    //{ ValueDataSource<T>* reader = new ValueDataSource<T>();
    //    reader->ref();
    //    Property<PropertyBag> bag("", "", input_bag);
    //    if (!ti.composeType(bag.getDataSource(), reader))
    //    {
    //        cerr << "cannot recompose type" << endl;
    //        return false;
    //    }

    //    T value = reader->get();
    //    if (!(get_test_value(value) == get_test_value(testValue)))
    //    {
    //        cerr << "error. Expected\n\n" << get_test_value(testValue) <<
    //            "\n\nand got\n\n" << get_test_value(value) << endl;
    //    }
    //    reader->deref();
    //}

#ifdef WITH_CORBA
    std::cerr << "Testing CORBA marshalling/unmarshalling ..." << std::endl;
    { RTT::corba::CorbaTypeTransporter* transport =
            dynamic_cast<RTT::corba::CorbaTypeTransporter*>(ti.getProtocol(ORO_CORBA_PROTOCOL_ID));

        CORBA::Any* result = transport->createAny(source);

        ValueDataSource<T>* reader = new ValueDataSource<T>();
        reader->ref();
        transport->updateFromAny(result, reader);

        T value = reader->get();
        if (!(get_test_value(value) == get_test_value(testValue)))
        {
            cerr << "error in CORBA marshalling/demarshalling" << endl;
            return false;
        }
        delete result;
        reader->deref();
    }
#endif

#ifdef WITH_TYPELIB
    if (!generic_typelib_test(testValue, ti, get_test_value))
        return false;
#endif

    source->deref();
    return true;
}

bool test_plain_opaque()
{
    cerr << "\n======== Testing plain opaque handling ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/NotOrogenCompatible/Point2D");
    if (! type)
    {
	cerr << "cannot find /NotOrogenCompatible/Point2D in the type info repository" << endl;
	return false;
    }

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        TestOpaque::Point2D testValue = { 100, 20, 30 };
        NotOrogenCompatible::Point2D p(0, 0);
        from_intermediate(p, testValue);

        if (testValue.x != p.x() || testValue.y != p.y())
        {
            cerr << "error in Typelib marshalling" << endl;
            return false;
        }
    }

    NotOrogenCompatible::Point2D testValue(10, 20);
    if (!generic_type_handling_test("opaque", testValue, *type, &::identity<NotOrogenCompatible::Point2D> ))
        return false;

    return true;
}

bool test_composed_opaque()
{
    cerr << "\n======== Testing opaque field in struct ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/TestOpaque/Position");
    if (! type)
    {
	cerr << "cannot find /TestOpaque/Position in the type info repository" << endl;
	return 1;
    }

    TestOpaque::Position testValue;
    testValue.timestamp = 10;
    testValue.p.x() = 20;
    testValue.p.y() = 30;

    generic_type_handling_test("composed_opaque", testValue, *type, &::identity<TestOpaque::Position> );

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        TestOpaque::Position_m testValue = { 100, 20, 30 };
        TestOpaque::Position p;
        memset(&p, 0, sizeof(p));
        from_intermediate(p, testValue);

        if (testValue.timestamp != p.timestamp || testValue.p.x != p.p.x() || testValue.p.y != p.p.y())
        {
            cerr << "error in Typelib marshalling" << endl;
            return false;
        }
    }

    return true;
}

template<typename T>
T get_ptr_content(boost::shared_ptr<T> const& left)
{ return *left; }

template<typename T>
T get_ro_ptr_content(RTT::extras::ReadOnlyPointer<T> const& left)
{ return *left; }

bool test_shared_pointer()
{
    cerr << "\n======== Testing shared pointer ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/boost/shared_ptr</std/vector</float>>");
    if (! type)
    {
	cerr << "cannot find /boost/shared_ptr</std/vector</float>> in the type info repository" << endl;
	return 1;
    }

    boost::shared_ptr< std::vector<float> > testValue( new std::vector<float> );
    std::vector<float>& data = *testValue;

    for (int i = 0; i < 10; ++i)
        data.push_back(i);

    generic_type_handling_test("shared_ptr__opaque_type", testValue, *type, &get_ptr_content< std::vector<float> >);

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        boost::shared_ptr< std::vector<float> > result;
        from_intermediate(result, *testValue);

        for (int i = 0; i < data.size(); ++i)
            if ((*result)[i] != (*testValue)[i])
            {
                cerr << "error in type initialization from an intermediate" << endl;
                return false;
            }
    }

    return true;
}

bool test_shared_ptr_shortcut()
{
    cerr << "\n======== Testing shared pointer (from #shared_ptr) ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/boost/shared_ptr</std/vector</int>>");
    if (! type)
    {
	cerr << "cannot find /boost/shared_ptr</std/vector</int>> in the type info repository" << endl;
	return 1;
    }

    boost::shared_ptr< std::vector<int> > testValue( new std::vector<int> );
    std::vector<int>& data = *testValue;

    for (int i = 0; i < 10; ++i)
        data.push_back(i);

    generic_type_handling_test("shared_ptr__shared_ptr", testValue, *type, &get_ptr_content< std::vector<int> >);

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        boost::shared_ptr< std::vector<int> > result;
        from_intermediate(result, data);

        for (int i = 0; i < data.size(); ++i)
            if ((*result)[i] != (*testValue)[i])
            {
                cerr << "error in type initialization from an intermediate" << endl;
                return false;
            }
    }

    return true;
}

bool test_ro_ptr()
{
    cerr << "\n======== Testing ReadOnlyPointer (from #ro_ptr) ========" << endl;

    TypeInfoRepository::shared_ptr ti = TypeInfoRepository::Instance();
    TypeInfo* type = ti->type("/RTT/extras/ReadOnlyPointer</std/vector</int>>");
    if (! type)
    {
	cerr << "cannot find /RTT/extras/ReadOnlyPointer</std/vector</int>> in the type info repository" << endl;
	return 1;
    }

    std::vector<int>* data = new std::vector<int>();
    for (int i = 0; i < 10; ++i)
        data->push_back(i);

    RTT::extras::ReadOnlyPointer< std::vector<int> > testValue(data);

    generic_type_handling_test("readonlypointer", testValue, *type, &get_ro_ptr_content< std::vector<int> >);

    std::cerr << "Testing the initialization of the types from an intermediate..." << std::endl;
    {
        RTT::extras::ReadOnlyPointer< std::vector<int> > result;
        from_intermediate(result, *data);

        for (int i = 0; i < data->size(); ++i)
            if ((*result)[i] != (*testValue)[i])
            {
                cerr << "error in type initialization from an intermediate" << endl;
                return false;
            }
    }

    return true;
}

int ORO_main(int argc, char** argv)
{
    log().setLogLevel( Logger::Debug );
    RTT::types::TypekitRepository::Import( new RTT::types::RealTimeTypekitPlugin );
    RTT::types::TypekitRepository::Import( new orogen_typekits::opaqueTypekitPlugin );
#ifdef WITH_CORBA
    RTT::types::TypekitRepository::Import( new orogen_typekits::opaqueCorbaTransportPlugin );
#endif
#ifdef WITH_TYPELIB
    RTT::types::TypekitRepository::Import( new orogen_typekits::opaqueTypelibTransportPlugin );
#endif

    if (!test_plain_opaque())
    {
        cerr << "plain_opaque failed" << endl;
        return 1;
    }
    if (!test_composed_opaque())
    {
        cerr << "composed_opaque failed" << endl;
        return 1;
    }
    if (!test_shared_pointer())
    {
        cerr << "shared_ptr failed" << endl;
        return 1;
    }
    if (!test_shared_ptr_shortcut())
    {
        cerr << "shared_ptr (from #shared_ptr) failed" << endl;
        return 1;
    }
    if (!test_ro_ptr())
    {
        cerr << "ReadOnlyPointer failed" << endl;
        return 1;
    }

    return 0;
}

<|endoftext|>