10 #ifndef smtk_resource_query_Factory_h
11 #define smtk_resource_query_Factory_h
13 #include "smtk/CoreExports.h"
18 #include "smtk/resource/query/BadTypeError.h"
19 #include "smtk/resource/query/Metadata.h"
20 #include "smtk/resource/query/Query.h"
23 #include <type_traits>
24 #include <unordered_set>
42 template<
typename QueryType>
50 template<
typename QueryType>
57 bool registerQuery(
Metadata&& metadata);
61 template<
typename Tuple>
64 return registerQueries<0, Tuple>();
68 template<
typename QueryType>
71 return unregisterQuery(QueryType::typeIndex());
75 bool unregisterQuery(std::size_t typeIndex);
78 template<
typename Tuple>
81 return unregisterQueries<0, Tuple>();
86 template<
typename QueryType>
89 return contains(QueryType::typeIndex());
94 bool contains(std::size_t typeIndex)
const;
98 template<
typename QueryType>
99 typename std::enable_if<!std::is_abstract<QueryType>::value, std::unique_ptr<QueryType>>::type
102 if (!contains<QueryType>())
104 registerQuery<QueryType>();
107 return std::unique_ptr<QueryType>{
static_cast<QueryType*
>(
108 create(QueryType::typeIndex()).release()) };
112 template<
typename QueryType>
113 typename std::enable_if<std::is_abstract<QueryType>::value, std::unique_ptr<QueryType>>::type
116 return std::unique_ptr<QueryType>{
static_cast<QueryType*
>(
117 create(QueryType::typeIndex()).release()) };
121 std::unique_ptr<Query> create(
const std::size_t& typeIndex)
const;
123 template<
typename QueryType>
124 std::size_t indexFor()
const
126 return indexFor(QueryType::typeIndex());
131 template<
typename QueryType>
132 typename std::enable_if<!std::is_abstract<QueryType>::value, std::size_t>::type
indexFor()
134 if (!contains<QueryType>())
136 registerQuery<QueryType>();
139 return indexFor(QueryType::typeIndex());
144 template<
typename QueryType>
145 typename std::enable_if<std::is_abstract<QueryType>::value, std::size_t>::type
indexFor()
147 return indexFor(QueryType::typeIndex());
152 std::size_t indexFor(
const std::size_t& typeIndex)
const;
155 template<std::
size_t I,
typename Tuple>
156 inline typename std::enable_if<I != std::tuple_size<Tuple>::value,
bool>::type registerQueries()
158 bool registered = this->registerQuery<typename std::tuple_element<I, Tuple>::type>();
159 return registered && registerQueries<I + 1, Tuple>();
162 template<std::
size_t I,
typename Tuple>
163 inline typename std::enable_if<I == std::tuple_size<Tuple>::value,
bool>::type registerQueries()
168 template<std::
size_t I,
typename Tuple>
169 inline typename std::enable_if<I != std::tuple_size<Tuple>::value,
bool>::type unregisterQueries()
171 bool unregistered = this->unregisterQuery<typename std::tuple_element<I, Tuple>::type>();
172 return unregistered && unregisterQueries<I + 1, Tuple>();
175 template<std::
size_t I,
typename Tuple>
176 inline typename std::enable_if<I == std::tuple_size<Tuple>::value,
bool>::type unregisterQueries()
181 struct HashByTypeIndex
183 std::size_t operator()(
const Metadata& metadata)
const {
return metadata.index(); }
185 struct EquateByTypeIndex
187 bool operator()(
const Metadata& lhs,
const Metadata& rhs)
const
189 return lhs.index() == rhs.index();
192 std::unordered_set<Metadata, HashByTypeIndex, EquateByTypeIndex> m_metadata;