Skip to content

Commit d1658b3

Browse files
committed
Merge branch 'master' into openvdb_cmd
2 parents 96f70bc + 7a1c176 commit d1658b3

File tree

8 files changed

+498
-118
lines changed

8 files changed

+498
-118
lines changed

openvdb/openvdb/TypeList.h

Lines changed: 100 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -112,36 +112,85 @@ struct TSHasTypeImpl<TypeList<T, Ts...>, T, Idx>
112112
};
113113

114114

115-
/// @brief Remove any duplicate types from a @c TypeList.
116-
/// @details This implementation effectively rebuilds a @c TypeList by starting
117-
/// with an empty @c TypeList and recursively defining an expanded
118-
/// @c TypeList for every type (first to last), only if the type does
119-
/// not already exist in the new @c TypeList. This has the effect of
120-
/// dropping all but the first of duplicate types.
121-
/// @note Each type must define a new instantiation of this object.
122-
/// @tparam ListT The starting @c TypeList, usually (but not limited to) an
123-
/// empty @c TypeList
124-
/// @tparam Ts The list of types to make unique
125-
template <typename ListT, typename... Ts>
126-
struct TSMakeUniqueImpl {
127-
using type = ListT;
115+
/// @brief Similar to TsAppendImpl but only appends types to a list if the
116+
/// type does not alreay exist in the list.
117+
/// @details Defines a new @c TypeList with non-unique types appended
118+
/// @tparam U Type to append
119+
/// @tparam ListT The @c TypeList to append to
120+
template <typename U, typename ListT,
121+
bool ListContainsType = TSHasTypeImpl<ListT, U>::Value>
122+
struct TSAppendUniqueImpl;
123+
124+
/// @brief Partial specialization where the currently evaluating type @c U in
125+
/// a @c TypeList already exists in the list. Returns the unmodified list.
126+
/// @tparam U Type to append
127+
/// @tparam Ts Other types within the @c TypeList
128+
template <typename U, typename... Ts>
129+
struct TSAppendUniqueImpl<U, TypeList<Ts...>, true> {
130+
private:
131+
using RemovedU = typename TypeList<Ts...>::template Remove<U>;
132+
public:
133+
/// @note It's simpler to remove the current type U and append the rest by
134+
/// just having "using type = TypeList<Ts...>". However this ends up with
135+
/// with keeping the last seen type rather than the first which this
136+
/// method historically did. e.g:
137+
/// TypeList<float, int, float>::Unique<> can become:
138+
/// a) TypeList<float, int> currently
139+
/// b) TypeList<int, float> if we used the afformentioned technique
140+
/// Might be useful to have both? Complexity in (a) is currently linear so
141+
/// this shouldn't be a problem, but be careful this doesn't change.
142+
//using type = TypeList<Ts...>;
143+
using type = typename TypeList<U>::template Append<RemovedU>;
144+
};
145+
146+
/// @brief Partial specialization where the currently evaluating type @c U in
147+
/// a @c TypeList does not exists in the list. Returns the appended list.
148+
/// @tparam U Type to append
149+
/// @tparam Ts Other types within the @c TypeList
150+
template <typename U, typename... Ts>
151+
struct TSAppendUniqueImpl<U, TypeList<Ts...>, false> {
152+
using type = TypeList<U, Ts...>;
153+
};
154+
155+
/// @brief Reconstruct a @c TypeList containing only unique types.
156+
/// @details This implementation effectively rebuilds a @c TypeList by
157+
/// starting with an empty @c TypeList and recursively defining an expanded
158+
/// @c TypeList for every type (first to last), only if the type does not
159+
/// already exist in the new @c TypeList. This has the effect of dropping all
160+
/// but the first of duplicate types.
161+
/// @warning This implementation previously used an embdedded std::conditional
162+
/// which resulted in drastically slow compilation times. If you're changing
163+
/// this implementation make sure to profile compile times with larger lists.
164+
/// @tparam Ts Types within the @c TypeList
165+
template <typename... Ts>
166+
struct TSRecurseAppendUniqueImpl;
167+
168+
/// @brief Terminate type recursion when the end of a @c TypeList is reached.
169+
template <>
170+
struct TSRecurseAppendUniqueImpl<> {
171+
using type = TypeList<>;
172+
};
173+
174+
/// @brief Merge and unpack an initial @c TypeList from the first argument if
175+
/// such a @c TypeList has been provided.
176+
/// @tparam Ts Types within the first @c TypeList
177+
/// @tparam OtherTs Other types
178+
template <typename... Ts, typename... OtherTs>
179+
struct TSRecurseAppendUniqueImpl<TypeList<Ts...>, OtherTs...> {
180+
using type = typename TSRecurseAppendUniqueImpl<OtherTs..., Ts...>::type;
128181
};
129182

130-
/// @brief Partial specialization for type packs, where by the next type @c U
131-
/// is checked in the existing type set @c Ts for duplication. If the
132-
/// type does not exist, it is added to the new @c TypeList definition,
133-
/// otherwise it is dropped. In either case, this class is recursively
134-
/// defined with the remaining types @c Us.
135-
/// @tparam Ts Current types in the @c TypeList
136-
/// @tparam U Type to check for duplication in @c Ts
137-
/// @tparam Us Remaining types
138-
template <typename... Ts, typename U, typename... Us>
139-
struct TSMakeUniqueImpl<TypeList<Ts...>, U, Us...>
183+
/// @brief Recursively call TSRecurseAppendUniqueImpl with each type in the
184+
/// provided @c TypeLists, rebuilding a new list with only the unique set
185+
/// of types.
186+
/// @tparam U Next type to check for uniqueness and append
187+
/// @tparam Ts Remaining types within the @c TypeList
188+
template <typename U, typename... Ts>
189+
struct TSRecurseAppendUniqueImpl<U, Ts...>
140190
{
141-
using type = typename std::conditional<
142-
TSHasTypeImpl<TypeList<Ts...>, U>::Value,
143-
typename TSMakeUniqueImpl<TypeList<Ts...>, Us...>::type,
144-
typename TSMakeUniqueImpl<TypeList<Ts..., U>, Us...>::type >::type;
191+
using type = typename TSAppendUniqueImpl<U,
192+
typename TSRecurseAppendUniqueImpl<Ts...>::type
193+
>::type;
145194
};
146195

147196

@@ -351,6 +400,10 @@ template<typename OpT> inline void TSForEachImpl(OpT) {}
351400
template<typename OpT, typename T, typename... Ts>
352401
inline void TSForEachImpl(OpT op) { op(T()); TSForEachImpl<OpT, Ts...>(op); }
353402

403+
template<template <typename> class OpT> inline void TSForEachImpl() {}
404+
template<template <typename> class OpT, typename T, typename... Ts>
405+
inline void TSForEachImpl() { OpT<T>()(); TSForEachImpl<OpT, Ts...>(); }
406+
354407
} // namespace internal
355408

