<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <cmath>

namespace MATH_NAMESPACE
{
namespace simd
{

//-------------------------------------------------------------------------------------------------
// float4 members
//

VSNRAY_FORCE_INLINE float4::basic_float(float x, float y, float z, float w)
    : value(_mm_set_ps(w, z, y, x))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(float const v[4])
    : value(_mm_load_ps(v))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(float s)
    : value(_mm_set1_ps(s))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(__m128i const& i)
    : value(_mm_cvtepi32_ps(i))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(__m128 const& v)
    : value(v)
{
}

VSNRAY_FORCE_INLINE float4::operator __m128() const
{
    return value;
}

//-------------------------------------------------------------------------------------------------
// Bitwise cast
//

VSNRAY_FORCE_INLINE int4 reinterpret_as_int(float4 const& a)
{
    return _mm_castps_si128(a);
}

//-------------------------------------------------------------------------------------------------
// Static cast
//

VSNRAY_FORCE_INLINE int4 convert_to_int(float4 const& a)
{
    return _mm_cvttps_epi32(a);
}

//-------------------------------------------------------------------------------------------------
// select intrinsic
//

VSNRAY_FORCE_INLINE float4 select(mask4 const& m, float4 const& a, float4 const& b)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_blendv_ps(b, a, m.f);
#else
    return _mm_or_ps(_mm_and_ps(m.f, a), _mm_andnot_ps(m.f, b));
#endif
}

//-------------------------------------------------------------------------------------------------
// Load / store / get
//

VSNRAY_FORCE_INLINE float4 load(float const dst[4])
{
    return _mm_load_ps(dst);
}

VSNRAY_FORCE_INLINE float4 load_unaligned(float const dst[4])
{
    return _mm_loadu_ps(dst);
}

VSNRAY_FORCE_INLINE void store(float dst[4], float4 const& v)
{
    _mm_store_ps(dst, v);
}

VSNRAY_FORCE_INLINE void store_unaligned(float dst[4], float4 const& v)
{
    _mm_storeu_ps(dst, v);
}

template <int U0, int U1, int V2, int V3>
VSNRAY_FORCE_INLINE float4 shuffle(float4 const& u, float4 const& v)
{
    return _mm_shuffle_ps(u, v, _MM_SHUFFLE(V3, V2, U1, U0));
}

template <int V0, int V1, int V2, int V3>
VSNRAY_FORCE_INLINE float4 shuffle(float4 const& v)
{
    return _mm_shuffle_ps(v, v, _MM_SHUFFLE(V3, V2, V1, V0));
}

template <size_t I>
VSNRAY_FORCE_INLINE float& get(float4& v)
{
    static_assert(I < 4, "Index out of range for SIMD vector access");

    return reinterpret_cast<float*>(&v)[I];
}

template <size_t I>
VSNRAY_FORCE_INLINE float const& get(float4 const& v)
{
    static_assert(I < 4, "Index out of range for SIMD vector access");

    return reinterpret_cast<float const*>(&v)[I];
}

//-------------------------------------------------------------------------------------------------
// Basic arithmetics
//

VSNRAY_FORCE_INLINE float4 operator+(float4 const& v)
{
    return _mm_add_ps(_mm_setzero_ps(), v);
}

VSNRAY_FORCE_INLINE float4 operator-(float4 const& v)
{
    return _mm_sub_ps(_mm_setzero_ps(), v);
}

VSNRAY_FORCE_INLINE float4 operator+(float4 const& u, float4 const& v)
{
    return _mm_add_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator-(float4 const& u, float4 const& v)
{
    return _mm_sub_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator*(float4 const& u, float4 const& v)
{
    return _mm_mul_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator/(float4 const& u, float4 const& v)
{
    return _mm_div_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Bitwise operations
//

VSNRAY_FORCE_INLINE float4 operator&(float4 const& u, float4 const& v)
{
    return _mm_and_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator|(float4 const& u, float4 const& v)
{
    return _mm_or_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator^(float4 const& u, float4 const& v)
{
    return _mm_xor_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Logical operations
//

VSNRAY_FORCE_INLINE float4 operator&&(float4 const& u, float4 const& v)
{
    return _mm_and_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator||(float4 const& u, float4 const& v)
{
    return _mm_or_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Comparisons
//

VSNRAY_FORCE_INLINE mask4 operator<(float4 const& u, float4 const& v)
{
    return _mm_cmplt_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator>(float4 const& u, float4 const& v)
{
    return _mm_cmpgt_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator<=(float4 const& u, float4 const& v)
{
    return _mm_cmple_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator>=(float4 const& u, float4 const& v)
{
    return _mm_cmpge_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator==(float4 const& u, float4 const& v)
{
    return _mm_cmpeq_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator!=(float4 const& u, float4 const& v)
{
    return _mm_cmpneq_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Math functions
//

VSNRAY_FORCE_INLINE float4 dot(float4 const& u, float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_dp_ps(u, v, 0xFF);
#else
   __m128 t1 = _mm_mul_ps(u, v);
   __m128 t2 = _mm_shuffle_ps(t1, t1, _MM_SHUFFLE(2,3,0,1));
   __m128 t3 = _mm_add_ps(t1, t2);
   __m128 t4 = _mm_shuffle_ps(t3, t3, _MM_SHUFFLE(0,1,2,3));
   __m128 t5 = _mm_add_ps(t3, t4);

   return t5;
#endif
}

VSNRAY_FORCE_INLINE float4 min(float4 const& u, float4 const& v)
{
    return _mm_min_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 max(float4 const& u, float4 const& v)
{
    return _mm_max_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 saturate(float4 const& u)
{
    return _mm_max_ps(_mm_setzero_ps(), _mm_min_ps(u, _mm_set1_ps(1.0f)));
}

VSNRAY_FORCE_INLINE float4 abs(float4 const& u)
{
    return _mm_and_ps(u, _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF)));
}

VSNRAY_FORCE_INLINE float4 round(float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_round_ps(v, _MM_FROUND_TO_NEAREST_INT);
#else
    // Mask out the signbits of v
    __m128 s = _mm_and_ps(v, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)));
    // Magic number: 2^23 with the signbits of v
    __m128 m = _mm_or_ps(s, _mm_castsi128_ps(_mm_set1_epi32(0x4B000000)));
    __m128 x = _mm_add_ps(v, m);
    __m128 y = _mm_sub_ps(x, m);

    return y;
#endif
}

VSNRAY_FORCE_INLINE float4 ceil(float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_ceil_ps(v);
#else
    // i = trunc(v)
    __m128 i = _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
    // r = i < v ? i i + 1 : i
    __m128 t = _mm_cmplt_ps(i, v);
    __m128 d = _mm_cvtepi32_ps(_mm_castps_si128(t)); // mask to float: 0 -> 0.0f, 0xFFFFFFFF -> -1.0f
    __m128 r = _mm_sub_ps(i, d);

    return r;
#endif
}

VSNRAY_FORCE_INLINE float4 floor(float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_floor_ps(v);
#else
    // i = trunc(v)
    __m128 i = _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
    // r = i > v ? i - 1 : i
    __m128 t = _mm_cmpgt_ps(i, v);
    __m128 d = _mm_cvtepi32_ps(_mm_castps_si128(t)); // mask to float: 0 -> 0.0f, 0xFFFFFFFF -> -1.0f
    __m128 r = _mm_add_ps(i, d);

    return r;
#endif
}

VSNRAY_FORCE_INLINE float4 sqrt(float4 const& v)
{
    return _mm_sqrt_ps(v);
}

VSNRAY_FORCE_INLINE mask4 isinf(float4 const& v)
{
    VSNRAY_ALIGN(16) float values[4] = {};
    store(values, v);

    return mask4(
            std::isinf(values[0]),
            std::isinf(values[1]),
            std::isinf(values[2]),
            std::isinf(values[3])
            );
}

VSNRAY_FORCE_INLINE mask4 isnan(float4 const& v)
{
    return v != v;
}

VSNRAY_FORCE_INLINE mask4 isfinite(float4 const& v)
{
    return !(isinf(v) | isnan(v));
}

//-------------------------------------------------------------------------------------------------
//
//

template <unsigned N>
VSNRAY_FORCE_INLINE float4 rcp(float4 const& v)
{
    float4 x0 = _mm_rcp_ps(v);
    return rcp_step<N>(x0);
}

VSNRAY_FORCE_INLINE float4 rcp(float4 const& v)
{
    float4 x0 = _mm_rcp_ps(v);
    return rcp_step<1>(x0);
}

template <unsigned N>
VSNRAY_FORCE_INLINE float4 rsqrt(float4 const& v)
{
    float4 x0 = _mm_rsqrt_ps(v);
    return rsqrt_step<N>(v, x0);
}

VSNRAY_FORCE_INLINE float4 rsqrt(float4 const& v)
{
    float4 x0 = _mm_rsqrt_ps(v);
    return rsqrt_step<1>(v, x0);
}

VSNRAY_FORCE_INLINE float4 approx_rsqrt(float4 const& v)
{
    return _mm_rsqrt_ps(v);
}

} // simd
} // MATH_NAMESPACE
<commit_msg>Refactoring<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <cmath>

namespace MATH_NAMESPACE
{
namespace simd
{

//-------------------------------------------------------------------------------------------------
// float4 members
//

VSNRAY_FORCE_INLINE float4::basic_float(float x, float y, float z, float w)
    : value(_mm_set_ps(w, z, y, x))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(float const v[4])
    : value(_mm_load_ps(v))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(float s)
    : value(_mm_set1_ps(s))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(__m128i const& i)
    : value(_mm_cvtepi32_ps(i))
{
}

VSNRAY_FORCE_INLINE float4::basic_float(__m128 const& v)
    : value(v)
{
}

VSNRAY_FORCE_INLINE float4::operator __m128() const
{
    return value;
}

//-------------------------------------------------------------------------------------------------
// Bitwise cast
//

VSNRAY_FORCE_INLINE int4 reinterpret_as_int(float4 const& a)
{
    return _mm_castps_si128(a);
}

//-------------------------------------------------------------------------------------------------
// Static cast
//

VSNRAY_FORCE_INLINE int4 convert_to_int(float4 const& a)
{
    return _mm_cvttps_epi32(a);
}

//-------------------------------------------------------------------------------------------------
// select intrinsic
//

VSNRAY_FORCE_INLINE float4 select(mask4 const& m, float4 const& a, float4 const& b)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_blendv_ps(b, a, m.f);
#else
    return _mm_or_ps(_mm_and_ps(m.f, a), _mm_andnot_ps(m.f, b));
#endif
}

//-------------------------------------------------------------------------------------------------
// Load / store / get
//

VSNRAY_FORCE_INLINE float4 load(float const src[4])
{
    return _mm_load_ps(src);
}

VSNRAY_FORCE_INLINE float4 load_unaligned(float const src[4])
{
    return _mm_loadu_ps(src);
}

VSNRAY_FORCE_INLINE void store(float dst[4], float4 const& v)
{
    _mm_store_ps(dst, v);
}

VSNRAY_FORCE_INLINE void store_unaligned(float dst[4], float4 const& v)
{
    _mm_storeu_ps(dst, v);
}

template <int U0, int U1, int V2, int V3>
VSNRAY_FORCE_INLINE float4 shuffle(float4 const& u, float4 const& v)
{
    return _mm_shuffle_ps(u, v, _MM_SHUFFLE(V3, V2, U1, U0));
}

template <int V0, int V1, int V2, int V3>
VSNRAY_FORCE_INLINE float4 shuffle(float4 const& v)
{
    return _mm_shuffle_ps(v, v, _MM_SHUFFLE(V3, V2, V1, V0));
}

template <size_t I>
VSNRAY_FORCE_INLINE float& get(float4& v)
{
    static_assert(I < 4, "Index out of range for SIMD vector access");

    return reinterpret_cast<float*>(&v)[I];
}

template <size_t I>
VSNRAY_FORCE_INLINE float const& get(float4 const& v)
{
    static_assert(I < 4, "Index out of range for SIMD vector access");

    return reinterpret_cast<float const*>(&v)[I];
}

//-------------------------------------------------------------------------------------------------
// Basic arithmetics
//

VSNRAY_FORCE_INLINE float4 operator+(float4 const& v)
{
    return _mm_add_ps(_mm_setzero_ps(), v);
}

VSNRAY_FORCE_INLINE float4 operator-(float4 const& v)
{
    return _mm_sub_ps(_mm_setzero_ps(), v);
}

VSNRAY_FORCE_INLINE float4 operator+(float4 const& u, float4 const& v)
{
    return _mm_add_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator-(float4 const& u, float4 const& v)
{
    return _mm_sub_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator*(float4 const& u, float4 const& v)
{
    return _mm_mul_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator/(float4 const& u, float4 const& v)
{
    return _mm_div_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Bitwise operations
//

VSNRAY_FORCE_INLINE float4 operator&(float4 const& u, float4 const& v)
{
    return _mm_and_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator|(float4 const& u, float4 const& v)
{
    return _mm_or_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator^(float4 const& u, float4 const& v)
{
    return _mm_xor_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Logical operations
//

VSNRAY_FORCE_INLINE float4 operator&&(float4 const& u, float4 const& v)
{
    return _mm_and_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 operator||(float4 const& u, float4 const& v)
{
    return _mm_or_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Comparisons
//

VSNRAY_FORCE_INLINE mask4 operator<(float4 const& u, float4 const& v)
{
    return _mm_cmplt_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator>(float4 const& u, float4 const& v)
{
    return _mm_cmpgt_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator<=(float4 const& u, float4 const& v)
{
    return _mm_cmple_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator>=(float4 const& u, float4 const& v)
{
    return _mm_cmpge_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator==(float4 const& u, float4 const& v)
{
    return _mm_cmpeq_ps(u, v);
}

VSNRAY_FORCE_INLINE mask4 operator!=(float4 const& u, float4 const& v)
{
    return _mm_cmpneq_ps(u, v);
}

//-------------------------------------------------------------------------------------------------
// Math functions
//

VSNRAY_FORCE_INLINE float4 dot(float4 const& u, float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_dp_ps(u, v, 0xFF);
#else
   __m128 t1 = _mm_mul_ps(u, v);
   __m128 t2 = _mm_shuffle_ps(t1, t1, _MM_SHUFFLE(2,3,0,1));
   __m128 t3 = _mm_add_ps(t1, t2);
   __m128 t4 = _mm_shuffle_ps(t3, t3, _MM_SHUFFLE(0,1,2,3));
   __m128 t5 = _mm_add_ps(t3, t4);

   return t5;
#endif
}

VSNRAY_FORCE_INLINE float4 min(float4 const& u, float4 const& v)
{
    return _mm_min_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 max(float4 const& u, float4 const& v)
{
    return _mm_max_ps(u, v);
}

VSNRAY_FORCE_INLINE float4 saturate(float4 const& u)
{
    return _mm_max_ps(_mm_setzero_ps(), _mm_min_ps(u, _mm_set1_ps(1.0f)));
}

VSNRAY_FORCE_INLINE float4 abs(float4 const& u)
{
    return _mm_and_ps(u, _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF)));
}

VSNRAY_FORCE_INLINE float4 round(float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_round_ps(v, _MM_FROUND_TO_NEAREST_INT);
#else
    // Mask out the signbits of v
    __m128 s = _mm_and_ps(v, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)));
    // Magic number: 2^23 with the signbits of v
    __m128 m = _mm_or_ps(s, _mm_castsi128_ps(_mm_set1_epi32(0x4B000000)));
    __m128 x = _mm_add_ps(v, m);
    __m128 y = _mm_sub_ps(x, m);

    return y;
#endif
}

VSNRAY_FORCE_INLINE float4 ceil(float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_ceil_ps(v);
#else
    // i = trunc(v)
    __m128 i = _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
    // r = i < v ? i i + 1 : i
    __m128 t = _mm_cmplt_ps(i, v);
    __m128 d = _mm_cvtepi32_ps(_mm_castps_si128(t)); // mask to float: 0 -> 0.0f, 0xFFFFFFFF -> -1.0f
    __m128 r = _mm_sub_ps(i, d);

    return r;
#endif
}

VSNRAY_FORCE_INLINE float4 floor(float4 const& v)
{
#if VSNRAY_SIMD_ISA_GE(VSNRAY_SIMD_ISA_SSE4_1)
    return _mm_floor_ps(v);
#else
    // i = trunc(v)
    __m128 i = _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
    // r = i > v ? i - 1 : i
    __m128 t = _mm_cmpgt_ps(i, v);
    __m128 d = _mm_cvtepi32_ps(_mm_castps_si128(t)); // mask to float: 0 -> 0.0f, 0xFFFFFFFF -> -1.0f
    __m128 r = _mm_add_ps(i, d);

    return r;
#endif
}

VSNRAY_FORCE_INLINE float4 sqrt(float4 const& v)
{
    return _mm_sqrt_ps(v);
}

VSNRAY_FORCE_INLINE mask4 isinf(float4 const& v)
{
    VSNRAY_ALIGN(16) float values[4] = {};
    store(values, v);

    return mask4(
            std::isinf(values[0]),
            std::isinf(values[1]),
            std::isinf(values[2]),
            std::isinf(values[3])
            );
}

VSNRAY_FORCE_INLINE mask4 isnan(float4 const& v)
{
    return v != v;
}

VSNRAY_FORCE_INLINE mask4 isfinite(float4 const& v)
{
    return !(isinf(v) | isnan(v));
}

//-------------------------------------------------------------------------------------------------
//
//

template <unsigned N>
VSNRAY_FORCE_INLINE float4 rcp(float4 const& v)
{
    float4 x0 = _mm_rcp_ps(v);
    return rcp_step<N>(x0);
}

VSNRAY_FORCE_INLINE float4 rcp(float4 const& v)
{
    float4 x0 = _mm_rcp_ps(v);
    return rcp_step<1>(x0);
}

template <unsigned N>
VSNRAY_FORCE_INLINE float4 rsqrt(float4 const& v)
{
    float4 x0 = _mm_rsqrt_ps(v);
    return rsqrt_step<N>(v, x0);
}

VSNRAY_FORCE_INLINE float4 rsqrt(float4 const& v)
{
    float4 x0 = _mm_rsqrt_ps(v);
    return rsqrt_step<1>(v, x0);
}

VSNRAY_FORCE_INLINE float4 approx_rsqrt(float4 const& v)
{
    return _mm_rsqrt_ps(v);
}

} // simd
} // MATH_NAMESPACE
<|endoftext|>


<commit_before>#pragma once

// std
#include <atomic>
#include <memory>

// project
#include "LockingQueue.hpp"
#include "xlink/XLinkConnection.hpp"

// shared
#include "depthai-shared/datatype/RawBuffer.hpp"

namespace dai {

// DataQueue presents a way to access data coming from MyriadX
class DataOutputQueue {
    std::shared_ptr<LockingQueue<std::shared_ptr<RawBuffer>>> pQueue;
    LockingQueue<std::shared_ptr<RawBuffer>>& queue;
    std::thread readingThread;
    std::shared_ptr<std::atomic<bool>> pRunning;
    std::atomic<bool>& running;
    std::shared_ptr<std::string> pExceptionMessage;
    std::string& exceptionMessage;

    // const std::chrono::milliseconds READ_TIMEOUT{500};

   public:
    DataOutputQueue(std::shared_ptr<XLinkConnection> conn, const std::string& streamName, unsigned int maxSize = 60, bool overwrite = false);
    ~DataOutputQueue();

    template <class T>
    bool has() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(queue.front(val) && dynamic_cast<T*>(val.get())) {
            return true;
        }
        return false;
    }

    bool has() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        return !queue.empty();
    }

    template <class T>
    std::shared_ptr<T> tryGet() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.tryPop(val)) return nullptr;
        return std::dynamic_pointer_cast<T>(val);
    }

    std::shared_ptr<RawBuffer> tryGet() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> p = nullptr;
        if(!queue.tryPop(p)) {
            return nullptr;
        }
        return p;
    }

    template <class T>
    std::shared_ptr<T> get() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.waitAndPop(val)) {
            throw std::runtime_error(exceptionMessage.c_str());
            return nullptr;
        }
        return std::dynamic_pointer_cast<T>(val);
    }

    std::shared_ptr<RawBuffer> get() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.waitAndPop(val)) {
            throw std::runtime_error(exceptionMessage.c_str());
            return nullptr;
        }
        return val;
    }

    template <class T, typename Rep, typename Period>
    std::shared_ptr<T> get(std::chrono::duration<Rep, Period> timeout) {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.tryWaitAndPop(val, timeout)) {
            if(queue.destructed) throw std::runtime_error(exceptionMessage.c_str());
            return nullptr;
        }
        return std::dynamic_pointer_cast<T>(val);
    }

    template <typename Rep, typename Period>
    std::shared_ptr<RawBuffer> get(std::chrono::duration<Rep, Period> timeout) {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.tryWaitAndPop(val, timeout)) {
            if(queue.destructed) throw std::runtime_error(exceptionMessage.c_str());
            return nullptr;
        }
        return val;
    }
};

// DataInputQueue presents a way to write to MyriadX
class DataInputQueue {
    std::shared_ptr<LockingQueue<std::shared_ptr<RawBuffer>>> pQueue;
    LockingQueue<std::shared_ptr<RawBuffer>>& queue;
    std::thread writingThread;
    std::shared_ptr<std::atomic<bool>> pRunning;
    std::atomic<bool>& running;
    std::shared_ptr<std::string> pExceptionMessage;
    std::string& exceptionMessage;

   public:
    DataInputQueue(std::shared_ptr<XLinkConnection> conn, const std::string& streamName, unsigned int maxSize = 60, bool overwrite = false);
    ~DataInputQueue();

    void send(const std::shared_ptr<RawBuffer>& val);
    void sendSync(const std::shared_ptr<RawBuffer>& val);

    template <typename Rep, typename Period>
    bool send(const std::shared_ptr<RawBuffer>& val, std::chrono::duration<Rep, Period> timeout) {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        return queue.tryWaitAndPush(val, timeout);
    }
};

}  // namespace dai
<commit_msg>Updated DataQueue<commit_after>#pragma once

// std
#include <atomic>
#include <memory>

// project
#include "LockingQueue.hpp"
#include "xlink/XLinkConnection.hpp"

// shared
#include "depthai-shared/datatype/RawBuffer.hpp"

namespace dai {

// DataQueue presents a way to access data coming from MyriadX
class DataOutputQueue {
    std::shared_ptr<LockingQueue<std::shared_ptr<RawBuffer>>> pQueue;
    LockingQueue<std::shared_ptr<RawBuffer>>& queue;
    std::thread readingThread;
    std::shared_ptr<std::atomic<bool>> pRunning;
    std::atomic<bool>& running;
    std::shared_ptr<std::string> pExceptionMessage;
    std::string& exceptionMessage;

    // const std::chrono::milliseconds READ_TIMEOUT{500};

   public:
    DataOutputQueue(std::shared_ptr<XLinkConnection> conn, const std::string& streamName, unsigned int maxSize = 60, bool overwrite = false);
    ~DataOutputQueue();

    template <class T>
    bool has() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(queue.front(val) && dynamic_cast<T*>(val.get())) {
            return true;
        }
        return false;
    }

    bool has() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        return !queue.empty();
    }

    template <class T>
    std::shared_ptr<T> tryGet() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.tryPop(val)) return nullptr;
        return std::dynamic_pointer_cast<T>(val);
    }

    std::shared_ptr<RawBuffer> tryGet() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> p = nullptr;
        if(!queue.tryPop(p)) {
            return nullptr;
        }
        return p;
    }

    template <class T>
    std::shared_ptr<T> get() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.waitAndPop(val)) {
            throw std::runtime_error(exceptionMessage.c_str());
            return nullptr;
        }
        return std::dynamic_pointer_cast<T>(val);
    }

    std::shared_ptr<RawBuffer> get() {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.waitAndPop(val)) {
            throw std::runtime_error(exceptionMessage.c_str());
            return nullptr;
        }
        return val;
    }

    template <class T, typename Rep, typename Period>
    std::shared_ptr<T> get(std::chrono::duration<Rep, Period> timeout) {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.tryWaitAndPop(val, timeout)) {
            return nullptr;
        }
        return std::dynamic_pointer_cast<T>(val);
    }

    template <typename Rep, typename Period>
    std::shared_ptr<RawBuffer> get(std::chrono::duration<Rep, Period> timeout) {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        std::shared_ptr<RawBuffer> val = nullptr;
        if(!queue.tryWaitAndPop(val, timeout)) {
            return nullptr;
        }
        return val;
    }
};

// DataInputQueue presents a way to write to MyriadX
class DataInputQueue {
    std::shared_ptr<LockingQueue<std::shared_ptr<RawBuffer>>> pQueue;
    LockingQueue<std::shared_ptr<RawBuffer>>& queue;
    std::thread writingThread;
    std::shared_ptr<std::atomic<bool>> pRunning;
    std::atomic<bool>& running;
    std::shared_ptr<std::string> pExceptionMessage;
    std::string& exceptionMessage;

   public:
    DataInputQueue(std::shared_ptr<XLinkConnection> conn, const std::string& streamName, unsigned int maxSize = 60, bool overwrite = false);
    ~DataInputQueue();

    void send(const std::shared_ptr<RawBuffer>& val);
    void sendSync(const std::shared_ptr<RawBuffer>& val);

    template <typename Rep, typename Period>
    bool send(const std::shared_ptr<RawBuffer>& val, std::chrono::duration<Rep, Period> timeout) {
        if(!running) throw std::runtime_error(exceptionMessage.c_str());
        return queue.tryWaitAndPush(val, timeout);
    }
};

}  // namespace dai
<|endoftext|>


<commit_before>//
// Copyright (c) 2020 INRIA
//

#ifndef __eigenpy_user_type_hpp__
#define __eigenpy_user_type_hpp__

#include "eigenpy/fwd.hpp"
#include "eigenpy/numpy-type.hpp"
#include "eigenpy/register.hpp"

namespace eigenpy
{
  namespace internal
  {
    template<typename T, int type_code = NumpyEquivalentType<T>::type_code>
    struct SpecialMethods
    {
      inline static void copyswap(void * /*dst*/, void * /*src*/, int /*swap*/, void * /*arr*/) /*{}*/;
      inline static PyObject * getitem(void * /*ip*/, void * /*ap*/) /*{ return NULL; }*/;
      inline static int setitem(PyObject * /*op*/, void * /*ov*/, void * /*ap*/) /*{ return -1; }*/;
      inline static void copyswapn(void * /*dest*/, long /*dstride*/, void * /*src*/,
                            long /*sstride*/, long /*n*/, int /*swap*/, void * /*arr*/) /*{}*/;
      inline static npy_bool nonzero(void * /*ip*/, void * /*array*/) /*{ return (npy_bool)false; }*/;
      inline static void dotfunc(void * /*ip0_*/, npy_intp /*is0*/, void * /*ip1_*/, npy_intp /*is1*/,
                          void * /*op*/, npy_intp /*n*/, void * /*arr*/);
      inline static int fillwithscalar(void* buffer_, npy_intp length,
                                       void* value, void* arr);
//      static void cast(void * /*from*/, void * /*to*/, npy_intp /*n*/, void * /*fromarr*/, void * /*toarr*/) {};
    };

