A toolkit for working with phylogenetic data.
v0.24.0
std.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_CORE_STD_H_
2 #define GENESIS_UTILS_CORE_STD_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2019 Lucas Czech and HITS gGmbH
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
34 #include <cstdint>
35 #include <memory>
36 #include <stdexcept>
37 #include <string>
38 
39 namespace genesis {
40 namespace utils {
41 
42 // =================================================================================================
43 // Expection Handling
44 // =================================================================================================
45 
46 // Try to find a macro that expands to the current function name.
47 #ifdef __cplusplus
48 # define GENESIS_FUNC __PRETTY_FUNCTION__
49 #else
50 # if defined __STDC_VERSION__
51 # define GENESIS_FUNC __func__
52 # else
53 # define GENESIS_FUNC __FUNCTION__
54 // # define GENESIS_FUNC ((const char *) 0)
55 # endif
56 #endif
57 
58 // =================================================================================================
59 // Shortcomings of the C++ 11 STL...
60 // =================================================================================================
61 
68 template<typename T, typename... Args>
69 std::unique_ptr<T> make_unique(Args&&... args)
70 {
71  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
72 }
73 
80 template <typename T>
82 public:
83 
84  explicit ArrowOperatorProxy( T const& v )
85  : t(v)
86  {}
87 
88  T* operator ->() const {
89  return &t;
90  }
91 
92 private:
93 
94  T t;
95 };
96 
97 template <typename T>
98 inline std::size_t hash_combine_32( std::size_t seed, T const& value )
99 {
100  return seed ^ ( std::hash<T>()( value ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 ));
101 }
102 
103 template <typename T>
104 inline std::size_t hash_combine_64( std::size_t seed, T const& value )
105 {
106  return seed ^ ( std::hash<T>()( value ) + 0x9e3779b97f4a7c16 + ( seed << 12 ) + ( seed >> 4 ));
107 }
108 
112 template <typename T>
113 inline std::size_t hash_combine( std::size_t seed, T const& value )
114 {
115  // We use a run-time check for the size of size_t,
116  // which however most likely is already resolved at compile time.
117  // The inner functions use the golden ratio phi = (1 + sqrt(5))/2 as an irrational number
118  // with random independent bits, by using its inverse and the max size:
119  // 2^64 / phi = 0x9e3779b97f4a7c16 for the 64bit version for example.
120  // Furthermore, shifting is added in order to spread bits around for greater diversity.
121  // This whole approach follows the Boost hash combine functions.
122 
123  if( sizeof( std::size_t ) == 4 ) {
124  return hash_combine_32( seed, value );
125  } else if( sizeof( std::size_t ) == 8 ) {
126  return hash_combine_64( seed, value );
127  } else {
128  throw std::runtime_error( "Invalid std::size_t size." );
129  }
130 }
131 
132 } // namespace utils
133 } // namespace genesis
134 
135 #endif // include guard
Proxy class to hold an element accessible via arrow operator.
Definition: std.hpp:81
std::size_t hash_combine(std::size_t seed, T const &value)
Combine a seed value (e.g., another hash) with the hash of a given type.
Definition: std.hpp:113
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
std::size_t hash_combine_32(std::size_t seed, T const &value)
Definition: std.hpp:98
std::unique_ptr< T > make_unique(Args &&... args)
Returns a std::unique_ptr for a given type.
Definition: std.hpp:69
std::size_t hash_combine_64(std::size_t seed, T const &value)
Definition: std.hpp:104