9 #include <alps/config.hpp> 16 #include <boost/cstdint.hpp> 19 #include <type_traits> 22 namespace accumulators {
28 typedef boost::uint64_t
type;
33 template<
typename C>
static char check(std::integral_constant<std::size_t,
sizeof(helper(&
C::count))>*);
34 template<
typename C>
static double check(...);
35 typedef std::integral_constant<bool, sizeof(char) == sizeof(check<T>(0))>
type;
36 constexpr
static bool value = type::value;
45 template<
typename A>
typename std::enable_if<
47 >
::type count_impl(A
const & acc) {
51 template<
typename A>
typename std::enable_if<
53 >
::type count_impl(A
const & acc) {
54 throw std::runtime_error(std::string(
typeid(A).name()) +
" has no count-method" +
ALPS_STACKTRACE);
62 template<
typename T,
typename B>
class Result<T, count_tag, B> :
public B {
66 typedef typename detail::make_scalar_result_type<impl::Result,T,count_tag,B>::type
scalar_result_type;
69 : m_count(count_type())
72 template<
typename A>
Result(A
const & acc)
73 : m_count(detail::count_impl(acc))
80 void operator()(T
const &);
83 throw std::runtime_error(
"No values can be added to a result" +
ALPS_STACKTRACE);
86 template<
typename S>
void print(S & os,
bool =
false)
const {
93 static std::size_t
rank() {
return 1; }
96 template<
typename U>
void operator+=(U
const & arg) { augadd(arg); }
97 template<
typename U>
void operator-=(U
const & arg) { augsub(arg); }
98 template<
typename U>
void operator*=(U
const & arg) { augmul(arg); }
99 template<
typename U>
void operator/=(U
const & arg) { augdiv(arg); }
106 template<
typename U>
void augadd(U
const & arg,
typename std::enable_if<std::is_scalar<U>::value,
int>::
type = 0) {
108 throw std::runtime_error(
"The results need measurements" +
ALPS_STACKTRACE);
111 template<
typename U>
void augadd(U
const & arg,
typename std::enable_if<!std::is_scalar<U>::value,
int>::
type = 0) {
112 if (m_count == 0 || arg.count() == 0)
113 throw std::runtime_error(
"Both results need measurements" +
ALPS_STACKTRACE);
114 m_count = std::min(m_count, arg.count());
118 template<
typename U>
void augsub(U
const & arg,
typename std::enable_if<std::is_scalar<U>::value,
int>::
type = 0) {
120 throw std::runtime_error(
"The results need measurements" +
ALPS_STACKTRACE);
123 template<
typename U>
void augsub(U
const & arg,
typename std::enable_if<!std::is_scalar<U>::value,
int>::
type = 0) {
124 if (m_count == 0 || arg.count() == 0)
125 throw std::runtime_error(
"Both results need measurements" +
ALPS_STACKTRACE);
126 m_count = std::min(m_count, arg.count());
130 template<
typename U>
void augmul(U
const & arg,
typename std::enable_if<std::is_scalar<U>::value,
int>::
type = 0) {
132 throw std::runtime_error(
"The results need measurements" +
ALPS_STACKTRACE);
135 template<
typename U>
void augmul(U
const & arg,
typename std::enable_if<!std::is_scalar<U>::value,
int>::
type = 0) {
136 if (m_count == 0 || arg.count() == 0)
137 throw std::runtime_error(
"Both results need measurements" +
ALPS_STACKTRACE);
138 m_count = std::min(m_count, arg.count());
142 template<
typename U>
void augdiv(U
const & arg,
typename std::enable_if<std::is_scalar<U>::value,
int>::
type = 0) {
144 throw std::runtime_error(
"The results need measurements" +
ALPS_STACKTRACE);
147 template<
typename U>
void augdiv(U
const & arg,
typename std::enable_if<!std::is_scalar<U>::value,
int>::
type = 0) {
148 if (m_count == 0 || arg.count() == 0)
149 throw std::runtime_error(
"Both results need measurements" +
ALPS_STACKTRACE);
150 m_count = std::min(m_count, arg.count());
157 template<
typename T,
typename B>
struct Accumulator<T, count_tag, B> :
public B {
168 : m_count(count_type())
179 throw std::runtime_error(
"Observable has no binary call operator" +
ALPS_STACKTRACE);
182 template<
typename S>
void print(S & os,
bool =
false)
const {
189 static std::size_t
rank() {
return 1; }
197 template <
typename A>
200 m_count += rhs.m_count;
204 void collective_merge(
208 void collective_merge(
218 template<
typename T,
typename B>
class BaseWrapper<T, count_tag, B> :
public B {
220 virtual bool has_count()
const = 0;
221 virtual boost::uint64_t
count()
const = 0;
224 template<
typename T,
typename B>
class DerivedWrapper<T, count_tag, B> :
public B {
231 typename boost::uint64_t
count()
const {
return detail::count_impl(this->m_data); }
void operator-=(U const &arg)
boost::uint64_t count() const
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 >())
detail::make_scalar_result_type< impl::Result, T, count_tag, B >::type scalar_result_type
void operator/=(U const &arg)
static std::size_t rank()
std::integral_constant< bool, sizeof(char)==sizeof(check< T >0))> type
void operator()(T const &, W)
detail::short_print_proxy< T const > short_print(T const &v, std::size_t p=6)
void operator()(T const &, W)
count_type< T >::type count_type
Encapsulation of an MPI communicator and some communicator-related operations.
void print(S &os, bool=false) const
boost::array< T, N > & operator+=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
void operator+=(U const &arg)
void reset(accumulator_wrapper &arg)
boost::array< T, N > & operator/=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
static std::size_t rank()
boost::array< T, N > & operator*=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
void operator*=(U const &arg)
void operator()(T const &)
void merge(const A &rhs)
Merge the counter of the given accumulator of type A into this counter.
Accumulator(Accumulator const &arg)
Accumulator(ArgumentPack const &, typename std::enable_if<!is_accumulator< ArgumentPack >::value, int >::type=0)
void print(S &os, bool=false) const
count_type< T >::type count_type
Result< T, count_tag, typename B::result_type > result_type
count_type< T >::type count(T const &arg)
DerivedWrapper(T const &arg)
boost::array< T, N > & operator-=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
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 >())