SimpleITK  
sitkMemberFunctionFactoryBase.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef sitkMemberFunctionFactoryBase_h
19#define sitkMemberFunctionFactoryBase_h
20
21#include "sitkConfigure.h"
23
24#include "Ancillary/type_list2.h"
25#include "Ancillary/FunctionTraits.h"
26
27#include <unordered_map>
28#include <functional>
29#include <tuple>
30
31namespace itk::simple::detail
32{
33
34// make hash function available in current name space to take priority
35
36template <typename T>
37struct hash : public std::hash<T>
38{};
39
41template <typename T>
42inline void
43hash_combine(std::size_t & seed, const T & val)
44{
45 // Code from boost
46 // Reciprocal of the golden ratio helps spread entropy
47 // and handles duplicates.
48 std::hash<T> hasher;
49 seed ^= hasher(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
50}
51
52template <typename S, typename T>
53struct hash<std::pair<S, T>>
54{
55 inline size_t
56 operator()(const std::pair<S, T> & val) const
57 {
58 size_t seed = 0;
59 hash_combine(seed, val.first);
60 hash_combine(seed, val.second);
61 return seed;
62 }
63};
64
65template <class... TupleArgs>
66struct hash<std::tuple<TupleArgs...>>
67{
68
69public:
70 size_t
71 operator()(std::tuple<TupleArgs...> tupleValue) const
72 {
73 size_t seed = 0;
74 std::apply([&seed](auto... tupleElement) { (hash_combine(seed, tupleElement), ...); }, tupleValue);
75 return seed;
76 }
77};
78
79
80template <typename TMemberFunctionPointer,
81 typename TKey,
82 class TContainer = std::unordered_map<TKey, TMemberFunctionPointer, hash<TKey>>>
84{
85protected:
86 using MemberFunctionType = TMemberFunctionPointer;
87 using ObjectType = typename ::detail::FunctionTraits<MemberFunctionType>::ClassType;
88 using MemberFunctionResultType = typename ::detail::FunctionTraits<MemberFunctionType>::ResultType;
89 using FunctionMapType = TContainer;
90
91
93
94public:
97 using FunctionObjectType = typename ::detail::FunctionTraits<MemberFunctionType>::FunctionObjectType;
98
99 [[nodiscard]] constexpr double
100 GetLoadFactor() const noexcept
101 {
102 return m_PFunction.load_factor();
103 }
104
105 [[nodiscard]] constexpr std::size_t
106 GetMaximumLoadFactor() const noexcept
107 {
108 return m_PFunction.max_load_factor();
109 }
110
111 [[nodiscard]] constexpr std::size_t
112 GetSize() const noexcept
113 {
114 return m_PFunction.size();
115 }
116
117 [[nodiscard]] constexpr std::size_t
118 GetMaxSize() const noexcept
119 {
120 return m_PFunction.max_size();
121 }
122
123protected:
124 using KeyType = TKey;
125
126
131 template <typename... Args>
132 static FunctionObjectType
133 BindObject(MemberFunctionResultType (ObjectType ::*pfunc)(Args...), ObjectType * objectPointer)
134 {
135 return [pfunc, objectPointer](Args... args) -> MemberFunctionResultType {
136 return std::invoke(pfunc, objectPointer, std::forward<Args>(args)...);
137 };
138 }
139
140 // maps of Keys to pointers to member functions
142};
143
144} // namespace itk::simple::detail
145
146#endif // sitkMemberFunctionFactoryBase_h
constexpr std::size_t GetMaximumLoadFactor() const noexcept
static FunctionObjectType BindObject(MemberFunctionResultType(ObjectType ::*pfunc)(Args...), ObjectType *objectPointer)
void hash_combine(std::size_t &seed, const T &val)
STL namespace.
size_t operator()(const std::pair< S, T > &val) const
size_t operator()(std::tuple< TupleArgs... > tupleValue) const