1 ////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source
3 // License.  See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by:
8 // Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
9 //
10 // File created by:
11 // Alfredo Correa, correaa@llnl.gov, Lawrence Livermore National Laboratory
12 ////////////////////////////////////////////////////////////////////////////////
13 
14 #ifndef AFQMC_TTI_HPP
15 #define AFQMC_TTI_HPP
16 
17 namespace qmcplusplus
18 {
19 namespace afqmc
20 {
21 // checks if clas has a member function called reserve that accepts a vector of size_t
22 template<class T, typename = decltype(std::declval<T>().reserve(std::vector<std::size_t>{}))>
23 std::true_type has_reserve_with_vector_aux(T);
24 std::false_type has_reserve_with_vector_aux(...);
25 template<class V>
26 struct has_reserve_with_vector : decltype(has_reserve_with_vector_aux(std::declval<V>()))
27 {};
28 
29 // reserve with either vector or size_t
30 template<class Container, typename integer, typename = std::enable_if_t<has_reserve_with_vector<Container>{}>>
reserve_to_fit(Container & C,std::vector<integer> const & v)31 void reserve_to_fit(Container& C, std::vector<integer> const& v)
32 {
33   C.reserve(v);
34 }
35 
36 template<class Container, typename integer, typename = std::enable_if_t<not has_reserve_with_vector<Container>{}>>
reserve_to_fit(Container & C,std::vector<integer> const & v,double=0)37 void reserve_to_fit(Container& C, std::vector<integer> const& v, double = 0)
38 {
39   C.reserve(std::accumulate(v.begin(), v.end(), std::size_t(0)));
40 }
41 
42 
43 // checks for emplace_back(tuple<int,int,SPComplexType>)
44 using tp = std::tuple<int, int, SPComplexType>;
45 template<class T, typename = decltype(std::declval<T>().emplace_back(tp{}))>
46 std::true_type has_emplace_back_tp_aux(T);
47 std::false_type has_emplace_back_tp_aux(...);
48 template<class V>
49 struct has_emplace_back_tp : decltype(has_emplace_back_tp_aux(std::declval<V>()))
50 {};
51 
52 // checks for emplace(tuple<int,int,SPComplexType>)
53 template<class T, typename = decltype(std::declval<T>().emplace(tp{}))>
54 std::true_type has_emplace_tp_aux(T);
55 std::false_type has_emplace_tp_aux(...);
56 template<class V>
57 struct has_emplace_tp : decltype(has_emplace_tp_aux(std::declval<V>()))
58 {};
59 
60 // dispatch to emplace_back preferentially
61 template<class Container, class tp_, typename = std::enable_if_t<has_emplace_back_tp<Container>{}>>
emplace(Container & C,tp_ const & a)62 void emplace(Container& C, tp_ const& a)
63 {
64   C.emplace_back(a);
65 }
66 
67 // dispatch to emplace if exists (and emplace_back doesn't)
68 template<class Container,
69          class tp_,
70          typename = std::enable_if_t<not has_emplace_back_tp<Container>{}>,
71          typename = std::enable_if_t<has_emplace_tp<Container>{}>>
emplace(Container & C,tp_ const & a)72 void emplace(Container& C, tp_ const& a)
73 {
74   C.emplace(a);
75 }
76 
77 /*
78 // checks for emplace_back(tuple<int,int,SPComplexType>)
79 template<typename T> using tp = std::tuple<int,int,T>;
80 template<class Q, class T, typename = decltype(std::declval<T>().emplace_back(tp<Q>{}))>
81 std::true_type  has_emplace_back_tp_aux(T);
82 template<class Q>
83 std::false_type has_emplace_back_tp_aux(...);
84 template<class V, class Q> struct has_emplace_back_tp : decltype(has_emplace_back_tp_aux<Q>(std::declval<V>())){};
85 
86 // checks for emplace(tuple<int,int,SPComplexType>)
87 template<class Q, class T, typename = decltype(std::declval<T>().emplace(tp<Q>{}))>
88 std::true_type  has_emplace_tp_aux(T);
89 template<class Q>
90 std::false_type has_emplace_tp_aux(...);
91 template<class V, class Q> struct has_emplace_tp : decltype(has_emplace_tp_aux<Q>(std::declval<V>())){};
92 
93 // dispatch to emplace_back preferentially
94 template<
95     class Container,
96     typename T,
97     typename = std::enable_if_t<has_emplace_back_tp<Container,T>{}>
98 >
99 void emplace(Container& C, tp<T> const& a){
100     C.emplace_back(a);
101 }
102 
103 // dispatch to emplace if exists (and emplace_back doesn't)
104 template<
105     class Container,
106     typename T,
107     typename = std::enable_if_t<not has_emplace_back_tp<Container,T>{}>,
108     typename = std::enable_if_t<has_emplace_tp<Container,T>{}>
109 >
110 void emplace(Container& C, tp<T> const& a){
111     C.emplace(a);
112 }
113 */
114 } // namespace afqmc
115 
116 } // namespace qmcplusplus
117 
118 #endif
119