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"
45template<
class Archive>
46struct 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{
120template<
class FusionSequence>
121struct FusionFacade:
public FusionSequence{
123 template<
class Sequence>
124 FusionFacade(
Sequence const& sequence):FusionSequence(sequence){}
128struct 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);
156typename boost::disable_if<detail::isFusionFacade<S>,
S&>::type
161typename 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)\
190SHARK_FUSION_DEFINE_STRUCT_REF_INLINE(FusionRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(reference,ATTRIBUTES))\
191SHARK_FUSION_DEFINE_STRUCT_CONST_REF_INLINE(FusionConstRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(const_reference,ATTRIBUTES))\
193struct 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);\
215struct const_reference: public detail::FusionFacade<FusionConstRef>{\
217const_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)\
231SHARK_FUSION_DEFINE_STRUCT_REF_INLINE(FusionRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES(reference,ATTRIBUTES))\
232SHARK_FUSION_DEFINE_STRUCT_CONST_REF_INLINE(FusionConstRef, SHARK_TRANSFORM_BATCH_ATTRIBUTES(const_reference,ATTRIBUTES))\
234struct 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);\
256struct 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()\
274typedef ProxyIterator<type, value_type, reference > iterator;\
275typedef ProxyIterator<const type, value_type, const_reference > const_iterator;\
277 return iterator(*this,0);\
279const_iterator begin()const{\
280 return const_iterator(*this,0);\
283 return iterator(*this,size());\
285const_iterator end()const{\
286 return const_iterator(*this,size());\
317#define SHARK_CREATE_BATCH_INTERFACE(NAME,ATTRIBUTES)\
319 SHARK_FUSION_DEFINE_STRUCT_INLINE(FusionType, SHARK_TRANSFORM_BATCH_ATTRIBUTES_TPL(type,ATTRIBUTES))\
321 struct type: public detail::FusionFacade<FusionType>{\
322 typedef NAME value_type;\
324 SHARK_CREATE_BATCH_REFERENCES_TPL(ATTRIBUTES)\
325 SHARK_CREATE_BATCH_ITERATORS()\
328 type(std::size_t size1, std::size_t size2){\
329 resize(size1,size2);\
331 void resize(std::size_t batchSize, std::size_t elementSize){\
332 boost::fusion::for_each(fusionize(*this), detail::resize(batchSize,elementSize));\
335 friend void swap(type& op1, type& op2){\
336 boost::fusion::swap(fusionize(op1),fusionize(op2));\
338 std::size_t size()const{\
339 return batchSize(boost::fusion::at_c<0>(fusionize(*this)));\
341 reference operator[](std::size_t i){\
342 return *(begin()+i);\
344 const_reference operator[](std::size_t i)const{\
345 return *(begin()+i);\
347 template<class Archive>\
348 void serialize(Archive & archive,unsigned int version)\
350 boost::fusion::for_each(fusionize(*this), detail::ItemSerializer<Archive>(archive));\
353 typedef NAME value_type;\
354 typedef typename type::reference reference;\
355 typedef typename type::const_reference const_reference;\
356 typedef typename type::iterator iterator;\
357 typedef typename type::const_iterator const_iterator;\
359 static type createBatch(value_type const& input, std::size_t size = 1){\
361 boost::fusion::copy(boost::fusion::transform(input,detail::CreateBatch(size)),fusionize(batch));\
364 template<class Iterator>\
365 static type createBatchFromRange(Iterator const& begin, Iterator const& end){\
366 std::size_t points = end - begin;\
367 type batch = createBatch(*begin,points);\
368 Iterator pos = begin;\
369 for(std::size_t i = 0; i != points; ++i,++pos){\
370 getBatchElement(batch,i) = *pos;\
374 static void resize(type& batch, std::size_t batchSize, std::size_t elements){\
375 batch.resize(batchSize,elements);\
378 static std::size_t size(T const& batch){return batch.size();}\
381 static typename T::reference get(T& batch, std::size_t i){\
385 static const_reference get(T const& batch, std::size_t i){\
389 static typename T::iterator begin(T& batch){\
390 return batch.begin();\
393 static const_iterator begin(T const& batch){\
394 return batch.begin();\
397 static typename T::iterator end(T& batch){\
401 static const_iterator end(T const& batch){\
433#define SHARK_CREATE_BATCH_INTERFACE_NO_TPL(NAME,ATTRIBUTES)\
435 SHARK_FUSION_DEFINE_STRUCT_INLINE(FusionType, SHARK_TRANSFORM_BATCH_ATTRIBUTES(type,ATTRIBUTES))\
437 struct type: public detail::FusionFacade<FusionType>{\
438 typedef NAME value_type;\
440 SHARK_CREATE_BATCH_REFERENCES(ATTRIBUTES)\
441 SHARK_CREATE_BATCH_ITERATORS()\
444 type(std::size_t size1, std::size_t size2){\
445 resize(size1,size2);\
447 void resize(std::size_t batchSize, std::size_t elementSize){\
448 boost::fusion::for_each(fusionize(*this), detail::resize(batchSize,elementSize));\
450 reference operator[](std::size_t i){\
451 return *(begin()+i);\
453 const_reference operator[](std::size_t i)const{\
454 return *(begin()+i);\
456 friend void swap(type& op1, type& op2){\
457 boost::fusion::swap(fusionize(op1),fusionize(op2));\
459 std::size_t size()const{\
460 return batchSize(boost::fusion::at_c<0>(fusionize(*this)));\
462 template<class Archive>\
463 void serialize(Archive & archive,unsigned int version)\
465 boost::fusion::for_each(fusionize(*this), detail::ItemSerializer<Archive>(archive));\
468 typedef NAME value_type;\
469 typedef type::reference reference;\
470 typedef type::const_reference const_reference;\
471 typedef type::iterator iterator;\
472 typedef type::const_iterator const_iterator;\
474 static type createBatch(value_type const& input, std::size_t size = 1){\
476 boost::fusion::copy(boost::fusion::transform(input,detail::CreateBatch(size)),fusionize(batch));\
479 template<class Iterator>\
480 static type createBatchFromRange(Iterator const& begin, Iterator const& end){\
481 std::size_t points = end - begin;\
482 type batch = createBatch(*begin,points);\
483 Iterator pos = begin;\
484 for(std::size_t i = 0; i != points; ++i,++pos){\
485 getBatchElement(batch,i) = *pos;\
489 static void resize(type& batch, std::size_t batchSize, std::size_t elements){\
490 batch.resize(batchSize,elements);\
493 static std::size_t size(T const& batch){return batch.size();}\
496 static typename T::reference get(T& batch, std::size_t i){\
500 static const_reference get(T const& batch, std::size_t i){\
504 static typename T::iterator begin(T& batch){\
505 return batch.begin();\
508 static const_iterator begin(T const& batch){\
509 return batch.begin();\
512 static typename T::iterator end(T& batch){\
516 static const_iterator end(T const& batch){\