A library for working with phylogenetic and population genetic data.
v0.27.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-2022 Lucas Czech
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 <lczech@carnegiescience.edu>
23  Department of Plant Biology, Carnegie Institution For Science
24  260 Panama Street, Stanford, CA 94305, USA
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 // Compiler Attributes
60 // =================================================================================================
61 
62 // We define them here as specified by later standards.
63 // Using them this way allows us to easly switch them off (by turning them into empty statements).
64 // #define GENESIS_LIKELY [[likely]]
65 // #define GENESIS_UNLIKELY [[unlikely]]
66 #define GENESIS_LIKELY
67 #define GENESIS_UNLIKELY
68 
69 // =================================================================================================
70 // Shortcomings of the C++ 11 STL...
71 // =================================================================================================
72 
81 template<typename T, typename... Args>
82 std::unique_ptr<T> make_unique(Args&&... args)
83 {
84  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
85 }
86 
93 template <typename T>
95 public:
96 
97  explicit ArrowOperatorProxy( T const& v )
98  : t(v)
99  {}
100 
101  T* operator ->() const {
102  return &t;
103  }
104 
105 private:
106 
107  T t;
108 };
109 
110 template <typename T>
111 inline constexpr std::size_t hash_combine_32( std::size_t seed, T const& value )
112 {
113  return seed ^ ( std::hash<T>()( value ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 ));
114 }
115 
116 template <typename T>
117 inline constexpr std::size_t hash_combine_64( std::size_t seed, T const& value )
118 {
119  return seed ^ ( std::hash<T>()( value ) + 0x9e3779b97f4a7c16 + ( seed << 12 ) + ( seed >> 4 ));
120 }
121 
125 template <typename T>
126 inline constexpr std::size_t hash_combine( std::size_t seed, T const& value )
127 {
128  // We use a run-time check for the size of size_t,
129  // which however most likely is already resolved at compile time.
130  // The inner functions use the golden ratio phi = (1 + sqrt(5))/2 as an irrational number
131  // with random independent bits, by using its inverse and the max size:
132  // 2^64 / phi = 0x9e3779b97f4a7c16 for the 64bit version for example.
133  // Furthermore, shifting is added in order to spread bits around for greater diversity.
134  // This whole approach follows the Boost hash combine functions.
135 
136  static_assert(
137  ( sizeof( std::size_t ) == 4 ) || ( sizeof( std::size_t ) == 8 ),
138  "Need sizeof( std::size_t ) to be 4 or 8 (32bit or 64bit integer)"
139  );
140  return ( sizeof( std::size_t ) == 4 )
141  ? hash_combine_32( seed, value )
142  : hash_combine_64( seed, value )
143  ;
144 
145  // constexpr in C++11 cannot have multiple return values
146  // if( sizeof( std::size_t ) == 4 ) {
147  // return hash_combine_32( seed, value );
148  // } else if( sizeof( std::size_t ) == 8 ) {
149  // return hash_combine_64( seed, value );
150  // } else {
151  // throw std::runtime_error( "Invalid std::size_t size." );
152  // }
153 }
154 
155 } // namespace utils
156 } // namespace genesis
157 
158 #endif // include guard
genesis::utils::ArrowOperatorProxy::ArrowOperatorProxy
ArrowOperatorProxy(T const &v)
Definition: std.hpp:97
genesis::utils::ArrowOperatorProxy
Proxy class to hold an element accessible via arrow operator.
Definition: std.hpp:94
genesis::utils::hash_combine_32
constexpr std::size_t hash_combine_32(std::size_t seed, T const &value)
Definition: std.hpp:111
genesis::utils::hash_combine_64
constexpr std::size_t hash_combine_64(std::size_t seed, T const &value)
Definition: std.hpp:117
genesis::utils::ArrowOperatorProxy::operator->
T * operator->() const
Definition: std.hpp:101
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Returns a std::unique_ptr for a given type.
Definition: std.hpp:82
genesis::utils::hash_combine
constexpr 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:126