    template<typename T>
    struct OffsetOf
    {
      struct Data
      {
        char c;
        T v;
      };

      enum { value = offsetof(Data, v) };
    };

    template<typename T>
    struct SpecialMethods<T,NPY_USERDEF>
    {
      inline static void copyswap(void * dst, void * src, int swap, void * /*arr*/)
      {
//        std::cout << "copyswap" << std::endl;
        if (src != NULL)
        {
          T & t1 = *static_cast<T*>(dst);
          T & t2 = *static_cast<T*>(src);
          t1 = t2;
        }

        if(swap)
        {
          T & t1 = *static_cast<T*>(dst);
          T & t2 = *static_cast<T*>(src);
          std::swap(t1,t2);
        }
      }

      ///
      /// \brief Get a python object from an array
      ///        It returns a standard Python object from
      ///        a single element of the array object arr pointed to by data.
      /// \param[in] data Pointer to the first element of the C++ data stream
      /// \param[in] arr  Pointer to the first element of the Python object data stream
      ///
      /// \returns PyObject corresponding to the python datastream.
      ///
      inline static PyObject * getitem(void * ip, void * /*ap*/)
      {
//        std::cout << "getitem" << std::endl;
        T * elt_ptr = static_cast<T*>(ip);
        bp::object m(*elt_ptr);
        Py_INCREF(m.ptr());
        return m.ptr();
      }

