32 #ifndef SHARK_DATA_BATCHINTERFACEADAPTSTRUCT_H 33 #define SHARK_DATA_BATCHINTERFACEADAPTSTRUCT_H 35 #include <boost/fusion/sequence/intrinsic/swap.hpp> 36 #include <boost/fusion/algorithm/iteration/for_each.hpp> 37 #include <boost/fusion/algorithm/transformation/transform.hpp> 40 #include <boost/preprocessor/seq/transform.hpp> 41 #include "Impl/BoostFusion151DefineStructInl.hpp" 45 template<
class Archive>
46 struct ItemSerializer {
47 ItemSerializer(Archive& ar):m_ar(ar) {}
50 void operator()(T& o)
const{
59 CreateBatch(std::size_t
size):m_size(size) {}
61 template<
class>
struct result;
63 struct result<CreateBatch(T const&)> {
68 typename result<CreateBatch(T const&)>::type operator()(T
const& value)
const{
75 resize(std::size_t size1, std::size_t size2):m_size1(size1),m_size2(size2){};
77 void operator()(T& batch)
const{
87 template<
class>
struct result;
89 struct result<MakeRef(T const&)> {
90 typedef typename boost::range_reference<T>::type type;
93 MakeRef(std::size_t index):m_index(index){}
96 typename result<MakeRef(T const&) >::type operator()(T
const& container)
const{
97 return get(
const_cast<T&
>(container),m_index);
104 template<
class>
struct result;
106 struct result<MakeConstRef(T const&)> {
107 typedef typename boost::range_reference<T const>::type type;
110 MakeConstRef(std::size_t index):m_index(index){}
113 typename result<MakeConstRef(T const&) >::type operator()(T
const& container)
const{
114 return get(container,m_index);
120 template<
class FusionSequence>
121 struct FusionFacade:
public FusionSequence{
123 template<
class Sequence>
124 FusionFacade(
Sequence const& sequence):FusionSequence(sequence){}
128 struct isFusionFacade{
130 struct Big{
int big[100]; };
132 static Big tester(FusionFacade<S>*);
134 static Big tester(FusionFacade<S>
const*);
135 static char tester(...);
136 static Type* generator();
138 BOOST_STATIC_CONSTANT(std::size_t,
size =
sizeof(tester(generator())));
140 BOOST_STATIC_CONSTANT(
bool, value = (
size!= 1));
141 typedef boost::mpl::bool_<value> type;
148 return static_cast<S&
>(facade);
151 S
const&
fusionize(detail::FusionFacade<S>
const& facade){
152 return static_cast<S const&
>(facade);
156 typename boost::disable_if<detail::isFusionFacade<S>,S&>::type
161 typename boost::disable_if<detail::isFusionFacade<S>,S
const& >::type
166 #define SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL_IMPL(s,TYPE,ELEM)\ 167 ( typename Batch<BOOST_PP_TUPLE_ELEM(2, 0, ELEM)>::TYPE,BOOST_PP_TUPLE_ELEM(2, 1, ELEM)) 169 #define SHARK_TRANSFORM_TUPLELIST_IMPL(s, data,ELEM)\ 170 BOOST_PP_TUPLE_ELEM(2, 0, ELEM),BOOST_PP_TUPLE_ELEM(2, 1, ELEM) 171 #define SHARK_TRANSFORM_TUPLELIST(ELEMS)\ 172 BOOST_PP_SEQ_TRANSFORM(SHARK_TRANSFORM_TUPLELIST_IMPL, _ , ELEMS) 174 #define SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(TYPE,ATTRIBUTES)\ 175 SHARK_TRANSFORM_TUPLELIST(BOOST_PP_SEQ_TRANSFORM(\ 176 SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL_IMPL,\ 177 TYPE, BOOST_PP_CAT(SHARK_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END))) 179 #define SHARK_TRANSFORM_BATCH_ATTRIBUTES_IMPL(s,TYPE,ELEM)\ 180 ( Batch<BOOST_PP_TUPLE_ELEM(2, 0, ELEM)>::TYPE,BOOST_PP_TUPLE_ELEM(2, 1, ELEM)) 182 #define SHARK_TRANSFORM_BATCH_ATTRIBUTES(TYPE,ATTRIBUTES)\ 183 SHARK_TRANSFORM_TUPLELIST(BOOST_PP_SEQ_TRANSFORM(\ 184 SHARK_TRANSFORM_BATCH_ATTRIBUTES_IMPL,\ 185 TYPE, BOOST_PP_CAT(SHARK_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END))) 188 #define SHARK_CREATE_BATCH_REFERENCES_TPL(ATTRIBUTES)\ 190 SHARK_FUSION_DEFINE_STRUCT_REF_INLINE(FusionRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(reference,ATTRIBUTES))\ 191 SHARK_FUSION_DEFINE_STRUCT_CONST_REF_INLINE(FusionConstRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(const_reference,ATTRIBUTES))\ 193 struct reference: public detail::FusionFacade<FusionRef>{\ 194 template<class Batch>\ 195 reference(Batch& batch, std::size_t i)\ 196 :detail::FusionFacade<FusionRef>(boost::fusion::transform(fusionize(batch),detail::MakeRef(i))){}\ 197 template<class Other>\ 198 reference& operator= (Other const& other ){\ 199 fusionize(*this) = other;\ 202 reference& operator= (reference const& other ){\ 203 fusionize(*this) = other;\ 206 friend void swap(reference op1, reference op2){\ 207 boost::fusion::swap(op1,op2);\ 209 operator value_type()const{\ 211 boost::fusion::copy(fusionize(*this), ret);\ 215 struct const_reference: public detail::FusionFacade<FusionConstRef>{\ 217 const_reference& operator= (const_reference const& other );\ 219 template<class Batch>\ 220 const_reference(Batch& batch, std::size_t i)\ 221 :detail::FusionFacade<FusionConstRef>(boost::fusion::transform(fusionize(batch),detail::MakeConstRef(i))){}\ 222 operator value_type()const{\ 224 boost::fusion::copy(fusionize(*this), ret);\ 229 #define SHARK_CREATE_BATCH_REFERENCES(ATTRIBUTES)\ 231 SHARK_FUSION_DEFINE_STRUCT_REF_INLINE(FusionRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES(reference,ATTRIBUTES))\ 232 SHARK_FUSION_DEFINE_STRUCT_CONST_REF_INLINE(FusionConstRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES(const_reference,ATTRIBUTES))\ 234 struct reference: public detail::FusionFacade<FusionRef>{\ 235 template<class Batch>\ 236 reference(Batch& batch, std::size_t i)\ 237 :detail::FusionFacade<FusionRef>(boost::fusion::transform(fusionize(batch),detail::MakeRef(i))){}\ 238 template<class Other>\ 239 reference& operator= (Other const& other ){\ 240 fusionize(*this) = other;\ 243 reference& operator= (reference const& other ){\ 244 fusionize(*this) = other;\ 247 friend void swap(reference& op1, reference& op2){\ 248 boost::fusion::swap(op1,op2);\ 250 operator value_type()const{\ 252 boost::fusion::copy(fusionize(*this), ret);\ 256 struct const_reference: public detail::FusionFacade<FusionConstRef>{\ 257 template<class Batch>\ 258 const_reference(Batch& batch, std::size_t i)\ 259 :detail::FusionFacade<FusionConstRef>(boost::fusion::transform(fusionize(batch),detail::MakeConstRef(i))){}\ 260 template<class Other>\ 261 const_reference& operator= (Other const& other ){\ 262 fusionize(*this) = other;\ 265 operator value_type()const{\ 267 boost::fusion::copy(fusionize(*this), ret);\ 273 #define SHARK_CREATE_BATCH_ITERATORS()\ 274 typedef ProxyIterator<type, value_type, reference > iterator;\ 275 typedef ProxyIterator<const type, value_type, const_reference > const_iterator;\ 277 return iterator(*this,0);\ 279 const_iterator begin()const{\ 280 return const_iterator(*this,0);\ 283 return iterator(*this,size());\ 285 const_iterator end()const{\ 286 return const_iterator(*this,size());\ 316 #define SHARK_CREATE_BATCH_INTERFACE(NAME,ATTRIBUTES)\
318 SHARK_FUSION_DEFINE_STRUCT_INLINE(FusionType, SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(type,ATTRIBUTES))\
320 struct type: public detail::FusionFacade<FusionType>{\
321 typedef NAME value_type;\
323 SHARK_CREATE_BATCH_REFERENCES_TPL(ATTRIBUTES)\
324 SHARK_CREATE_BATCH_ITERATORS()\
327 type(std::size_t size1, std::size_t size2){\
328 resize(size1,size2);\
330 void resize(std::size_t batchSize, std::size_t elementSize){\
331 boost::fusion::for_each(fusionize(*this), detail::resize(batchSize,elementSize));\
334 friend void swap(type& op1, type& op2){\
335 boost::fusion::swap(fusionize(op1),fusionize(op2));\
337 std::size_t size()const{\
338 return shark::size(boost::fusion::at_c<0>(fusionize(*this)));\
340 template<class Archive>\
341 void serialize(Archive & archive,unsigned int version)\
343 boost::fusion::for_each(fusionize(*this), detail::ItemSerializer<Archive>(archive));\
346 typedef NAME value_type;\
347 typedef typename type::reference reference;\
348 typedef typename type::const_reference const_reference;\
349 typedef typename type::iterator iterator;\
350 typedef typename type::const_iterator const_iterator;\
352 static type createBatch(value_type const& input, std::size_t size = 1){\
354 boost::fusion::copy(boost::fusion::transform(input,detail::CreateBatch(size)),fusionize(batch));\
357 template<class Range>\
358 static type createBatchFromRange(Range const& range){\
359 std::size_t points = shark::size(range);\
360 type batch = createBatch(*range.begin(),points);\
361 typename boost::range_iterator<Range>::type pos = range.begin();\
362 for(std::size_t i = 0; i != points; ++i,++pos){\
363 get(batch,i) = *pos;\
367 static void resize(type& batch, std::size_t batchSize, std::size_t elements){\
368 batch.resize(batchSize,elements);\
399 #define SHARK_CREATE_BATCH_INTERFACE_NO_TPL(NAME,ATTRIBUTES)\ 401 SHARK_FUSION_DEFINE_STRUCT_INLINE(FusionType, SHARK_TRANSFORM_BATCH_ATTRIBUTES(type,ATTRIBUTES))\ 403 struct type: public detail::FusionFacade<FusionType>{\ 404 typedef NAME value_type;\ 406 SHARK_CREATE_BATCH_REFERENCES(ATTRIBUTES)\ 407 SHARK_CREATE_BATCH_ITERATORS()\ 410 type(std::size_t size1, std::size_t size2){\ 411 resize(size1,size2);\ 413 void resize(std::size_t batchSize, std::size_t elementSize){\ 414 boost::fusion::for_each(fusionize(*this), detail::resize(batchSize,elementSize));\ 417 friend void swap(type& op1, type& op2){\ 418 boost::fusion::swap(fusionize(op1),fusionize(op2));\ 420 std::size_t size()const{\ 421 return shark::size(boost::fusion::at_c<0>(fusionize(*this)));\ 423 template<class Archive>\ 424 void serialize(Archive & archive,unsigned int version)\ 426 boost::fusion::for_each(fusionize(*this), detail::ItemSerializer<Archive>(archive));\ 429 typedef NAME value_type;\ 430 typedef type::reference reference;\ 431 typedef type::const_reference const_reference;\ 432 typedef type::iterator iterator;\ 433 typedef type::const_iterator const_iterator;\ 435 static type createBatch(value_type const& input, std::size_t size = 1){\ 437 boost::fusion::copy(boost::fusion::transform(input,detail::CreateBatch(size)),fusionize(batch));\ 440 template<class Range>\ 441 static type createBatchFromRange(Range const& range){\ 442 std::size_t points = shark::size(range);\ 443 type batch = createBatch(*range.begin(),points);\ 444 typename boost::range_iterator<Range>::type pos = range.begin();\ 445 for(std::size_t i = 0; i != points; ++i,++pos){\ 446 get(batch,i) = *pos;\ 450 static void resize(type& batch, std::size_t batchSize, std::size_t elements){\ 451 batch.resize(batchSize,elements);\