ALPSCore reference
weight.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #pragma once
8 
12 
13 #include <alps/hdf5/archive.hpp>
16 
17 #include <boost/utility.hpp>
18 
19 #include <stdexcept>
20 #include <type_traits>
21 
22 namespace alps {
23  namespace accumulators {
24 
25  template<typename T> class base_wrapper;
26 
27  // this should be called namespace tag { struct weight; }
28  // but gcc <= 4.4 has lookup error, so name it different
29  struct weight_tag;
30 
31  template<typename T> struct has_feature<T, weight_tag> {
32  template<typename R, typename C> static char helper(R(C::*)() const);
33  template<typename C> static char check(std::integral_constant<std::size_t, sizeof(helper(&C::owns_weight))>*);
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;
37  };
38 
39  namespace detail {
40  struct no_weight_type {};
41  template <bool, typename T> struct weight_type_impl {
42  typedef no_weight_type type;
43  };
44  template <typename T> struct weight_type_impl<true, T> {
45  typedef typename T::weight_type type;
46  };
47  }
48 
49  template<typename T> struct weight_type {
50  typedef typename detail::weight_type_impl<has_feature<T, weight_tag>::type::value, T>::type type;
51  };
52 
53  template<typename T> base_wrapper<typename value_type<T>::type> const * weight(T const & arg) {
54  return arg.weight();
55  }
56 
57  namespace detail {
58 
59  template<typename A> typename std::enable_if<
62  >::type weight_impl(A const & acc) {
63  return weight(acc);
64  }
65 
66  template<typename A> typename std::enable_if<
67  !has_feature<A, weight_tag>::value
69  >::type weight_impl(A const &) {
70  throw std::runtime_error(std::string(typeid(A).name()) + " has no weight-method" + ALPS_STACKTRACE);
71  return NULL;
72  }
73  }
74 
75  namespace impl {
76 
77  template<typename T, typename B> class BaseWrapper<T, weight_tag, B> : public B {
78  public:
79  virtual bool has_weight() const = 0;
80  virtual base_wrapper<T> const * weight() const = 0;
81  };
82 
83  template<typename T, typename B> class DerivedWrapper<T, weight_tag, B> : public B {
84  public:
85  DerivedWrapper(): B() {}
86  DerivedWrapper(T const & arg): B(arg) {}
87 
89  base_wrapper<typename value_type<T>::type> const * weight() const { return detail::weight_impl(this->m_data); }
90  };
91 
92  }
93  }
94 }
base_wrapper< typename value_type< T >::type > const * weight() const
Definition: weight.hpp:89
std::integral_constant< bool, sizeof(char)==sizeof(check< T >0))> type
Definition: weight.hpp:35
detail::weight_type_impl< has_feature< T, weight_tag >::type::value, T >::type type
Definition: weight.hpp:50
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
base_wrapper< typename value_type< T >::type > const * weight(T const &arg)
Definition: weight.hpp:53