      ///
      /// \brief Set a python object in an array.
      ///        It sets the Python object "item" into the array, arr, at the position
      ///        pointed to by data. This function deals with “misbehaved” arrays.
      ///        If successful, a zero is returned, otherwise, a negative one is returned
      ///        (and a Python error set).

      /// \param[in] src_obj  Pointer to the location of the python object
      /// \param[in] dest_ptr Pointer to the location in the array where the source object should be saved.
      /// \param[in] array Pointer to the location of the array
      ///
      /// \returns int Success(0) or Failure(-1)
      ///

      inline static int setitem(PyObject * src_obj, void * dest_ptr, void * array)
      {
//        std::cout << "setitem" << std::endl;
        if(array == NULL)
        {
          eigenpy::Exception("Cannot retrieve the type stored in the array.");
          return -1;
        }
        PyArrayObject * py_array = static_cast<PyArrayObject *>(array);
        PyArray_Descr * descr = PyArray_DTYPE(py_array);
        PyTypeObject * array_scalar_type = descr->typeobj;
        PyTypeObject * src_obj_type = Py_TYPE(src_obj);

        if(array_scalar_type != src_obj_type)
        {
          return -1;
        }

        bp::extract<T&> extract_src_obj(src_obj);
        if(!extract_src_obj.check())
        {
          std::stringstream ss;
          ss << "The input type is of wrong type. ";
          ss << "The expected type is " << bp::type_info(typeid(T)).name() << std::endl;
          eigenpy::Exception(ss.str());
          return -1;
        }

        const T & src = extract_src_obj();
        T & dest = *static_cast<T*>(dest_ptr);
        dest = src;

        return 0;
      }

