typeidx: add type tagged namespacing to queries
This commit is contained in:
parent
3866249607
commit
077ecf5682
@ -13,5 +13,38 @@ main (int, char**)
|
||||
tap.expect_eq (cruft::typeidx<float> (), cruft::typeidx<float> (), "equality for float");
|
||||
tap.expect_neq (cruft::typeidx<int> (), cruft::typeidx<float> (), "inequality for int/float");
|
||||
|
||||
struct tag_a {};
|
||||
struct tag_b {};
|
||||
|
||||
// Register an unequal number of types (that don't include f32) to each
|
||||
// tag before we get to testing in the expectation that will force f32 to
|
||||
// be different in the following tests.
|
||||
cruft::typeidx<i16, tag_a> ();
|
||||
cruft::typeidx<i32, tag_a> ();
|
||||
cruft::typeidx<i08, tag_b> ();
|
||||
cruft::typeidx<i16, tag_b> ();
|
||||
cruft::typeidx<i32, tag_b> ();
|
||||
|
||||
// We test using f32 rather than int because we're pretty sure it's not
|
||||
// going to have the first index (and hence give us false results) given
|
||||
// int was registered first just above here.
|
||||
tap.expect_neq (
|
||||
cruft::typeidx<f32,tag_a> (),
|
||||
cruft::typeidx<f32> (),
|
||||
"inequality for f32/f32, tag_a"
|
||||
);
|
||||
|
||||
tap.expect_neq (
|
||||
cruft::typeidx<f32,tag_a> (),
|
||||
cruft::typeidx<f32,tag_b> (),
|
||||
"inequality for f32/f32, tag_a/tag_b"
|
||||
);
|
||||
|
||||
tap.expect_neq (
|
||||
cruft::typeidx<f32,tag_a> (),
|
||||
cruft::typeidx<f32, tag_b> (),
|
||||
"equality for f32/f32, tag_a/tag_a"
|
||||
);
|
||||
|
||||
return tap.status ();
|
||||
}
|
18
typeidx.cpp
18
typeidx.cpp
@ -7,21 +7,3 @@
|
||||
*/
|
||||
|
||||
#include "typeidx.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static std::atomic<int> counter;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int
|
||||
cruft::detail::typeidx_next ()
|
||||
{
|
||||
// We can't return zero, but we want to optimise access to the static
|
||||
// (which means we can't have it locally due to initialisation locking).
|
||||
//
|
||||
// Ensure we use pre-increment so that we can utilise zero static
|
||||
// initialisation instead.
|
||||
return ++counter;
|
||||
}
|
||||
|
23
typeidx.hpp
23
typeidx.hpp
@ -8,12 +8,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace cruft {
|
||||
namespace detail { int typeidx_next (void); }
|
||||
namespace detail {
|
||||
template <typename TagT>
|
||||
int typeidx_next (void)
|
||||
{
|
||||
static std::atomic<int> counter;
|
||||
return ++counter;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a globally unique runtime ID for a given type.
|
||||
/// Return a globally unique runtime ID for a given type (namespaced by a
|
||||
/// tag type).
|
||||
///
|
||||
/// This is intended to be used as a lightweight type check for variants
|
||||
/// and such without requiring RTTI.
|
||||
@ -28,11 +38,16 @@ namespace cruft {
|
||||
/// The range of identifiers is _probably_ contiguous. This should not
|
||||
/// be relied upon for correctness, but may be used for performance
|
||||
/// concerns.
|
||||
template <typename T>
|
||||
///
|
||||
/// \tparam T The type to register-and-retrieve the ID for
|
||||
/// \tparam TagT A namespacing type; different tags will have different
|
||||
/// sets of IDs. The default Tag is void.
|
||||
/// \return The unique ID of the type
|
||||
template <typename T, typename TagT = void>
|
||||
int
|
||||
typeidx (void)
|
||||
{
|
||||
static auto id = detail::typeidx_next ();
|
||||
static auto id = detail::typeidx_next<TagT> ();
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user