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{
78 BatchTraits<T>::type::resize(batch,m_size1,m_size2);
87 template<
class>
struct result;
89 struct result<MakeRef(T const&)> {
90 typedef typename BatchTraits<T>::type::reference type;
93 MakeRef(std::size_t index):m_index(index){}
96 typename result<MakeRef(T const&) >::type operator()(T
const& container)
const{
104 template<
class>
struct result;
106 struct result<MakeConstRef(T const&)> {
107 typedef typename BatchTraits<T>::type::const_reference type;
110 MakeConstRef(std::size_t index):m_index(index){}
113 typename result<MakeConstRef(T const&) >::type operator()(T
const& container)
const{
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);
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 batchSize(boost::fusion::at_c<0>(fusionize(*this)));\
340 reference operator[](std::size_t i){\
341 return *(begin()+i);\
343 const_reference operator[](std::size_t i)const{\
344 return *(begin()+i);\
346 template<class Archive>\
347 void serialize(Archive & archive,unsigned int version)\
349 boost::fusion::for_each(fusionize(*this), detail::ItemSerializer<Archive>(archive));\
352 typedef NAME value_type;\
353 typedef typename type::reference reference;\
354 typedef typename type::const_reference const_reference;\
355 typedef typename type::iterator iterator;\
356 typedef typename type::const_iterator const_iterator;\
358 static type createBatch(value_type const& input, std::size_t size = 1){\
360 boost::fusion::copy(boost::fusion::transform(input,detail::CreateBatch(size)),fusionize(batch));\
363 template<class Iterator>\
364 static type createBatchFromRange(Iterator const& begin, Iterator const& end){\
365 std::size_t points = end - begin;\
366 type batch = createBatch(*begin,points);\
367 Iterator pos = begin;\
368 for(std::size_t i = 0; i != points; ++i,++pos){\
369 getBatchElement(batch,i) = *pos;\
373 static void resize(type& batch, std::size_t batchSize, std::size_t elements){\
374 batch.resize(batchSize,elements);\
377 static std::size_t size(T const& batch){return batch.size();}\
380 static typename T::reference get(T& batch, std::size_t i){\
384 static const_reference get(T const& batch, std::size_t i){\
388 static typename T::iterator begin(T& batch){\
389 return batch.begin();\
392 static const_iterator begin(T const& batch){\
393 return batch.begin();\
396 static typename T::iterator end(T& batch){\
400 static const_iterator end(T const& batch){\
432 #define SHARK_CREATE_BATCH_INTERFACE_NO_TPL(NAME,ATTRIBUTES)\ 434 SHARK_FUSION_DEFINE_STRUCT_INLINE(FusionType, SHARK_TRANSFORM_BATCH_ATTRIBUTES(type,ATTRIBUTES))\ 436 struct type: public detail::FusionFacade<FusionType>{\ 437 typedef NAME value_type;\ 439 SHARK_CREATE_BATCH_REFERENCES(ATTRIBUTES)\ 440 SHARK_CREATE_BATCH_ITERATORS()\ 443 type(std::size_t size1, std::size_t size2){\ 444 resize(size1,size2);\ 446 void resize(std::size_t batchSize, std::size_t elementSize){\ 447 boost::fusion::for_each(fusionize(*this), detail::resize(batchSize,elementSize));\ 449 reference operator[](std::size_t i){\ 450 return *(begin()+i);\ 452 const_reference operator[](std::size_t i)const{\ 453 return *(begin()+i);\ 455 friend void swap(type& op1, type& op2){\ 456 boost::fusion::swap(fusionize(op1),fusionize(op2));\ 458 std::size_t size()const{\ 459 return batchSize(boost::fusion::at_c<0>(fusionize(*this)));\ 461 template<class Archive>\ 462 void serialize(Archive & archive,unsigned int version)\ 464 boost::fusion::for_each(fusionize(*this), detail::ItemSerializer<Archive>(archive));\ 467 typedef NAME value_type;\ 468 typedef type::reference reference;\ 469 typedef type::const_reference const_reference;\ 470 typedef type::iterator iterator;\ 471 typedef type::const_iterator const_iterator;\ 473 static type createBatch(value_type const& input, std::size_t size = 1){\ 475 boost::fusion::copy(boost::fusion::transform(input,detail::CreateBatch(size)),fusionize(batch));\ 478 template<class Iterator>\ 479 static type createBatchFromRange(Iterator const& begin, Iterator const& end){\ 480 std::size_t points = end - begin;\ 481 type batch = createBatch(*begin,points);\ 482 Iterator pos = begin;\ 483 for(std::size_t i = 0; i != points; ++i,++pos){\ 484 getBatchElement(batch,i) = *pos;\ 488 static void resize(type& batch, std::size_t batchSize, std::size_t elements){\ 489 batch.resize(batchSize,elements);\ 492 static std::size_t size(T const& batch){return batch.size();}\ 495 static typename T::reference get(T& batch, std::size_t i){\ 499 static const_reference get(T const& batch, std::size_t i){\ 503 static typename T::iterator begin(T& batch){\ 504 return batch.begin();\ 507 static const_iterator begin(T const& batch){\ 508 return batch.begin();\ 511 static typename T::iterator end(T& batch){\ 515 static const_iterator end(T const& batch){\