      inline static void copyswapn(void * dst, long dstride, void * src, long sstride,
                                   long n, int swap, void * array)
      {
//        std::cout << "copyswapn" << std::endl;

        char *dstptr = static_cast<char*>(dst);
        char *srcptr = static_cast<char*>(src);

        PyArrayObject * py_array = static_cast<PyArrayObject *>(array);
        PyArray_CopySwapFunc * copyswap = PyArray_DESCR(py_array)->f->copyswap;

        for (npy_intp i = 0; i < n; i++)
        {
          copyswap(dstptr, srcptr, swap, array);
          dstptr += dstride;
          srcptr += sstride;
        }
      }

      inline static npy_bool nonzero(void * ip, void * array)
      {
//        std::cout << "nonzero" << std::endl;
        static const T ZeroValue = T(0);
        PyArrayObject * py_array = static_cast<PyArrayObject *>(array);
        if(py_array == NULL || PyArray_ISBEHAVED_RO(py_array))
        {
          const T & value = *static_cast<T*>(ip);
          return (npy_bool)(value != ZeroValue);
        }
        else
        {
          T tmp_value;
          PyArray_DESCR(py_array)->f->copyswap(&tmp_value, ip, PyArray_ISBYTESWAPPED(py_array),
                                               array);
          return (npy_bool)(tmp_value != ZeroValue);
        }
      }

      inline static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1,
                                 void * op, npy_intp n, void * /*arr*/)
      {
          T res = T(0);
          char *ip0 = (char*)ip0_, *ip1 = (char*)ip1_;
          npy_intp i;
          for(i = 0; i < n; i++)
          {

            res += *static_cast<T*>(static_cast<void*>(ip0))
            * *static_cast<T*>(static_cast<void*>(ip1));
            ip0 += is0;
            ip1 += is1;
          }
          *static_cast<T*>(op) = res;
      }

      inline static int fillwithscalar(void* buffer_, npy_intp length,
                                       void* value, void* /*arr*/)
      {
        T r = *(T*)value;
        T* buffer = (T*)buffer_;
        npy_intp i;
        for (i = 0; i < length; i++) {
          buffer[i] = r;
        }
        return 0;
      }

//      static void cast(void * from, void * to, npy_intp n, void * fromarr, void * toarr)
//      {
//      }

    };  //     struct SpecialMethods<T,NPY_USERDEF>

  } // namespace internal

  template<typename Scalar>
  int registerNewType(PyTypeObject * py_type_ptr = NULL)
  {
    // Check whether the type is a Numpy native type.
    // In this case, the registration is not required.
    if(isNumpyNativeType<Scalar>())
      return NumpyEquivalentType<Scalar>::type_code;

    // Retrieve the registered type for the current Scalar
    if(py_type_ptr == NULL)
    { // retrive the type from Boost.Python
      py_type_ptr = Register::getPyType<Scalar>();
    }

    if(Register::isRegistered(py_type_ptr))
      return Register::getTypeCode(py_type_ptr); // the type is already registered

    PyArray_GetItemFunc * getitem = &internal::SpecialMethods<Scalar>::getitem;
    PyArray_SetItemFunc * setitem = &internal::SpecialMethods<Scalar>::setitem;
    PyArray_NonzeroFunc * nonzero = &internal::SpecialMethods<Scalar>::nonzero;
    PyArray_CopySwapFunc * copyswap = &internal::SpecialMethods<Scalar>::copyswap;
    PyArray_CopySwapNFunc * copyswapn = reinterpret_cast<PyArray_CopySwapNFunc*>(&internal::SpecialMethods<Scalar>::copyswapn);
    PyArray_DotFunc * dotfunc = &internal::SpecialMethods<Scalar>::dotfunc;
    PyArray_FillWithScalarFunc * fillwithscalar = &internal::SpecialMethods<Scalar>::fillwithscalar;
//    PyArray_CastFunc * cast = &internal::SpecialMethods<Scalar>::cast;

    int code = Register::registerNewType(py_type_ptr,
                                         &typeid(Scalar),
                                         sizeof(Scalar),
                                         internal::OffsetOf<Scalar>::value,
                                         getitem, setitem, nonzero,
                                         copyswap, copyswapn,
                                         dotfunc,
                                         fillwithscalar);

    call_PyArray_RegisterCanCast(call_PyArray_DescrFromType(NPY_OBJECT),
                                 code, NPY_NOSCALAR);

    return code;
  }

} // namespace eigenpy

#endif // __eigenpy_user_type_hpp__
<commit_msg>types: remove indent + add print<commit_after>//
// Copyright (c) 2020 INRIA
//

#ifndef __eigenpy_user_type_hpp__
#define __eigenpy_user_type_hpp__

#include "eigenpy/fwd.hpp"
#include "eigenpy/numpy-type.hpp"
#include "eigenpy/register.hpp"

namespace eigenpy
{
  namespace internal
  {
    template<typename T, int type_code = NumpyEquivalentType<T>::type_code>
    struct SpecialMethods
    {
      inline static void copyswap(void * /*dst*/, void * /*src*/, int /*swap*/, void * /*arr*/) /*{}*/;
      inline static PyObject * getitem(void * /*ip*/, void * /*ap*/) /*{ return NULL; }*/;
      inline static int setitem(PyObject * /*op*/, void * /*ov*/, void * /*ap*/) /*{ return -1; }*/;
      inline static void copyswapn(void * /*dest*/, long /*dstride*/, void * /*src*/,
                            long /*sstride*/, long /*n*/, int /*swap*/, void * /*arr*/) /*{}*/;
      inline static npy_bool nonzero(void * /*ip*/, void * /*array*/) /*{ return (npy_bool)false; }*/;
      inline static void dotfunc(void * /*ip0_*/, npy_intp /*is0*/, void * /*ip1_*/, npy_intp /*is1*/,
                          void * /*op*/, npy_intp /*n*/, void * /*arr*/);
      inline static int fillwithscalar(void* buffer_, npy_intp length,
                                       void* value, void* arr);
//      static void cast(void * /*from*/, void * /*to*/, npy_intp /*n*/, void * /*fromarr*/, void * /*toarr*/) {};
    };

    template<typename T>
    struct OffsetOf
    {
      struct Data
      {
        char c;
        T v;
      };

      enum { value = offsetof(Data, v) };
    };

    template<typename T>
    struct SpecialMethods<T,NPY_USERDEF>
    {
      inline static void copyswap(void * dst, void * src, int swap, void * /*arr*/)
      {
//        std::cout << "copyswap" << std::endl;
        if (src != NULL)
        {
          T & t1 = *static_cast<T*>(dst);
          T & t2 = *static_cast<T*>(src);
          t1 = t2;
        }

        if(swap)
        {
          T & t1 = *static_cast<T*>(dst);
          T & t2 = *static_cast<T*>(src);
          std::swap(t1,t2);
        }
      }

      ///
      /// \brief Get a python object from an array
      ///        It returns a standard Python object from
      ///        a single element of the array object arr pointed to by data.
      /// \param[in] data Pointer to the first element of the C++ data stream
      /// \param[in] arr  Pointer to the first element of the Python object data stream
      ///
      /// \returns PyObject corresponding to the python datastream.
      ///
      inline static PyObject * getitem(void * ip, void * /*ap*/)
      {
//        std::cout << "getitem" << std::endl;
        T * elt_ptr = static_cast<T*>(ip);
        bp::object m(*elt_ptr);
        Py_INCREF(m.ptr());
        return m.ptr();
      }

      ///
      /// \brief Set a python object in an array.
      ///        It sets the Python object "item" into the array, arr, at the position
      ///        pointed to by data. This function deals with “misbehaved” arrays.
      ///        If successful, a zero is returned, otherwise, a negative one is returned
      ///        (and a Python error set).

      /// \param[in] src_obj  Pointer to the location of the python object
      /// \param[in] dest_ptr Pointer to the location in the array where the source object should be saved.
      /// \param[in] array Pointer to the location of the array
      ///
      /// \returns int Success(0) or Failure(-1)
      ///

      inline static int setitem(PyObject * src_obj, void * dest_ptr, void * array)
      {
//        std::cout << "setitem" << std::endl;
        if(array == NULL)
        {
          eigenpy::Exception("Cannot retrieve the type stored in the array.");
          return -1;
        }
        PyArrayObject * py_array = static_cast<PyArrayObject *>(array);
        PyArray_Descr * descr = PyArray_DTYPE(py_array);
        PyTypeObject * array_scalar_type = descr->typeobj;
        PyTypeObject * src_obj_type = Py_TYPE(src_obj);

        if(array_scalar_type != src_obj_type)
        {
          return -1;
        }

        bp::extract<T&> extract_src_obj(src_obj);
        if(!extract_src_obj.check())
        {
          std::stringstream ss;
          ss << "The input type is of wrong type. ";
          ss << "The expected type is " << bp::type_info(typeid(T)).name() << std::endl;
          eigenpy::Exception(ss.str());
          return -1;
        }

        const T & src = extract_src_obj();
        T & dest = *static_cast<T*>(dest_ptr);
        dest = src;

        return 0;
      }

      inline static void copyswapn(void * dst, long dstride, void * src, long sstride,
                                   long n, int swap, void * array)
      {
//        std::cout << "copyswapn" << std::endl;

        char *dstptr = static_cast<char*>(dst);
        char *srcptr = static_cast<char*>(src);

        PyArrayObject * py_array = static_cast<PyArrayObject *>(array);
        PyArray_CopySwapFunc * copyswap = PyArray_DESCR(py_array)->f->copyswap;

        for (npy_intp i = 0; i < n; i++)
        {
          copyswap(dstptr, srcptr, swap, array);
          dstptr += dstride;
          srcptr += sstride;
        }
      }

      inline static npy_bool nonzero(void * ip, void * array)
      {
//        std::cout << "nonzero" << std::endl;
        static const T ZeroValue = T(0);
        PyArrayObject * py_array = static_cast<PyArrayObject *>(array);
        if(py_array == NULL || PyArray_ISBEHAVED_RO(py_array))
        {
          const T & value = *static_cast<T*>(ip);
          return (npy_bool)(value != ZeroValue);
        }
        else
        {
          T tmp_value;
          PyArray_DESCR(py_array)->f->copyswap(&tmp_value, ip, PyArray_ISBYTESWAPPED(py_array),
                                               array);
          return (npy_bool)(tmp_value != ZeroValue);
        }
      }

