9 #include <alps/config.hpp> 20 #include <boost/variant/variant.hpp> 21 #include <boost/variant/get.hpp> 28 #include <type_traits> 32 namespace accumulators {
35 typedef std::string printable_type;
37 template<
typename T>
struct add_base_wrapper_pointer {
38 typedef std::shared_ptr<base_wrapper<T> > type;
41 template<
typename... Types>
struct make_variant_type {
42 typedef boost::variant<typename add_base_wrapper_pointer<Types>::type...> type;
45 typedef typename make_variant_type<ALPS_ACCUMULATOR_VALUE_TYPES>::type variant_type;
47 template<
typename T,
typename A>
struct is_valid_argument : std::conditional<
48 std::is_scalar<A>::value
49 , typename std::is_convertible<T, A>::type
50 , typename std::is_same<T, A>::type
57 template <
typename LHSWT,
typename RHSWT>
58 struct is_compatible_op
59 : std::is_same<typename alps::numeric::scalar<typename LHSWT::value_type>::type,
60 typename RHSWT::value_type>
67 void check_ptr(
const std::shared_ptr<T>& ptr) {
68 if (!ptr)
throw std::runtime_error(
"Uninitialized accumulator accessed");
82 : m_variant(typename detail::add_base_wrapper_pointer<typename
value_type<T>::type>::type(
89 : m_variant(typename detail::add_base_wrapper_pointer<T>::type(arg))
99 result_wrapper & operator=(std::shared_ptr<result_wrapper>
const & rhs);
103 struct assign_visitor;
107 template<
typename T>
struct get_visitor:
public boost::static_visitor<> {
108 template<
typename X>
void operator()(X
const & ) {
109 throw std::runtime_error(std::string(
"Cannot cast observable") +
typeid(X).name() +
" to base type: " +
typeid(T).name() +
ALPS_STACKTRACE);
111 void operator()(
typename detail::add_base_wrapper_pointer<T>::type
const & arg) { value = arg; }
112 typename detail::add_base_wrapper_pointer<T>::type value;
116 get_visitor<T> visitor;
118 return *visitor.value;
123 template<
typename A>
struct extract_visitor:
public boost::static_visitor<A*> {
124 template<
typename T> A* operator()(T
const & arg) {
return &arg->template extract<A>(); }
128 extract_visitor<A> visitor;
131 template <
typename A> A
const &
extract()
const {
132 extract_visitor<A> visitor;
141 template<
template<
typename>
class AFROM,
142 template<
typename>
class ATO>
143 struct cast_visitor:
public boost::static_visitor<result_wrapper> {
146 typedef typename AFROM<value_type>::result_type raw_result_from_type;
147 typedef typename ATO<value_type>::result_type raw_result_to_type;
149 const raw_result_from_type& from=arg->template extract<raw_result_from_type>();
150 const raw_result_to_type& to=
dynamic_cast<const raw_result_to_type&
>(from);
169 template <
template<
typename>
class AFROM,
template<
typename>
class ATO>
171 cast_visitor<AFROM,ATO> visitor;
176 boost::uint64_t
count()
const;
179 #define ALPS_ACCUMULATOR_PROPERTY_PROXY(PROPERTY, TYPE) \ 181 template<typename T> struct PROPERTY ## _visitor: public boost::static_visitor<T> { \ 182 template<typename X> T apply(typename std::enable_if< \ 183 detail::is_valid_argument<typename TYPE <X>::type, T>::value, X const & \ 184 >::type arg) const { \ 185 return arg. PROPERTY (); \ 187 template<typename X> T apply(typename std::enable_if<! \ 188 detail::is_valid_argument<typename TYPE <X>::type, T>::value, X const & \ 190 throw std::logic_error(std::string("cannot convert: ") \ 191 + typeid(typename TYPE <X>::type).name() + " to " \ 192 + typeid(T).name() + ALPS_STACKTRACE); \ 194 template<typename X> T operator()(X const & arg) const { \ 195 return apply<typename X::element_type>(*arg); \ 199 template<typename T> typename TYPE <base_wrapper<T> >::type PROPERTY () const { \ 200 PROPERTY ## _visitor<typename TYPE <base_wrapper<T> >::type> visitor; \ 201 return boost::apply_visitor(visitor, m_variant); \ 206 #undef ALPS_ACCUMULATOR_PROPERTY_PROXY 215 void print(std::ostream & os,
bool terse=
false)
const;
219 template<
typename T>
struct transform_1_visitor:
public boost::static_visitor<> {
220 transform_1_visitor(boost::function<T(T)> f) : op(f) {}
221 template<
typename X>
void apply(
typename std::enable_if<
226 template<
typename X>
void apply(
typename std::enable_if<!
231 template<
typename X>
void operator()(X & arg)
const {
232 apply<typename X::element_type>(*arg);
234 boost::function<T(T)> op;
243 return transform(boost::function<T(T)>(op));
263 #define ALPS_ACCUMULATOR_OPERATOR_PROXY(OPNAME, AUGOPNAME, AUGOP, FUN) \ 265 struct FUN ## _self_visitor; \ 268 result_wrapper & AUGOPNAME (result_wrapper const & rhs); \ 270 result_wrapper & AUGOPNAME (long double arg); \ 271 result_wrapper OPNAME (result_wrapper const & arg) const; \ 273 result_wrapper OPNAME (long double arg) const; 278 #undef ALPS_ACCUMULATOR_OPERATOR_PROXY 281 result_wrapper inverse()
const;
283 result_wrapper
sin ()
const;
284 result_wrapper
cos ()
const;
285 result_wrapper
tan ()
const;
286 result_wrapper
sinh ()
const;
287 result_wrapper
cosh ()
const;
288 result_wrapper
tanh ()
const;
289 result_wrapper
asin ()
const;
290 result_wrapper
acos ()
const;
291 result_wrapper
atan ()
const;
292 result_wrapper
abs ()
const;
293 result_wrapper
sqrt ()
const;
294 result_wrapper
log ()
const;
295 result_wrapper
sq ()
const;
296 result_wrapper
cb ()
const;
297 result_wrapper
cbrt ()
const;
301 detail::variant_type m_variant;
349 template <
typename AFROM,
typename ATO>
351 const AFROM& raw_res_from=extract<AFROM>(res);
352 const ATO& raw_res_to=
dynamic_cast<const ATO&
>(raw_res_from);
370 template <
template<
typename>
class AFROM,
371 template<
typename>
class ATO>
373 return res.
cast<AFROM,ATO>();
396 template <
typename T>
397 static void check_nonempty_vector(
const T&) {}
401 template <
typename T>
402 static void check_nonempty_vector(
const std::vector<T>& vec) {
403 if (vec.empty())
throw std::runtime_error(
"Zero-sized vector observables are not allowed");
412 : m_variant(typename detail::add_base_wrapper_pointer<typename
value_type<T>::type>::type(
426 template<
typename T>
struct call_1_visitor:
public boost::static_visitor<> {
427 call_1_visitor(T
const & v) : value(v) {}
428 template<
typename X>
void apply(
typename std::enable_if<
433 template<
typename X>
void apply(
typename std::enable_if<!
438 template<
typename X>
void operator()(X & arg)
const {
440 apply<typename X::element_type>(*arg);
446 check_nonempty_vector(value);
467 boost::uint64_t
count()
const;
471 struct merge_visitor;
473 struct assign_visitor;
477 template<
typename T>
struct get_visitor:
public boost::static_visitor<> {
478 template<
typename X>
void operator()(X
const & ) {
479 throw std::runtime_error(std::string(
"Cannot cast observable") +
typeid(X).name() +
" to base type: " +
typeid(T).name() +
ALPS_STACKTRACE);
481 void operator()(
typename detail::add_base_wrapper_pointer<T>::type
const & arg) { value = arg; }
482 typename detail::add_base_wrapper_pointer<T>::type value;
486 get_visitor<T> visitor;
488 check_ptr(visitor.value);
489 return *visitor.value;
494 template<
typename A>
struct extract_visitor:
public boost::static_visitor<A*> {
495 template<
typename T> A* operator()(T
const & arg) { check_ptr(arg);
return &arg->template extract<A>(); }
499 extract_visitor<A> visitor;
504 #define ALPS_ACCUMULATOR_PROPERTY_PROXY(PROPERTY, TYPE) \ 506 template<typename T> struct PROPERTY ## _visitor: public boost::static_visitor<T> { \ 507 template<typename X> T apply(typename std::enable_if< \ 508 detail::is_valid_argument<typename TYPE <X>::type, T>::value, X const & \ 509 >::type arg) const { \ 510 return arg. PROPERTY (); \ 512 template<typename X> T apply(typename std::enable_if<! \ 513 detail::is_valid_argument<typename TYPE <X>::type, T>::value, X const & \ 515 throw std::logic_error(std::string("cannot convert: ") \ 516 + typeid(typename TYPE <X>::type).name() + " to " \ 517 + typeid(T).name() + ALPS_STACKTRACE); \ 519 template<typename X> T operator()(X const & arg) const { \ 521 return apply<typename X::element_type>(*arg); \ 525 template<typename T> typename TYPE <base_wrapper<T> >::type PROPERTY () const { \ 526 PROPERTY ## _visitor<typename TYPE <base_wrapper<T> >::type> visitor; \ 527 return boost::apply_visitor(visitor, m_variant); \ 531 #undef ALPS_ACCUMULATOR_PROPERTY_PROXY 542 std::shared_ptr<result_wrapper>
result()
const;
545 void print(std::ostream & os,
bool terse=
false)
const;
553 detail::variant_type m_variant;
result_wrapper operator-(long double arg1, result_wrapper const &arg2)
result_wrapper cast() const
Cast to the result_wrapper containing another raw result type, or throw.
result_wrapper cbrt(result_wrapper const &arg)
A const & extract() const
accumulator_wrapper(T arg)
constructor from raw accumulator
result_wrapper operator*(long double arg1, result_wrapper const &arg2)
void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
result_wrapper cos(result_wrapper const &arg)
impl::wrapper_set< result_wrapper > result_set
result_wrapper(base_wrapper< T > *arg)
result_wrapper transform(boost::function< T(T)> op) const
result_wrapper sqrt(result_wrapper const &arg)
result_wrapper cb(result_wrapper const &arg)
void operator()(T const &value)
result_wrapper sq(result_wrapper const &arg)
result_wrapper operator+(long double arg1, result_wrapper const &arg2)
detail::printable_type short_print(const result_wrapper &arg)
Return an "ostream-able" object to print result in a terse format.
mean_result< T > transform(no_prop, const transformer< T > &tf, const InResult &in)
Encapsulation of an MPI communicator and some communicator-related operations.
F::result_type apply_visitor(F &visitor, dictionary::const_iterator it)
Const-access visitor to a value by an iterator.
mean_type< T >::type mean(T const &arg)
result_wrapper cast(const result_wrapper &res)
Cast to the result_wrapper containing another raw result type, or throw.
A & extract(result_wrapper &m)
Return the "raw result" of type A held in the result_wrapper m, or throw.
result_wrapper log(result_wrapper const &arg)
std::ostream & operator<<(std::ostream &os, const result_wrapper &arg)
result_wrapper operator/(long double arg1, result_wrapper const &arg2)
void reset(accumulator_wrapper &arg)
result_wrapper cast_raw(const result_wrapper &res)
Cast to the result_wrapper containing another raw result type, or throw.
detail::printable_type full_print(const result_wrapper &arg)
Return an "ostream-able" object to print result in a verbose format.
result_wrapper tanh(result_wrapper const &arg)
error_type< T >::type error(T const &arg)
impl::wrapper_set< accumulator_wrapper > accumulator_set
#define ALPS_ACCUMULATOR_PROPERTY_PROXY(PROPERTY, TYPE)
result_wrapper acos(result_wrapper const &arg)
std::ostream & print(std::ostream &s, const dict_value &dv, bool terse)
#define ALPS_ACCUMULATOR_OPERATOR_PROXY(OPNAME, AUGOPNAME, AUGOP, FUN)
autocorrelation_type< T >::type autocorrelation(T const &arg)
result_wrapper sin(result_wrapper const &arg)
result_wrapper asin(result_wrapper const &arg)
traits< Acc >::result_type result(const Acc &acc)
result_wrapper tan(result_wrapper const &arg)
result_wrapper abs(result_wrapper const &arg)
result_wrapper sinh(result_wrapper const &arg)
std::vector< T > & merge(std::vector< T > &left, const std::vector< T > &right)
Vector merge.
accumulator_wrapper & operator<<(T const &value)
result_wrapper inverse() const
result_wrapper cosh(result_wrapper const &arg)
count_type< T >::type count(T const &arg)
result_wrapper atan(result_wrapper const &arg)
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
result_wrapper transform(T(*op)(T)) const