356409
/// @endcond
@@ -421,7 +474,7 @@ struct TypeList
421474
/// }
422475
/// @endcode
423476
template<typename ListT = TypeList<>>
424-
using Unique = typename typelist_internal::TSMakeUniqueImpl<ListT, Ts...>::type;
477+
using Unique = typename typelist_internal::TSRecurseAppendUniqueImpl<ListT, Ts...>::type;
425478

426479
/// @brief Append types, or the members of another TypeList, to this list.
427480
/// @details Example:
@@ -499,6 +552,25 @@ struct TypeList
499552
template <size_t First, size_t Last>
500553
using RemoveByIndex = typename typelist_internal::TSRemoveIndicesImpl<Self, First, Last>::type;
501554

555+
/// @brief Invoke a templated class operator on each type in this list. Use
556+
/// this method if you only need access to the type for static methods.
557+
/// @code
558+
/// #include <typeinfo>
559+
///
560+
/// template <typename T>
561+
/// struct PintTypes() {
562+
/// inline void operator()() { std::cout << typeid(T).name() << std::endl; }
563+
/// };
564+
///
565+
/// using MyTypes = openvdb::TypeList<int, float, double>;
566+
/// MyTypes::foreach<PintTypes>(); // "i, f, d" (exact output is compiler-dependent)
567+
/// @endcode
568+
///
569+
/// @note OpT must be a templated class. It is created and invoked for each
570+
/// type in this list.
571+
template<template <typename> class OpT>
572+
static void foreach() { typelist_internal::TSForEachImpl<OpT, Ts...>(); }
573+
502574
/// @brief Invoke a templated, unary functor on a value of each type in this list.
503575
/// @details Example:
504576
/// @code