      inline static void dotfunc(void * ip0_, npy_intp is0, void * ip1_, npy_intp is1,
                                 void * op, npy_intp n, void * /*arr*/)
      {
//        std::cout << "dotfunc" << std::endl;
        T res(0);
        char *ip0 = (char*)ip0_, *ip1 = (char*)ip1_;
        npy_intp i;
        for(i = 0; i < n; i++)
        {

          res += *static_cast<T*>(static_cast<void*>(ip0))
          * *static_cast<T*>(static_cast<void*>(ip1));
          ip0 += is0;
          ip1 += is1;
        }
        *static_cast<T*>(op) = res;
      }

      inline static int fillwithscalar(void* buffer_, npy_intp length,
                                       void* value, void* /*arr*/)
      {
        T r = *(T*)value;
        T* buffer = (T*)buffer_;
        npy_intp i;
        for (i = 0; i < length; i++) {
          buffer[i] = r;
        }
        return 0;
      }

//      static void cast(void * from, void * to, npy_intp n, void * fromarr, void * toarr)
//      {
//      }

    };  //     struct SpecialMethods<T,NPY_USERDEF>

  } // namespace internal

  template<typename Scalar>
  int registerNewType(PyTypeObject * py_type_ptr = NULL)
  {
    // Check whether the type is a Numpy native type.
    // In this case, the registration is not required.
    if(isNumpyNativeType<Scalar>())
      return NumpyEquivalentType<Scalar>::type_code;

    // Retrieve the registered type for the current Scalar
    if(py_type_ptr == NULL)
    { // retrive the type from Boost.Python
      py_type_ptr = Register::getPyType<Scalar>();
    }

    if(Register::isRegistered(py_type_ptr))
      return Register::getTypeCode(py_type_ptr); // the type is already registered

    PyArray_GetItemFunc * getitem = &internal::SpecialMethods<Scalar>::getitem;
    PyArray_SetItemFunc * setitem = &internal::SpecialMethods<Scalar>::setitem;
    PyArray_NonzeroFunc * nonzero = &internal::SpecialMethods<Scalar>::nonzero;
    PyArray_CopySwapFunc * copyswap = &internal::SpecialMethods<Scalar>::copyswap;
    PyArray_CopySwapNFunc * copyswapn = reinterpret_cast<PyArray_CopySwapNFunc*>(&internal::SpecialMethods<Scalar>::copyswapn);
    PyArray_DotFunc * dotfunc = &internal::SpecialMethods<Scalar>::dotfunc;
    PyArray_FillWithScalarFunc * fillwithscalar = &internal::SpecialMethods<Scalar>::fillwithscalar;
//    PyArray_CastFunc * cast = &internal::SpecialMethods<Scalar>::cast;

    int code = Register::registerNewType(py_type_ptr,
                                         &typeid(Scalar),
                                         sizeof(Scalar),
                                         internal::OffsetOf<Scalar>::value,
                                         getitem, setitem, nonzero,
                                         copyswap, copyswapn,
                                         dotfunc,
                                         fillwithscalar);

    call_PyArray_RegisterCanCast(call_PyArray_DescrFromType(NPY_OBJECT),
                                 code, NPY_NOSCALAR);

    return code;
  }

} // namespace eigenpy

#endif // __eigenpy_user_type_hpp__
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/impl/cublas/cuda.hpp"

namespace etl {

#ifdef ETL_CUDA
template<typename T>
using gpu_handler = impl::cuda::cuda_memory<T>;
#else
template<typename>
using gpu_handler = int;
#endif

/*!
 * \brief Wrapper for opaque memory.
 *
 * This is used to give direct memory access to any expressions
 * without showing the complete type, acting as a form of type
 * erasure
 */
template <typename T, std::size_t D>
struct opaque_memory {
    static constexpr std::size_t n_dimensions = D; ///< The number of dimensions

    using value_type        = T;                    ///< The type of value
    using memory_type       = T*;                   ///< The type of memory
    using const_memory_type = std::add_const_t<T>*; ///< The type of const memory

private:
    T* memory;                             ///< The memory pointer
    const std::size_t etl_size;            ///< The full size of the matrix
    const std::array<std::size_t, D> dims; ///< The dimensions of the matrix
    gpu_handler<T>& _gpu_memory_handler;   ///< The GPU memory handler
    const order storage_order;             ///< The storage order

public:
    /*!
     * \brief Create a new opaque memory
     * \param memory The pointer to memory
     * \param size The size of the memory
     * \param dims The dimensions
     * \param handler The GPU memory handler
     * \param storage_order The Storage order
     */
    opaque_memory(const T* memory, std::size_t size, const std::array<std::size_t, D>& dims, const gpu_handler<T>& handler, order storage_order)
            : memory(const_cast<T*>(memory)),
              etl_size(size),
              dims(dims),
              _gpu_memory_handler(const_cast<gpu_handler<T>&>(handler)),
              storage_order(storage_order) {
        //Nothing else to init
    }

    /*!
     * \brief Returns the number of dimensions of the matrix
     * \return the number of dimensions of the matrix
     */
    static constexpr std::size_t dimensions() noexcept {
        return n_dimensions;
    }

    /*!
     * \brief Returns the size of the matrix, in O(1)
     * \return The size of the matrix
     */
    std::size_t size() const noexcept {
        return etl_size;
    }

    /*!
     * \brief Returns the Dth dimension of the matrix
     * \return The Dth dimension of the matrix
     */
    template <std::size_t DD>
    std::size_t dim() const noexcept {
        return dims[DD];
    }

    /*!
     * \brief Returns the DDth dimension of the matrix
     * \return The DDth dimension of the matrix
     */
    std::size_t dim(std::size_t DD) const noexcept {
        return dims[DD];
    }

    /*!
     * \brief Returns a pointer to the first element in memory.
     * \return a pointer tot the first element in memory.
     */
    memory_type memory_start() const noexcept {
        return &memory[0];
    }

    /*!
     * \brief Returns a pointer to the past-the-end element in memory.
     * \return a pointer tot the past-the-end element in memory.
     */
    memory_type memory_end() const noexcept {
        return &memory[etl_size];
    }

#ifdef ETL_CUDA
    /*!
     * \brief Indicates if the expression is allocated in GPU.
     * \return true if the expression is allocated in GPU, false otherwise
     */
    bool is_gpu_allocated() const noexcept {
        return _gpu_memory_handler.is_set();
    }

    /*!
     * \brief Evict the expression from GPU.
     */
    void gpu_evict() const noexcept {
        if (is_gpu_allocated()) {
            _gpu_memory_handler.reset();
        }
    }

    /*!
     * \brief Return GPU memory of this expression, if any.
     * \return a pointer to the GPU memory or nullptr if not allocated in GPU.
     */
    value_type* gpu_memory() const noexcept {
        return _gpu_memory_handler.get();
    }

    /*!
     * \brief Allocate memory on the GPU for the expression
     */
    void gpu_allocate() const {
        _gpu_memory_handler = impl::cuda::cuda_allocate_only<T>(etl_size);
    }

    /*!
     * \brief Allocate memory on the GPU for the expression, only if not already allocated
     */
    void gpu_allocate_if_necessary() const {
        if (!is_gpu_allocated()) {
            gpu_allocate();
        }
    }

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU.
     */
    void gpu_allocate_copy() const {
        _gpu_memory_handler = impl::cuda::cuda_allocate_copy(memory, etl_size);
    }

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU, only if not already allocated.
     */
    void gpu_allocate_copy_if_necessary() const {
        if (!is_gpu_allocated()) {
            gpu_allocate_copy();
        }
    }

    /*!
     * \brief Reallocate the GPU memory.
     * \param memory The new GPU memory (will be moved)
     */
    void gpu_reallocate(impl::cuda::cuda_memory<T>&& memory) {
        _gpu_memory_handler = std::move(memory);
    }

    /*!
     * \brief Release the GPU memory for another expression to use
     * \return A rvalue reference to the _gpu_memory_handler.
     */
    impl::cuda::cuda_memory<T>&& gpu_release() const {
        return std::move(_gpu_memory_handler);
    }

    /*!
     * \brief Copy back from the GPU to the expression memory if
     * necessary.
     */
    void gpu_copy_from_if_necessary() const {
        if (is_gpu_allocated()) {
            gpu_copy_from();
        }
    }

    /*!
     * \brief Copy back from the GPU to the expression memory.
     */
    void gpu_copy_from() const {
        cpp_assert(is_gpu_allocated(), "Cannot copy from unallocated GPU memory()");

        auto* gpu_ptr = gpu_memory();
        auto* cpu_ptr = memory;

        cpp_assert(!std::is_const<std::remove_pointer_t<decltype(gpu_ptr)>>::value, "copy_from should not be used on const memory");
        cpp_assert(!std::is_const<value_type>::value, "copy_from should not be used on const memory");

        cuda_check(cudaMemcpy(
            const_cast<std::remove_const_t<value_type>*>(cpu_ptr),
            const_cast<std::remove_const_t<value_type>*>(gpu_ptr),
            etl_size * sizeof(T), cudaMemcpyDeviceToHost));
    }

    /*!
     * \brief Copy back from the GPU to the expression memory.
     */
    void gpu_copy_to() const {
        cpp_assert(is_gpu_allocated(), "Cannot copy to unallocated GPU memory()");

        auto* gpu_ptr = gpu_memory();
        auto* cpu_ptr = memory;

        cuda_check(cudaMemcpy(
            const_cast<std::remove_const_t<value_type>*>(gpu_ptr),
            const_cast<std::remove_const_t<value_type>*>(cpu_ptr),
            etl_size * sizeof(T), cudaMemcpyHostToDevice));
    }
#else
    /*!
     * \brief Indicates if the expression is allocated in GPU.
     * \return true if the expression is allocated in GPU, false otherwise
     */
    bool is_gpu_allocated() const noexcept {
        return false;
    }

    /*!
     * \brief Evict the expression from GPU.
     */
    void gpu_evict() const noexcept {}

    /*!
     * \brief Return GPU memory of this expression, if any.
     * \return a pointer to the GPU memory or nullptr if not allocated in GPU.
     */
    value_type* gpu_memory() const noexcept {
        return nullptr;
    }

    /*!
     * \brief Allocate memory on the GPU for the expression
     */
    void gpu_allocate() const {}

