mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2026-06-25 04:53:17 -04:00
Squashed 'boost/' content from commit b4feb19f2
git-subtree-dir: boost git-subtree-split: b4feb19f287ee92d87a9624b5d36b7cf46aeadeb
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://boostorg.github.com/compute for more information.
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_COMPUTE_TYPES_COMPLEX_HPP
|
||||
#define BOOST_COMPUTE_TYPES_COMPLEX_HPP
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include <boost/compute/functional.hpp>
|
||||
#include <boost/compute/types/fundamental.hpp>
|
||||
#include <boost/compute/type_traits/make_vector_type.hpp>
|
||||
#include <boost/compute/type_traits/type_name.hpp>
|
||||
#include <boost/compute/detail/meta_kernel.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
meta_kernel& operator<<(meta_kernel &kernel, const std::complex<T> &x)
|
||||
{
|
||||
typedef typename std::complex<T> value_type;
|
||||
|
||||
kernel << "(" << type_name<value_type>() << ")"
|
||||
<< "(" << x.real() << ", " << x.imag() << ")";
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
// get<N>() result type specialization for std::complex<>
|
||||
template<size_t N, class T>
|
||||
struct get_result_type<N, std::complex<T> >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// get<N>() specialization for std::complex<>
|
||||
template<size_t N, class Arg, class T>
|
||||
inline meta_kernel& operator<<(meta_kernel &kernel,
|
||||
const invoked_get<N, Arg, std::complex<T> > &expr)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(N < 2);
|
||||
|
||||
return kernel << expr.m_arg << (N == 0 ? ".x" : ".y");
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
// returns the real component of a complex<T>
|
||||
template<class T>
|
||||
struct real
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
template<class Arg>
|
||||
detail::invoked_get<0, Arg, std::complex<T> >
|
||||
operator()(const Arg &x) const
|
||||
{
|
||||
return detail::invoked_get<0, Arg, std::complex<T> >(x);
|
||||
}
|
||||
};
|
||||
|
||||
// returns the imaginary component of a complex<T>
|
||||
template<class T>
|
||||
struct imag
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
template<class Arg>
|
||||
detail::invoked_get<1, Arg, std::complex<T> >
|
||||
operator()(const Arg &x) const
|
||||
{
|
||||
return detail::invoked_get<1, Arg, std::complex<T> >(x);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class Arg1, class Arg2, class T>
|
||||
struct invoked_complex_multiplies
|
||||
{
|
||||
typedef typename std::complex<T> result_type;
|
||||
|
||||
invoked_complex_multiplies(const Arg1 &x, const Arg2 &y)
|
||||
: m_x(x),
|
||||
m_y(y)
|
||||
{
|
||||
}
|
||||
|
||||
Arg1 m_x;
|
||||
Arg2 m_y;
|
||||
};
|
||||
|
||||
template<class Arg1, class Arg2, class T>
|
||||
inline meta_kernel& operator<<(meta_kernel &kernel,
|
||||
const invoked_complex_multiplies<Arg1, Arg2, T> &expr)
|
||||
{
|
||||
typedef typename std::complex<T> value_type;
|
||||
|
||||
kernel << "(" << type_name<value_type>() << ")"
|
||||
<< "(" << expr.m_x << ".x*" << expr.m_y << ".x-"
|
||||
<< expr.m_x << ".y*" << expr.m_y << ".y,"
|
||||
<< expr.m_x << ".y*" << expr.m_y << ".x+"
|
||||
<< expr.m_x << ".x*" << expr.m_y << ".y" << ")";
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
template<class Arg, class T>
|
||||
struct invoked_complex_conj
|
||||
{
|
||||
typedef typename std::complex<T> result_type;
|
||||
|
||||
invoked_complex_conj(const Arg &arg)
|
||||
: m_arg(arg)
|
||||
{
|
||||
}
|
||||
|
||||
Arg m_arg;
|
||||
};
|
||||
|
||||
template<class Arg, class T>
|
||||
inline meta_kernel& operator<<(meta_kernel &kernel,
|
||||
const invoked_complex_conj<Arg, T> &expr)
|
||||
{
|
||||
typedef typename std::complex<T> value_type;
|
||||
|
||||
kernel << "(" << type_name<value_type>() << ")"
|
||||
<< "(" << expr.m_arg << ".x" << ", -" << expr.m_arg << ".y" << ")";
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
// specialization for multiplies<T>
|
||||
template<class T>
|
||||
class multiplies<std::complex<T> > :
|
||||
public function<std::complex<T> (std::complex<T>, std::complex<T>)>
|
||||
{
|
||||
public:
|
||||
multiplies() :
|
||||
function<
|
||||
std::complex<T> (std::complex<T>, std::complex<T>)
|
||||
>("complex_multiplies")
|
||||
{
|
||||
}
|
||||
|
||||
template<class Arg1, class Arg2>
|
||||
detail::invoked_complex_multiplies<Arg1, Arg2, T>
|
||||
operator()(const Arg1 &x, const Arg2 &y) const
|
||||
{
|
||||
return detail::invoked_complex_multiplies<Arg1, Arg2, T>(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
// returns the complex conjugate of a complex<T>
|
||||
template<class T>
|
||||
struct conj
|
||||
{
|
||||
typedef typename std::complex<T> result_type;
|
||||
|
||||
template<class Arg>
|
||||
detail::invoked_complex_conj<Arg, T>
|
||||
operator()(const Arg &x) const
|
||||
{
|
||||
return detail::invoked_complex_conj<Arg, T>(x);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// type_name() specialization for std::complex
|
||||
template<class T>
|
||||
struct type_name_trait<std::complex<T> >
|
||||
{
|
||||
static const char* value()
|
||||
{
|
||||
typedef typename make_vector_type<T, 2>::type vector_type;
|
||||
|
||||
return type_name<vector_type>();
|
||||
}
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_TYPES_COMPLEX_HPP
|
||||
@@ -0,0 +1,172 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://boostorg.github.com/compute for more information.
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP
|
||||
#define BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP
|
||||
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/comma.hpp>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
|
||||
#include <boost/compute/cl.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
|
||||
// scalar data types
|
||||
typedef cl_char char_;
|
||||
typedef cl_uchar uchar_;
|
||||
typedef cl_short short_;
|
||||
typedef cl_ushort ushort_;
|
||||
typedef cl_int int_;
|
||||
typedef cl_uint uint_;
|
||||
typedef cl_long long_;
|
||||
typedef cl_ulong ulong_;
|
||||
typedef cl_float float_;
|
||||
typedef cl_double double_;
|
||||
|
||||
// converts uchar to ::boost::compute::uchar_
|
||||
#define BOOST_COMPUTE_MAKE_SCALAR_TYPE(scalar) \
|
||||
BOOST_PP_CAT(::boost::compute::scalar, _)
|
||||
|
||||
// converts float, 4 to ::boost::compute::float4_
|
||||
#define BOOST_COMPUTE_MAKE_VECTOR_TYPE(scalar, size) \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(::boost::compute::scalar, size), _)
|
||||
|
||||
// vector data types
|
||||
template<class Scalar, size_t N>
|
||||
class vector_type
|
||||
{
|
||||
public:
|
||||
typedef Scalar scalar_type;
|
||||
|
||||
vector_type()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
explicit vector_type(const Scalar scalar)
|
||||
{
|
||||
for(size_t i = 0; i < N; i++)
|
||||
m_value[i] = scalar;
|
||||
}
|
||||
|
||||
vector_type(const vector_type<Scalar, N> &other)
|
||||
{
|
||||
std::memcpy(m_value, other.m_value, sizeof(m_value));
|
||||
}
|
||||
|
||||
vector_type<Scalar, N>&
|
||||
operator=(const vector_type<Scalar, N> &other)
|
||||
{
|
||||
std::memcpy(m_value, other.m_value, sizeof(m_value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
Scalar& operator[](size_t i)
|
||||
{
|
||||
return m_value[i];
|
||||
}
|
||||
|
||||
Scalar operator[](size_t i) const
|
||||
{
|
||||
return m_value[i];
|
||||
}
|
||||
|
||||
bool operator==(const vector_type<Scalar, N> &other) const
|
||||
{
|
||||
return std::memcmp(m_value, other.m_value, sizeof(m_value)) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const vector_type<Scalar, N> &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
protected:
|
||||
scalar_type m_value[N];
|
||||
};
|
||||
|
||||
#define BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION(z, i, _) \
|
||||
BOOST_PP_COMMA_IF(i) scalar_type BOOST_PP_CAT(arg, i)
|
||||
#define BOOST_COMPUTE_VECTOR_TYPE_DECLARE_CTOR_ARGS(scalar, size) \
|
||||
BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION, _)
|
||||
#define BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_ARG(z, i, _) \
|
||||
m_value[i] = BOOST_PP_CAT(arg, i);
|
||||
#define BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_SINGLE_ARG(z, i, _) \
|
||||
m_value[i] = arg;
|
||||
|
||||
#define BOOST_COMPUTE_DECLARE_VECTOR_TYPE_CLASS(cl_scalar, size, class_name) \
|
||||
class class_name : public vector_type<cl_scalar, size> \
|
||||
{ \
|
||||
public: \
|
||||
class_name() { } \
|
||||
explicit class_name( scalar_type arg ) \
|
||||
{ \
|
||||
BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_SINGLE_ARG, _) \
|
||||
} \
|
||||
class_name( \
|
||||
BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION, _) \
|
||||
) \
|
||||
{ \
|
||||
BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_ARG, _) \
|
||||
} \
|
||||
};
|
||||
|
||||
#define BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, size) \
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPE_CLASS(BOOST_PP_CAT(cl_, scalar), \
|
||||
size, \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(scalar, size), _)) \
|
||||
\
|
||||
inline std::ostream& operator<<( \
|
||||
std::ostream &s, \
|
||||
const BOOST_COMPUTE_MAKE_VECTOR_TYPE(scalar, size) &v) \
|
||||
{ \
|
||||
s << BOOST_PP_STRINGIZE(BOOST_PP_CAT(scalar, size)) << "("; \
|
||||
for(size_t i = 0; i < size; i++){\
|
||||
s << v[i]; \
|
||||
if(i != size - 1){\
|
||||
s << ", "; \
|
||||
} \
|
||||
} \
|
||||
s << ")"; \
|
||||
return s; \
|
||||
}
|
||||
|
||||
#define BOOST_COMPUTE_DECLARE_VECTOR_TYPES(scalar) \
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 2) \
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 4) \
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 8) \
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 16) \
|
||||
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(char)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(uchar)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(short)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(ushort)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(int)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(uint)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(long)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(ulong)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(float)
|
||||
BOOST_COMPUTE_DECLARE_VECTOR_TYPES(double)
|
||||
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP
|
||||
@@ -0,0 +1,117 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://boostorg.github.com/compute for more information.
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_COMPUTE_TYPES_PAIR_HPP
|
||||
#define BOOST_COMPUTE_TYPES_PAIR_HPP
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/compute/functional/get.hpp>
|
||||
#include <boost/compute/type_traits/type_definition.hpp>
|
||||
#include <boost/compute/type_traits/type_name.hpp>
|
||||
#include <boost/compute/detail/meta_kernel.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// meta_kernel operator for std::pair literals
|
||||
template<class T1, class T2>
|
||||
inline meta_kernel&
|
||||
operator<<(meta_kernel &kernel, const std::pair<T1, T2> &x)
|
||||
{
|
||||
kernel << "(" << type_name<std::pair<T1, T2> >() << ")"
|
||||
<< "{" << kernel.make_lit(x.first) << ", "
|
||||
<< kernel.make_lit(x.second) << "}";
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
// inject_type() specialization for std::pair
|
||||
template<class T1, class T2>
|
||||
struct inject_type_impl<std::pair<T1, T2> >
|
||||
{
|
||||
void operator()(meta_kernel &kernel)
|
||||
{
|
||||
typedef std::pair<T1, T2> pair_type;
|
||||
|
||||
kernel.inject_type<T1>();
|
||||
kernel.inject_type<T2>();
|
||||
|
||||
kernel.add_type_declaration<pair_type>(type_definition<pair_type>());
|
||||
}
|
||||
};
|
||||
|
||||
// get<N>() result type specialization for std::pair<>
|
||||
template<class T1, class T2>
|
||||
struct get_result_type<0, std::pair<T1, T2> >
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct get_result_type<1, std::pair<T1, T2> >
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
// get<N>() specialization for std::pair<>
|
||||
template<size_t N, class Arg, class T1, class T2>
|
||||
inline meta_kernel& operator<<(meta_kernel &kernel,
|
||||
const invoked_get<N, Arg, std::pair<T1, T2> > &expr)
|
||||
{
|
||||
kernel.inject_type<std::pair<T1, T2> >();
|
||||
|
||||
return kernel << expr.m_arg << (N == 0 ? ".first" : ".second");
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
namespace detail {
|
||||
|
||||
// type_name() specialization for std::pair
|
||||
template<class T1, class T2>
|
||||
struct type_name_trait<std::pair<T1, T2> >
|
||||
{
|
||||
static const char* value()
|
||||
{
|
||||
static std::string name =
|
||||
std::string("_pair_") +
|
||||
type_name<T1>() + "_" + type_name<T2>() +
|
||||
"_t";
|
||||
|
||||
return name.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
// type_definition() specialization for std::pair
|
||||
template<class T1, class T2>
|
||||
struct type_definition_trait<std::pair<T1, T2> >
|
||||
{
|
||||
static std::string value()
|
||||
{
|
||||
typedef std::pair<T1, T2> pair_type;
|
||||
|
||||
std::stringstream declaration;
|
||||
declaration << "typedef struct {\n"
|
||||
<< " " << type_name<T1>() << " first;\n"
|
||||
<< " " << type_name<T2>() << " second;\n"
|
||||
<< "} " << type_name<pair_type>() << ";\n";
|
||||
|
||||
return declaration.str();
|
||||
}
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_TYPES_PAIR_HPP
|
||||
@@ -0,0 +1,173 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://boostorg.github.com/compute for more information.
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_COMPUTE_TYPES_STRUCT_HPP
|
||||
#define BOOST_COMPUTE_TYPES_STRUCT_HPP
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/preprocessor/expr_if.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/seq/fold_left.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/preprocessor/seq/transform.hpp>
|
||||
|
||||
#include <boost/compute/type_traits/type_definition.hpp>
|
||||
#include <boost/compute/type_traits/type_name.hpp>
|
||||
#include <boost/compute/detail/meta_kernel.hpp>
|
||||
#include <boost/compute/detail/variadic_macros.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
template<class Struct, class T>
|
||||
inline std::string adapt_struct_insert_member(T Struct::*, const char *name)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << " " << type_name<T>() << " " << name << ";\n";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
template<class Struct, class T, int N>
|
||||
inline std::string adapt_struct_insert_member(T (Struct::*)[N], const char *name)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << " " << type_name<T>() << " " << name << "[" << N << "]" << ";\n";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
/// \internal_
|
||||
#define BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_INSERT_MEMBER(r, type, member) \
|
||||
<< ::boost::compute::detail::adapt_struct_insert_member( \
|
||||
&type::member, BOOST_PP_STRINGIZE(member) \
|
||||
)
|
||||
|
||||
/// \internal_
|
||||
#define BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_STREAM_MEMBER(r, data, i, elem) \
|
||||
BOOST_PP_EXPR_IF(i, << ", ") << data.elem
|
||||
|
||||
/// \internal_
|
||||
#define BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE(s, struct_, member_) \
|
||||
sizeof(((struct_ *)0)->member_)
|
||||
|
||||
/// \internal_
|
||||
#define BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_ADD(s, x, y) (x+y)
|
||||
|
||||
/// \internal_
|
||||
#define BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_SUM(struct_, members_) \
|
||||
BOOST_PP_SEQ_FOLD_LEFT( \
|
||||
BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_ADD, \
|
||||
0, \
|
||||
BOOST_PP_SEQ_TRANSFORM( \
|
||||
BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE, struct_, members_ \
|
||||
) \
|
||||
)
|
||||
|
||||
/// \internal_
|
||||
///
|
||||
/// Returns true if struct_ contains no internal padding bytes (i.e. it is
|
||||
/// packed). members_ is a sequence of the names of the struct members.
|
||||
#define BOOST_COMPUTE_DETAIL_STRUCT_IS_PACKED(struct_, members_) \
|
||||
(sizeof(struct_) == BOOST_COMPUTE_DETAIL_STRUCT_MEMBER_SIZE_SUM(struct_, members_))
|
||||
|
||||
/// The BOOST_COMPUTE_ADAPT_STRUCT() macro makes a C++ struct/class available
|
||||
/// to OpenCL kernels.
|
||||
///
|
||||
/// \param type The C++ type.
|
||||
/// \param name The OpenCL name.
|
||||
/// \param members A tuple of the struct's members.
|
||||
///
|
||||
/// For example, to adapt a 2D particle struct with position (x, y) and
|
||||
/// velocity (dx, dy):
|
||||
/// \code
|
||||
/// // c++ struct definition
|
||||
/// struct Particle
|
||||
/// {
|
||||
/// float x, y;
|
||||
/// float dx, dy;
|
||||
/// };
|
||||
///
|
||||
/// // adapt struct for OpenCL
|
||||
/// BOOST_COMPUTE_ADAPT_STRUCT(Particle, Particle, (x, y, dx, dy))
|
||||
/// \endcode
|
||||
///
|
||||
/// After adapting the struct it can be used in Boost.Compute containers
|
||||
/// and with Boost.Compute algorithms:
|
||||
/// \code
|
||||
/// // create vector of particles
|
||||
/// boost::compute::vector<Particle> particles = ...
|
||||
///
|
||||
/// // function to compare particles by their x-coordinate
|
||||
/// BOOST_COMPUTE_FUNCTION(bool, sort_by_x, (Particle a, Particle b),
|
||||
/// {
|
||||
/// return a.x < b.x;
|
||||
/// });
|
||||
///
|
||||
/// // sort particles by their x-coordinate
|
||||
/// boost::compute::sort(
|
||||
/// particles.begin(), particles.end(), sort_by_x, queue
|
||||
/// );
|
||||
/// \endcode
|
||||
///
|
||||
/// Due to differences in struct padding between the host compiler and the
|
||||
/// device compiler, the \c BOOST_COMPUTE_ADAPT_STRUCT() macro requires that
|
||||
/// the adapted struct is packed (i.e. no padding bytes between members).
|
||||
///
|
||||
/// \see type_name()
|
||||
#define BOOST_COMPUTE_ADAPT_STRUCT(type, name, members) \
|
||||
BOOST_STATIC_ASSERT_MSG( \
|
||||
BOOST_COMPUTE_DETAIL_STRUCT_IS_PACKED(type, BOOST_COMPUTE_PP_TUPLE_TO_SEQ(members)), \
|
||||
"BOOST_COMPUTE_ADAPT_STRUCT() does not support structs with internal padding." \
|
||||
); \
|
||||
BOOST_COMPUTE_TYPE_NAME(type, name) \
|
||||
namespace boost { namespace compute { \
|
||||
template<> \
|
||||
inline std::string type_definition<type>() \
|
||||
{ \
|
||||
std::stringstream declaration; \
|
||||
declaration << "typedef struct __attribute__((packed)) {\n" \
|
||||
BOOST_PP_SEQ_FOR_EACH( \
|
||||
BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_INSERT_MEMBER, \
|
||||
type, \
|
||||
BOOST_COMPUTE_PP_TUPLE_TO_SEQ(members) \
|
||||
) \
|
||||
<< "} " << type_name<type>() << ";\n"; \
|
||||
return declaration.str(); \
|
||||
} \
|
||||
namespace detail { \
|
||||
template<> \
|
||||
struct inject_type_impl<type> \
|
||||
{ \
|
||||
void operator()(meta_kernel &kernel) \
|
||||
{ \
|
||||
kernel.add_type_declaration<type>(type_definition<type>()); \
|
||||
} \
|
||||
}; \
|
||||
inline meta_kernel& operator<<(meta_kernel &k, type s) \
|
||||
{ \
|
||||
return k << "(" << #name << "){" \
|
||||
BOOST_PP_SEQ_FOR_EACH_I( \
|
||||
BOOST_COMPUTE_DETAIL_ADAPT_STRUCT_STREAM_MEMBER, \
|
||||
s, \
|
||||
BOOST_COMPUTE_PP_TUPLE_TO_SEQ(members) \
|
||||
) \
|
||||
<< "}"; \
|
||||
} \
|
||||
}}}
|
||||
|
||||
#endif // BOOST_COMPUTE_TYPES_STRUCT_HPP
|
||||
@@ -0,0 +1,220 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://boostorg.github.com/compute for more information.
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_COMPUTE_TYPES_TUPLE_HPP
|
||||
#define BOOST_COMPUTE_TYPES_TUPLE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/preprocessor/enum.hpp>
|
||||
#include <boost/preprocessor/expr_if.hpp>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/compute/config.hpp>
|
||||
#include <boost/compute/functional/get.hpp>
|
||||
#include <boost/compute/type_traits/type_name.hpp>
|
||||
#include <boost/compute/detail/meta_kernel.hpp>
|
||||
|
||||
#ifndef BOOST_COMPUTE_NO_STD_TUPLE
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace detail {
|
||||
|
||||
// meta_kernel operators for boost::tuple literals
|
||||
#define BOOST_COMPUTE_PRINT_ELEM(z, n, unused) \
|
||||
BOOST_PP_EXPR_IF(n, << ", ") \
|
||||
<< kernel.make_lit(boost::get<n>(x))
|
||||
|
||||
#define BOOST_COMPUTE_PRINT_TUPLE(z, n, unused) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class T)> \
|
||||
inline meta_kernel& \
|
||||
operator<<(meta_kernel &kernel, \
|
||||
const boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> &x) \
|
||||
{ \
|
||||
return kernel \
|
||||
<< "(" \
|
||||
<< type_name<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> >() \
|
||||
<< ")" \
|
||||
<< "{" \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_ELEM, ~) \
|
||||
<< "}"; \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TUPLE, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_PRINT_TUPLE
|
||||
#undef BOOST_COMPUTE_PRINT_ELEM
|
||||
|
||||
// inject_type() specializations for boost::tuple
|
||||
#define BOOST_COMPUTE_INJECT_TYPE(z, n, unused) \
|
||||
kernel.inject_type<T ## n>();
|
||||
|
||||
#define BOOST_COMPUTE_INJECT_DECL(z, n, unused) \
|
||||
<< " " << type_name<T ## n>() << " v" #n ";\n"
|
||||
|
||||
#define BOOST_COMPUTE_INJECT_IMPL(z, n, unused) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class T)> \
|
||||
struct inject_type_impl<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
|
||||
{ \
|
||||
void operator()(meta_kernel &kernel) \
|
||||
{ \
|
||||
typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_TYPE, ~) \
|
||||
std::stringstream declaration; \
|
||||
declaration << "typedef struct {\n" \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_INJECT_DECL, ~) \
|
||||
<< "} " << type_name<tuple_type>() << ";\n"; \
|
||||
kernel.add_type_declaration<tuple_type>(declaration.str()); \
|
||||
} \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_INJECT_IMPL, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_INJECT_IMPL
|
||||
#undef BOOST_COMPUTE_INJECT_DECL
|
||||
#undef BOOST_COMPUTE_INJECT_TYPE
|
||||
|
||||
#ifdef BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
|
||||
// type_name() specializations for boost::tuple (without variadic templates)
|
||||
#define BOOST_COMPUTE_PRINT_TYPE(z, n, unused) \
|
||||
+ type_name<T ## n>() + "_"
|
||||
|
||||
#define BOOST_COMPUTE_PRINT_TYPE_NAME(z, n, unused) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class T)> \
|
||||
struct type_name_trait<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
|
||||
{ \
|
||||
static const char* value() \
|
||||
{ \
|
||||
static std::string name = \
|
||||
std::string("boost_tuple_") \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_PRINT_TYPE, ~) \
|
||||
"t"; \
|
||||
return name.c_str(); \
|
||||
} \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_PRINT_TYPE_NAME, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_PRINT_TYPE_NAME
|
||||
#undef BOOST_COMPUTE_PRINT_TYPE
|
||||
|
||||
#else
|
||||
template<size_t N, class T, class... Rest>
|
||||
struct write_tuple_type_names
|
||||
{
|
||||
void operator()(std::ostream &os)
|
||||
{
|
||||
os << type_name<T>() << "_";
|
||||
write_tuple_type_names<N-1, Rest...>()(os);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class... Rest>
|
||||
struct write_tuple_type_names<1, T, Rest...>
|
||||
{
|
||||
void operator()(std::ostream &os)
|
||||
{
|
||||
os << type_name<T>();
|
||||
}
|
||||
};
|
||||
|
||||
// type_name<> specialization for boost::tuple<...> (with variadic templates)
|
||||
template<class... T>
|
||||
struct type_name_trait<boost::tuple<T...>>
|
||||
{
|
||||
static const char* value()
|
||||
{
|
||||
static std::string str = make_type_name();
|
||||
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
static std::string make_type_name()
|
||||
{
|
||||
typedef typename boost::tuple<T...> tuple_type;
|
||||
|
||||
std::stringstream s;
|
||||
s << "boost_tuple_";
|
||||
write_tuple_type_names<
|
||||
boost::tuples::length<tuple_type>::value, T...
|
||||
>()(s);
|
||||
s << "_t";
|
||||
return s.str();
|
||||
}
|
||||
};
|
||||
#endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
|
||||
|
||||
#ifndef BOOST_COMPUTE_NO_STD_TUPLE
|
||||
// type_name<> specialization for std::tuple<T...>
|
||||
template<class... T>
|
||||
struct type_name_trait<std::tuple<T...>>
|
||||
{
|
||||
static const char* value()
|
||||
{
|
||||
static std::string str = make_type_name();
|
||||
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
static std::string make_type_name()
|
||||
{
|
||||
typedef typename std::tuple<T...> tuple_type;
|
||||
|
||||
std::stringstream s;
|
||||
s << "std_tuple_";
|
||||
write_tuple_type_names<
|
||||
std::tuple_size<tuple_type>::value, T...
|
||||
>()(s);
|
||||
s << "_t";
|
||||
return s.str();
|
||||
}
|
||||
};
|
||||
#endif // BOOST_COMPUTE_NO_STD_TUPLE
|
||||
|
||||
// get<N>() result type specialization for boost::tuple<>
|
||||
#define BOOST_COMPUTE_GET_RESULT_TYPE(z, n, unused) \
|
||||
template<size_t N, BOOST_PP_ENUM_PARAMS(n, class T)> \
|
||||
struct get_result_type<N, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
|
||||
{ \
|
||||
typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \
|
||||
typedef typename boost::tuples::element<N, T>::type type; \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_RESULT_TYPE, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_GET_RESULT_TYPE
|
||||
|
||||
|
||||
// get<N>() specialization for boost::tuple<>
|
||||
#define BOOST_COMPUTE_GET_N(z, n, unused) \
|
||||
template<size_t N, class Arg, BOOST_PP_ENUM_PARAMS(n, class T)> \
|
||||
inline meta_kernel& operator<<(meta_kernel &kernel, \
|
||||
const invoked_get<N, Arg, boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > &expr) \
|
||||
{ \
|
||||
typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> T; \
|
||||
BOOST_STATIC_ASSERT(N < size_t(boost::tuples::length<T>::value)); \
|
||||
kernel.inject_type<T>(); \
|
||||
return kernel << expr.m_arg << ".v" << uint_(N); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_GET_N, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_GET_N
|
||||
|
||||
} // end detail namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_TYPES_TUPLE_HPP
|
||||
Reference in New Issue
Block a user