openvdb/openvdb/openvdb.cc

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
#include "openvdb.h"
55
#include "io/DelayedLoadMetadata.h"
6-
//#ifdef OPENVDB_ENABLE_POINTS
76
#include "points/PointDataGrid.h"
8-
//#endif
97
#include "tools/PointIndexGrid.h"
108
#include "util/logging.h"
119

@@ -54,6 +52,11 @@ std::mutex sInitMutex;
5452
std::atomic<bool> sIsInitialized{false};
5553
}
5654

55+
/// @todo Change registerX() methods to simply be register()...
56+
template <typename GridT> struct RegisterGrid { inline void operator()() { GridT::registerGrid(); } };
57+
template <typename MetaT> struct RegisterMeta { inline void operator()() { MetaT::registerType(); } };
58+
template <typename MapT> struct RegisterMap { inline void operator()() { MapT::registerMap(); } };
59+
5760
void
5861
initialize()
5962
{
@@ -65,65 +68,29 @@ initialize()
6568

6669
// Register metadata.
6770
Metadata::clearRegistry();
68-
BoolMetadata::registerType();
69-
DoubleMetadata::registerType();
70-
FloatMetadata::registerType();
71-
Int32Metadata::registerType();
72-
Int64Metadata::registerType();
73-
StringMetadata::registerType();
74-
Vec2IMetadata::registerType();
75-
Vec2SMetadata::registerType();
76-
Vec2DMetadata::registerType();
77-
Vec3IMetadata::registerType();
78-
Vec3SMetadata::registerType();
79-
Vec3DMetadata::registerType();
80-
Vec4IMetadata::registerType();
81-
Vec4SMetadata::registerType();
82-
Vec4DMetadata::registerType();
83-
Mat4SMetadata::registerType();
84-
Mat4DMetadata::registerType();
71+
MetaTypes::foreach<RegisterMeta>();
8572

8673
// Register maps
8774
math::MapRegistry::clear();
88-
math::AffineMap::registerMap();
89-
math::UnitaryMap::registerMap();
90-
math::ScaleMap::registerMap();
91-
math::UniformScaleMap::registerMap();
92-
math::TranslationMap::registerMap();
93-
math::ScaleTranslateMap::registerMap();
94-
math::UniformScaleTranslateMap::registerMap();
95-
math::NonlinearFrustumMap::registerMap();
75+
MapTypes::foreach<RegisterMap>();
9676

9777
// Register common grid types.
9878
GridBase::clearRegistry();
99-
BoolGrid::registerGrid();
100-
MaskGrid::registerGrid();
101-
FloatGrid::registerGrid();
102-
DoubleGrid::registerGrid();
103-
Int32Grid::registerGrid();
104-
Int64Grid::registerGrid();
79+
GridTypes::foreach<RegisterGrid>();
80+
10581
// @note String grids types are deprecated but we still register them
10682
// as supported serializable types for backward compatibility. This
10783
// will likely be removed in a future major version
10884
OPENVDB_NO_DEPRECATION_WARNING_BEGIN
10985
StringGrid::registerGrid();
11086
OPENVDB_NO_DEPRECATION_WARNING_END
111-
Vec3IGrid::registerGrid();
112-
Vec3SGrid::registerGrid();
113-
Vec3DGrid::registerGrid();
11487

11588
// Register types associated with point index grids.
11689
Metadata::registerType(typeNameAsString<PointIndex32>(), Int32Metadata::createMetadata);
11790
Metadata::registerType(typeNameAsString<PointIndex64>(), Int64Metadata::createMetadata);
118-
tools::PointIndexGrid::registerGrid();
11991

12092
// Register types associated with point data grids.
121-
//#ifdef OPENVDB_ENABLE_POINTS
12293
points::internal::initialize();
123-
//#endif
124-
125-
// Register delay load metadata
126-
io::DelayedLoadMetadata::registerType();
12794

12895
#ifdef OPENVDB_USE_BLOSC
12996
blosc_init();
@@ -166,10 +133,7 @@ __pragma(warning(default:1711))
166133
Metadata::clearRegistry();
167134
GridBase::clearRegistry();
168135
math::MapRegistry::clear();
169-
170-
//#ifdef OPENVDB_ENABLE_POINTS
171136
points::internal::uninitialize();
172-
//#endif
173137

174138
#ifdef OPENVDB_USE_BLOSC
175139
// We don't want to destroy Blosc, because it might have been

0 commit comments

Comments
 (0)