    /*!
     * \brief Allocate memory on the GPU for the expression, only if not already allocated
     */
    void gpu_allocate_if_necessary() const {}

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU.
     */
    void gpu_allocate_copy() const {}

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU, only if not already allocated.
     */
    void gpu_allocate_copy_if_necessary() const {}

    /*!
     * \brief Reallocate the GPU memory.
     * \param memory The new GPU memory (will be moved)
     */
    void gpu_reallocate(impl::cuda::cuda_memory<T>&& memory) {
        cpp_unused(memory);
    }

    /*!
     * \brief Release the GPU memory for another expression to use
     * \return A rvalue reference to the gpu_memory_handler.
     */
    impl::cuda::cuda_memory<T>&& gpu_release() const {}

    /*!
     * \brief Copy back from the GPU to the expression memory if
     * necessary.
     */
    void gpu_copy_from_if_necessary() const {}

    /*!
     * \brief Copy back from the GPU to the expression memory.
     */
    void gpu_copy_from() const {}
#endif
};

} //end of namespace etl
<commit_msg>Avoid confusion<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/impl/cublas/cuda.hpp"

namespace etl {

#ifdef ETL_CUDA
template<typename T>
using gpu_handler = impl::cuda::cuda_memory<T>;
#else
template<typename>
using gpu_handler = int;
#endif

/*!
 * \brief Wrapper for opaque memory.
 *
 * This is used to give direct memory access to any expressions
 * without showing the complete type, acting as a form of type
 * erasure
 */
template <typename T, std::size_t D>
struct opaque_memory {
    static constexpr std::size_t n_dimensions = D; ///< The number of dimensions

    using value_type        = T;                    ///< The type of value
    using memory_type       = T*;                   ///< The type of memory
    using const_memory_type = std::add_const_t<T>*; ///< The type of const memory

private:
    T* memory;                             ///< The memory pointer
    const std::size_t etl_size;            ///< The full size of the matrix
    const std::array<std::size_t, D> dims; ///< The dimensions of the matrix
    gpu_handler<T>& _gpu_memory_handler;   ///< The GPU memory handler
    const order storage_order;             ///< The storage order

public:
    /*!
     * \brief Create a new opaque memory
     * \param memory The pointer to memory
     * \param size The size of the memory
     * \param dims The dimensions
     * \param handler The GPU memory handler
     * \param storage_order The Storage order
     */
    opaque_memory(const T* memory, std::size_t size, const std::array<std::size_t, D>& dims, const gpu_handler<T>& handler, order storage_order)
            : memory(const_cast<T*>(memory)),
              etl_size(size),
              dims(dims),
              _gpu_memory_handler(const_cast<gpu_handler<T>&>(handler)),
              storage_order(storage_order) {
        //Nothing else to init
    }

    /*!
     * \brief Returns the number of dimensions of the matrix
     * \return the number of dimensions of the matrix
     */
    static constexpr std::size_t dimensions() noexcept {
        return n_dimensions;
    }

    /*!
     * \brief Returns the size of the matrix, in O(1)
     * \return The size of the matrix
     */
    std::size_t size() const noexcept {
        return etl_size;
    }

    /*!
     * \brief Returns the Dth dimension of the matrix
     * \return The Dth dimension of the matrix
     */
    template <std::size_t DD>
    std::size_t dim() const noexcept {
        return dims[DD];
    }

    /*!
     * \brief Returns the DDth dimension of the matrix
     * \return The DDth dimension of the matrix
     */
    std::size_t dim(std::size_t DD) const noexcept {
        return dims[DD];
    }

    /*!
     * \brief Returns a pointer to the first element in memory.
     * \return a pointer tot the first element in memory.
     */
    memory_type memory_start() const noexcept {
        return &memory[0];
    }

    /*!
     * \brief Returns a pointer to the past-the-end element in memory.
     * \return a pointer tot the past-the-end element in memory.
     */
    memory_type memory_end() const noexcept {
        return &memory[etl_size];
    }

#ifdef ETL_CUDA
    /*!
     * \brief Indicates if the expression is allocated in GPU.
     * \return true if the expression is allocated in GPU, false otherwise
     */
    bool is_gpu_allocated() const noexcept {
        return _gpu_memory_handler.is_set();
    }

    /*!
     * \brief Evict the expression from GPU.
     */
    void gpu_evict() const noexcept {
        if (is_gpu_allocated()) {
            _gpu_memory_handler.reset();
        }
    }

    /*!
     * \brief Return GPU memory of this expression, if any.
     * \return a pointer to the GPU memory or nullptr if not allocated in GPU.
     */
    value_type* gpu_memory() const noexcept {
        return _gpu_memory_handler.get();
    }

    /*!
     * \brief Allocate memory on the GPU for the expression
     */
    void gpu_allocate() const {
        _gpu_memory_handler = impl::cuda::cuda_allocate_only<T>(etl_size);
    }

    /*!
     * \brief Allocate memory on the GPU for the expression, only if not already allocated
     */
    void gpu_allocate_if_necessary() const {
        if (!is_gpu_allocated()) {
            gpu_allocate();
        }
    }

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU.
     */
    void gpu_allocate_copy() const {
        _gpu_memory_handler = impl::cuda::cuda_allocate_copy(memory, etl_size);
    }

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU, only if not already allocated.
     */
    void gpu_allocate_copy_if_necessary() const {
        if (!is_gpu_allocated()) {
            gpu_allocate_copy();
        }
    }

    /*!
     * \brief Reallocate the GPU memory.
     * \param new_memory The new GPU memory (will be moved)
     */
    void gpu_reallocate(impl::cuda::cuda_memory<T>&& new_memory) {
        _gpu_memory_handler = std::move(new_memory);
    }

    /*!
     * \brief Release the GPU memory for another expression to use
     * \return A rvalue reference to the _gpu_memory_handler.
     */
    impl::cuda::cuda_memory<T>&& gpu_release() const {
        return std::move(_gpu_memory_handler);
    }

    /*!
     * \brief Copy back from the GPU to the expression memory if
     * necessary.
     */
    void gpu_copy_from_if_necessary() const {
        if (is_gpu_allocated()) {
            gpu_copy_from();
        }
    }

    /*!
     * \brief Copy back from the GPU to the expression memory.
     */
    void gpu_copy_from() const {
        cpp_assert(is_gpu_allocated(), "Cannot copy from unallocated GPU memory()");

        auto* gpu_ptr = gpu_memory();
        auto* cpu_ptr = memory;

        cpp_assert(!std::is_const<std::remove_pointer_t<decltype(gpu_ptr)>>::value, "copy_from should not be used on const memory");
        cpp_assert(!std::is_const<value_type>::value, "copy_from should not be used on const memory");

        cuda_check(cudaMemcpy(
            const_cast<std::remove_const_t<value_type>*>(cpu_ptr),
            const_cast<std::remove_const_t<value_type>*>(gpu_ptr),
            etl_size * sizeof(T), cudaMemcpyDeviceToHost));
    }

    /*!
     * \brief Copy back from the GPU to the expression memory.
     */
    void gpu_copy_to() const {
        cpp_assert(is_gpu_allocated(), "Cannot copy to unallocated GPU memory()");

        auto* gpu_ptr = gpu_memory();
        auto* cpu_ptr = memory;

        cuda_check(cudaMemcpy(
            const_cast<std::remove_const_t<value_type>*>(gpu_ptr),
            const_cast<std::remove_const_t<value_type>*>(cpu_ptr),
            etl_size * sizeof(T), cudaMemcpyHostToDevice));
    }
#else
    /*!
     * \brief Indicates if the expression is allocated in GPU.
     * \return true if the expression is allocated in GPU, false otherwise
     */
    bool is_gpu_allocated() const noexcept {
        return false;
    }

    /*!
     * \brief Evict the expression from GPU.
     */
    void gpu_evict() const noexcept {}

    /*!
     * \brief Return GPU memory of this expression, if any.
     * \return a pointer to the GPU memory or nullptr if not allocated in GPU.
     */
    value_type* gpu_memory() const noexcept {
        return nullptr;
    }

    /*!
     * \brief Allocate memory on the GPU for the expression
     */
    void gpu_allocate() const {}

    /*!
     * \brief Allocate memory on the GPU for the expression, only if not already allocated
     */
    void gpu_allocate_if_necessary() const {}

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU.
     */
    void gpu_allocate_copy() const {}

    /*!
     * \brief Allocate memory on the GPU for the expression and copy the values into the GPU, only if not already allocated.
     */
    void gpu_allocate_copy_if_necessary() const {}

    /*!
     * \brief Reallocate the GPU memory.
     * \param memory The new GPU memory (will be moved)
     */
    void gpu_reallocate(impl::cuda::cuda_memory<T>&& memory) {
        cpp_unused(memory);
    }

    /*!
     * \brief Release the GPU memory for another expression to use
     * \return A rvalue reference to the gpu_memory_handler.
     */
    impl::cuda::cuda_memory<T>&& gpu_release() const {}

    /*!
     * \brief Copy back from the GPU to the expression memory if
     * necessary.
     */
    void gpu_copy_from_if_necessary() const {}

    /*!
     * \brief Copy back from the GPU to the expression memory.
     */
    void gpu_copy_from() const {}
#endif
};

} //end of namespace etl
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_STRING_HPP
#define FLUSSPFERD_STRING_HPP

#include "convert.hpp"
#include "implementation/string.hpp"
#include <string>

namespace flusspferd {

class value;

/**
 * A Javascript string.
 *
 * @ingroup value_types
 */
class string : public Impl::string_impl {
public:
  string();
  string(value const &v);
  string(char const *str, std::size_t length = 0);
  string(char16_t const *str, std::size_t length);
  string(std::string const &s);
  string(std::basic_string<char16_t> const &s);
  string(Impl::string_impl const &s)
    : Impl::string_impl(s)
  { }

  ~string();

  string &operator=(string const &o);

  std::size_t length() const;

  bool empty() const {
    return !length();
  }

  std::string to_string() const;
  char const *c_str() const;

  std::basic_string<char16_t> to_utf16_string() const;
  char16_t const *data() const;

  string substr(size_t start, size_t length);

  static string concat(string const &a, string const &b);
};

/**
 * Compare two string%s for equality.
 *
 * @relates string
 */
bool operator==(string const &lhs, string const &rhs);

/**
 * Compare two string%s lexicographically.
 *
 * @return Whether @p lhs is lexicographically smaller than @p rhs.
 *
 * @relates string
 */
bool operator<(string const &lhs, string const &rhs);

template<>
struct detail::convert<string> {
  typedef to_value_helper<string> to_value;

  struct from_value {
    root_value root;

    string perform(value const &v) {
      string s = v.to_string();
      root = s;
      return s;
    }
  };
};

template<>
struct detail::convert<char const *> {
  typedef to_value_helper<char const *, string> to_value;

  struct from_value {
    root_value root;

    char const *perform(value const &v) {
      string s = v.to_string();
      root = s;
      return s.c_str();
    }
  };
};

template<>
struct detail::convert<std::string> {
  typedef to_value_helper<std::string, string> to_value;

  struct from_value {
    std::string perform(value const &v) {
      return v.to_string().to_string();
    }
  };
};

template<>
struct detail::convert<std::basic_string<char16_t> > {
  typedef std::basic_string<char16_t> string_t;

  typedef to_value_helper<string_t, string> to_value;

  struct from_value {
    string_t perform(value const &v) {
      return v.to_string().to_utf16_string();
    }
  };
};

}

#endif /* FLUSSPFERD_STRING_HPP */
<commit_msg>doc: some string docs<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_STRING_HPP
#define FLUSSPFERD_STRING_HPP

#include "convert.hpp"
#include "implementation/string.hpp"
#include <string>

namespace flusspferd {

class value;

/**
 * A Javascript string.
 *
 * @ingroup value_types
 */
class string : public Impl::string_impl {
public:
  /// Construct an empty string.
  string();

  /**
   * Construct a string from a value.
   *
   * @param v The value to convert to a string.
   */
  string(value const &v);

  /**
   * Construct a string from a UTF-8 input string.
   *
   * @param str The UTF-8 string.
   * @param length The length in bytes. If this is 0, std::strlen
   *            will be used to determine the length.
   */
  string(char const *str, std::size_t length = 0);
  string(char16_t const *str, std::size_t length);
  string(std::string const &s);
  string(std::basic_string<char16_t> const &s);
  string(Impl::string_impl const &s)
    : Impl::string_impl(s)
  { }

  ~string();

  string &operator=(string const &o);

  std::size_t length() const;

  bool empty() const {
    return !length();
  }

  std::string to_string() const;
  char const *c_str() const;

  std::basic_string<char16_t> to_utf16_string() const;
  char16_t const *data() const;

  string substr(size_t start, size_t length);

  static string concat(string const &a, string const &b);
};

/**
 * Compare two string%s for equality.
 *
 * @relates string
 */
bool operator==(string const &lhs, string const &rhs);

/**
 * Compare two string%s lexicographically.
 *
 * @return Whether @p lhs is lexicographically smaller than @p rhs.
 *
 * @relates string
 */
bool operator<(string const &lhs, string const &rhs);

template<>
struct detail::convert<string> {
  typedef to_value_helper<string> to_value;

  struct from_value {
    root_value root;

    string perform(value const &v) {
      string s = v.to_string();
      root = s;
      return s;
    }
  };
};

template<>
struct detail::convert<char const *> {
  typedef to_value_helper<char const *, string> to_value;

  struct from_value {
    root_value root;

    char const *perform(value const &v) {
      string s = v.to_string();
      root = s;
      return s.c_str();
    }
  };
};

template<>
struct detail::convert<std::string> {
  typedef to_value_helper<std::string, string> to_value;

  struct from_value {
    std::string perform(value const &v) {
      return v.to_string().to_string();
    }
  };
};

template<>
struct detail::convert<std::basic_string<char16_t> > {
  typedef std::basic_string<char16_t> string_t;

  typedef to_value_helper<string_t, string> to_value;

  struct from_value {
    string_t perform(value const &v) {
      return v.to_string().to_utf16_string();
    }
  };
};

}

#endif /* FLUSSPFERD_STRING_HPP */
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#ifdef TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)))

#else

#include <alloca.h>
#include <stdlib.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#endif

#endif

<commit_msg>Hopefully really fixed alloca.h for now.<commit_after>/*

Copyright (c) 2008, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_ALLOCA

#include "libtorrent/config.hpp"

#ifdef TORRENT_WINDOWS

#include <malloc.h>
#define TORRENT_ALLOCA(t, n) static_cast<t*>(_alloca(sizeof(t) * (n)))

#else

#if defined (_LINUX_) || defined (_CYGWIN_)
#include <alloca.h>
#elif defined (_FREEBSD_)
#include <stdlib.h>
#endif

#define TORRENT_ALLOCA(t, n) static_cast<t*>(alloca(sizeof(t) * (n)))

#endif

#endif

<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_ASSERT

#include "libtorrent/config.hpp"
#include <string>

#ifdef __GNUC__
std::string demangle(char const* name);
#endif

#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !defined(NDEBUG)

TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file, char const* function);
#define TORRENT_ASSERT(x) if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__)

#else
#define TORRENT_ASSERT(x) assert(x)
#endif

#endif

<commit_msg>put back #include <cassert><commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_ASSERT

#include "libtorrent/config.hpp"
#include <string>

#ifdef __GNUC__
std::string demangle(char const* name);
#endif

#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !defined(NDEBUG)

TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file, char const* function);
#define TORRENT_ASSERT(x) if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__)

#else
#include <cassert>
#define TORRENT_ASSERT(x) assert(x)
#endif

#endif

<|endoftext|>


<commit_before>/*

Copyright (c) 2005, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_CONFIG_HPP_INCLUDED
#define TORRENT_CONFIG_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/version.hpp>
#include <stdio.h> // for snprintf

#ifndef WIN32
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#endif

#ifndef PRId64
#ifdef _WIN32
#define PRId64 "I64d"
#else
#define PRId64 "lld"
#endif
#endif

// ======= GCC =========

#if defined __GNUC__

# if __GNUC__ >= 3
#  define TORRENT_DEPRECATED __attribute__ ((deprecated))
# endif

// GCC pre 4.0 did not have support for the visibility attribute
# if __GNUC__ >= 4
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __attribute__ ((visibility("default")))
#  endif
# endif

// ======= SUNPRO =========

#elif defined __SUNPRO_CC

# if __SUNPRO_CC >= 0x550
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __global
#  endif
# endif

// ======= MSVC =========

#elif defined BOOST_MSVC

#pragma warning(disable: 4258)
#pragma warning(disable: 4251)

# if defined(TORRENT_BUILDING_SHARED)
#  define TORRENT_EXPORT __declspec(dllexport)
# elif defined(TORRENT_LINKING_SHARED)
#  define TORRENT_EXPORT __declspec(dllimport)
# endif

#define TORRENT_DEPRECATED_PREFIX __declspec(deprecated)

#endif

// ======= PLATFORMS =========

// set up defines for target environments
#if (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __NetBSD__ \
	|| defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ \
	|| defined __FreeBSD_kernel__
#define TORRENT_BSD
#elif defined __linux__
#define TORRENT_LINUX
#elif defined __MINGW32__
#define TORRENT_MINGW
#elif defined WIN32
#define TORRENT_WINDOWS
#elif defined sun || defined __sun
#define TORRENT_SOLARIS
#elif defined __BEOS__ || defined __HAIKU__
#define TORRENT_BEOS
#include <storage/StorageDefs.h> // B_PATH_NAME_LENGTH
#define TORRENT_HAS_FALLOCATE 0
#if __GNUCC__ == 2
# if defined(TORRENT_BUILDING_SHARED)
#  define TORRENT_EXPORT __declspec(dllexport)
# elif defined(TORRENT_LINKING_SHARED)
#  define TORRENT_EXPORT __declspec(dllimport)
# endif
#endif
#else
#warning unknown OS, assuming BSD
#define TORRENT_BSD
#endif

#ifndef TORRENT_EXPORT
# define TORRENT_EXPORT
#endif

#ifndef TORRENT_DEPRECATED_PREFIX
#define TORRENT_DEPRECATED_PREFIX
#endif

#ifndef TORRENT_DEPRECATED
#define TORRENT_DEPRECATED
#endif

#ifndef TORRENT_USE_IPV6
#define TORRENT_USE_IPV6 1
#endif

#define TORRENT_USE_MLOCK 1
#define TORRENT_USE_READV 1
#define TORRENT_USE_WRITEV 1

#if !defined TORRENT_USE_IOSTREAM && !defined BOOST_NO_IOSTREAM
#define TORRENT_USE_IOSTREAM 1
#else
#define TORRENT_USE_IOSTREAM 0
#endif

#define TORRENT_USE_I2P 1

// set this to 1 to disable all floating point operations
// (disables some float-dependent APIs)
#define TORRENT_NO_FPU 0

// on windows, NAME_MAX refers to Unicode characters
// on linux it refers to bytes (utf-8 encoded)
// TODO: Make this count Unicode characters instead of bytes on windows

// windows
#if defined FILENAME_MAX
#define TORRENT_MAX_PATH FILENAME_MAX

// beos
#elif defined B_PATH_NAME_LENGTH
#defined TORRENT_MAX_PATH B_PATH_NAME_LENGTH

// solaris
#elif defined MAXPATH
#define TORRENT_MAX_PATH MAXPATH

// posix
#elif defined NAME_MAX
#define TORRENT_MAX_PATH NAME_MAX

// none of the above
#else
// this is the maximum number of characters in a
// path element / filename on windows
#define TORRENT_MAX_PATH 255
#warning unknown platform, assuming the longest path is 255

#endif

#ifdef TORRENT_WINDOWS

// class X needs to have dll-interface to be used by clients of class Y
#pragma warning(disable:4251)
// '_vsnprintf': This function or variable may be unsafe
#pragma warning(disable:4996)

#include <stdarg.h>

inline int snprintf(char* buf, int len, char const* fmt, ...)
{
	va_list lp;
	va_start(lp, fmt);
	int ret = _vsnprintf(buf, len, fmt, lp);
	va_end(lp);
	if (ret < 0) { buf[len-1] = 0; ret = len-1; }
	return ret;
}

#define strtoll _strtoi64
#else
#include <limits.h>
#endif

#if (defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)) && !defined (TORRENT_UPNP_LOGGING)
#define TORRENT_UPNP_LOGGING
#endif

// windows has its own functions to convert
// apple uses utf-8 as its locale, so no conversion
// is necessary
#if !defined TORRENT_WINDOWS && !defined __APPLE__
// libiconv presence, not implemented yet
#define TORRENT_USE_ICONV 1
#else
#define TORRENT_ISE_ICONV 0
#endif

#if defined UNICODE && !defined BOOST_NO_STD_WSTRING
#define TORRENT_USE_WSTRING 1
#else
#define TORRENT_USE_WSTRING 0
#endif // UNICODE

#ifndef TORRENT_HAS_FALLOCATE
#define TORRENT_HAS_FALLOCATE 1
#endif

#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
# define TORRENT_READ_HANDLER_MAX_SIZE 256
#endif

#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE)
# define TORRENT_WRITE_HANDLER_MAX_SIZE 256
#endif

#if defined _MSC_VER && _MSC_VER <= 1200
#define for if (false) {} else for
#endif

// determine what timer implementation we can use
// if one is already defined, don't pick one
// autmatically. This lets the user control this
// from the Jamfile
#if !defined TORRENT_USE_ABSOLUTE_TIME \
	&& !defined TORRENT_USE_QUERY_PERFORMANCE_TIMER \
	&& !defined TORRENT_USE_CLOCK_GETTIME \
	&& !defined TORRENT_USE_BOOST_DATE_TIME \
	&& !defined TORRENT_USE_SYSTEM_TIME

#if defined(__MACH__)
#define TORRENT_USE_ABSOLUTE_TIME 1
#elif defined(_WIN32)
#define TORRENT_USE_QUERY_PERFORMANCE_TIMER 1
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
#define TORRENT_USE_CLOCK_GETTIME 1
#elif defined(TORRENT_BEOS)
#define TORRENT_USE_SYSTEM_TIME 1
#else
#define TORRENT_USE_BOOST_DATE_TIME 1
#endif

#endif

#endif // TORRENT_CONFIG_HPP_INCLUDED

<commit_msg>updated config header to be slightly more structured<commit_after>/*

Copyright (c) 2005, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_CONFIG_HPP_INCLUDED
#define TORRENT_CONFIG_HPP_INCLUDED

#include <boost/config.hpp>
#include <boost/version.hpp>
#include <stdio.h> // for snprintf

#ifndef WIN32
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#endif

#ifndef PRId64
#ifdef _WIN32
#define PRId64 "I64d"
#else
#define PRId64 "lld"
#endif
#endif

// ======= GCC =========

#if defined __GNUC__

# if __GNUC__ >= 3
#  define TORRENT_DEPRECATED __attribute__ ((deprecated))
# endif

// GCC pre 4.0 did not have support for the visibility attribute
# if __GNUC__ >= 4
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __attribute__ ((visibility("default")))
#  endif
# endif

// ======= SUNPRO =========

#elif defined __SUNPRO_CC

# if __SUNPRO_CC >= 0x550
#  if defined(TORRENT_BUILDING_SHARED) || defined(TORRENT_LINKING_SHARED)
#   define TORRENT_EXPORT __global
#  endif
# endif

// ======= MSVC =========

#elif defined BOOST_MSVC

#pragma warning(disable: 4258)
#pragma warning(disable: 4251)

# if defined(TORRENT_BUILDING_SHARED)
#  define TORRENT_EXPORT __declspec(dllexport)
# elif defined(TORRENT_LINKING_SHARED)
#  define TORRENT_EXPORT __declspec(dllimport)
# endif

#define TORRENT_DEPRECATED_PREFIX __declspec(deprecated)

#endif

// ======= PLATFORMS =========

// set up defines for target environments
// ==== AMIGA ===
#if defined __AMIGA__ || defined __amigaos__ || defined __AROS__
#define TORRENT_AMIGA
#define TORRENT_USE_MLOCK 0
#define TORRENT_USE_WRITEV 0
#define TORRENT_USE_READV 0
#define TORRENT_USE_IPV6 0
#define TORRENT_USE_BOOST_THREAD 0
#define TORRENT_USE_IOSTREAM 0
// set this to 1 to disable all floating point operations
// (disables some float-dependent APIs)
#define TORRENT_NO_FPU 1
#define TORRENT_USE_I2P 0

// ==== Darwin/BSD ===
#elif (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __NetBSD__ \
	|| defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ \
	|| defined __FreeBSD_kernel__
#define TORRENT_BSD

// ==== LINUX ===
#elif defined __linux__
#define TORRENT_LINUX
#elif defined __MINGW32__
#define TORRENT_MINGW

// ==== WINDOWS ===
#elif defined WIN32
#define TORRENT_WINDOWS

// ==== SOLARIS ===
#elif defined sun || defined __sun
#define TORRENT_SOLARIS

// ==== BEOS ===
#elif defined __BEOS__ || defined __HAIKU__
#define TORRENT_BEOS
#include <storage/StorageDefs.h> // B_PATH_NAME_LENGTH
#define TORRENT_HAS_FALLOCATE 0
#if __GNUCC__ == 2
# if defined(TORRENT_BUILDING_SHARED)
#  define TORRENT_EXPORT __declspec(dllexport)
# elif defined(TORRENT_LINKING_SHARED)
#  define TORRENT_EXPORT __declspec(dllimport)
# endif
#endif
#else
#warning unknown OS, assuming BSD
#define TORRENT_BSD
#endif

// on windows, NAME_MAX refers to Unicode characters
// on linux it refers to bytes (utf-8 encoded)
// TODO: Make this count Unicode characters instead of bytes on windows

// windows
#if defined FILENAME_MAX
#define TORRENT_MAX_PATH FILENAME_MAX

// beos
#elif defined B_PATH_NAME_LENGTH
#define TORRENT_MAX_PATH B_PATH_NAME_LENGTH

// solaris
#elif defined MAXPATH
#define TORRENT_MAX_PATH MAXPATH

// posix
#elif defined NAME_MAX
#define TORRENT_MAX_PATH NAME_MAX

// none of the above
#else
// this is the maximum number of characters in a
// path element / filename on windows
#define TORRENT_MAX_PATH 255
#warning unknown platform, assuming the longest path is 255

#endif

#ifdef TORRENT_WINDOWS

// class X needs to have dll-interface to be used by clients of class Y
#pragma warning(disable:4251)
// '_vsnprintf': This function or variable may be unsafe
#pragma warning(disable:4996)

#include <stdarg.h>

inline int snprintf(char* buf, int len, char const* fmt, ...)
{
	va_list lp;
	va_start(lp, fmt);
	int ret = _vsnprintf(buf, len, fmt, lp);
	va_end(lp);
	if (ret < 0) { buf[len-1] = 0; ret = len-1; }
	return ret;
}

#define strtoll _strtoi64
#else
#include <limits.h>
#endif

#if (defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)) \
	&& !defined (TORRENT_UPNP_LOGGING) && TORRENT_USE_IOSTREAM
#define TORRENT_UPNP_LOGGING
#endif

// windows has its own functions to convert
// apple uses utf-8 as its locale, so no conversion
// is necessary
#if !defined TORRENT_WINDOWS && !defined __APPLE__ && !defined TORRENT_AMIGA
// libiconv presence, not implemented yet
#define TORRENT_USE_ICONV 1
#else
#define TORRENT_ISE_ICONV 0
#endif

#if defined UNICODE && !defined BOOST_NO_STD_WSTRING
#define TORRENT_USE_WSTRING 1
#else
#define TORRENT_USE_WSTRING 0
#endif // UNICODE

#ifndef TORRENT_HAS_FALLOCATE
#define TORRENT_HAS_FALLOCATE 1
#endif

#ifndef TORRENT_EXPORT
# define TORRENT_EXPORT
#endif

#ifndef TORRENT_DEPRECATED_PREFIX
#define TORRENT_DEPRECATED_PREFIX
#endif

#ifndef TORRENT_DEPRECATED
#define TORRENT_DEPRECATED
#endif

#ifndef TORRENT_USE_IPV6
#define TORRENT_USE_IPV6 1
#endif

#ifndef TORRENT_USE_MLOCK
#define TORRENT_USE_MLOCK 1
#endif

#ifndef TORRENT_USE_WRITEV
#define TORRENT_USE_WRITEV 1
#endif

#ifndef TORRENT_USE_READV
#define TORRENT_USE_READV 1
#endif

#ifndef TORRENT_NO_FPU
#define TORRENT_NO_FPU 0
#endif

#if !defined TORRENT_USE_IOSTREAM && !defined BOOST_NO_IOSTREAM
#define TORRENT_USE_IOSTREAM 1
#else
#define TORRENT_USE_IOSTREAM 0
#endif

#ifndef TORRENT_USE_I2P
#define TORRENT_USE_I2P 1
#endif

#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
# define TORRENT_READ_HANDLER_MAX_SIZE 256
#endif

#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE)
# define TORRENT_WRITE_HANDLER_MAX_SIZE 256
#endif

#if defined _MSC_VER && _MSC_VER <= 1200
#define for if (false) {} else for
#endif

// determine what timer implementation we can use
// if one is already defined, don't pick one
// autmatically. This lets the user control this
// from the Jamfile
#if !defined TORRENT_USE_ABSOLUTE_TIME \
	&& !defined TORRENT_USE_QUERY_PERFORMANCE_TIMER \
	&& !defined TORRENT_USE_CLOCK_GETTIME \
	&& !defined TORRENT_USE_BOOST_DATE_TIME \
	&& !defined TORRENT_USE_ECLOCK \
	&& !defined TORRENT_USE_SYSTEM_TIME

#if defined(__MACH__)
#define TORRENT_USE_ABSOLUTE_TIME 1
#elif defined(_WIN32)
#define TORRENT_USE_QUERY_PERFORMANCE_TIMER 1
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
#define TORRENT_USE_CLOCK_GETTIME 1
#elif defined(TORRENT_AMIGA)
#define TORRENT_USE_ECLOCK 1
#elif defined(TORRENT_BEOS)
#define TORRENT_USE_SYSTEM_TIME 1
#else
#define TORRENT_USE_BOOST_DATE_TIME 1
#endif

#endif

#endif // TORRENT_CONFIG_HPP_INCLUDED

<|endoftext|>