-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allows specifying the specific information the Framework wants to know: relevant inheritance and container information.
- Loading branch information
Showing
9 changed files
with
484 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef FWCore_Reflection_DataProductReflectionInfo_h | ||
#define FWCore_Reflection_DataProductReflectionInfo_h | ||
// -*- C++ -*- | ||
// | ||
// Package: FWCore/Reflection | ||
// Class : DataProductReflectionInfo | ||
// | ||
/**\class DataProductReflectionInfo DataProductReflectionInfo.h "FWCore/Reflection/interface/DataProductReflectionInfo.h" | ||
Description: [one line class summary] | ||
Usage: | ||
<usage> | ||
*/ | ||
// | ||
// Original Author: Christopher Jones | ||
// Created: Wed, 27 Jul 2022 20:49:53 GMT | ||
// | ||
|
||
// system include files | ||
|
||
// user include files | ||
#include "FWCore/Reflection/interface/InheritanceReflection.h" | ||
#include "FWCore/Reflection/interface/StaticDataProductReflection.h" | ||
|
||
// forward declarations | ||
namespace edm { | ||
struct DataProductReflectionInfo { | ||
using BaseRange = InheritanceReflection::BaseRange; | ||
|
||
constexpr DataProductReflectionInfo(InheritanceReflection iType, std::type_info const* iElementType) | ||
: m_type(iType), m_elementType(iElementType) {} | ||
|
||
constexpr std::type_info const& typeInfo() const noexcept { return m_type.typeInfo(); } | ||
constexpr BaseRange inheritsFrom() const noexcept { return m_type.inheritsFrom(); } | ||
|
||
constexpr bool isContainer() const noexcept { return static_cast<bool>(m_elementType); } | ||
constexpr std::type_info const& elementType() const noexcept { | ||
if (m_elementType) { | ||
return *m_elementType; | ||
} | ||
return m_type.typeInfo(); | ||
} | ||
|
||
private: | ||
InheritanceReflection const m_type; | ||
std::type_info const* const m_elementType; | ||
}; | ||
|
||
template <typename T> | ||
//can't make this constexpr until C++23 | ||
const DataProductReflectionInfo makeDataProductReflectionInfo() { | ||
using Reflectn = StaticDataProductReflection<T>; | ||
static auto const s_bases = Reflectn::inherits_from(); | ||
InheritanceReflection reflection(&typeid(T), | ||
InheritanceReflection::BaseRange(s_bases.data(), s_bases.data() + s_bases.size())); | ||
if constexpr (Reflectn::is_container) { | ||
return DataProductReflectionInfo{reflection, &typeid(typename Reflectn::element_type)}; | ||
} | ||
return DataProductReflectionInfo{reflection, nullptr}; | ||
} | ||
|
||
} // namespace edm | ||
#endif |
77 changes: 77 additions & 0 deletions
77
FWCore/Reflection/interface/DataProductReflectionInfoRegistry.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#ifndef FWCore_Reflection_DataProductReflectionInfoRegistry_h | ||
#define FWCore_Reflection_DataProductReflectionInfoRegistry_h | ||
// -*- C++ -*- | ||
// | ||
// Package: FWCore/Reflection | ||
// Class : DataProductReflectionInfoRegistry | ||
// | ||
/**\class DataProductReflectionInfoRegistry DataProductReflectionInfoRegistry.h "FWCore/Reflection/interface/DataProductReflectionInfoRegistry.h" | ||
Description: [one line class summary] | ||
Usage: | ||
<usage> | ||
*/ | ||
// | ||
// Original Author: Christopher Jones | ||
// Created: Wed, 27 Jul 2022 21:00:33 GMT | ||
// | ||
|
||
// system include files | ||
#include <typeinfo> | ||
#include <typeindex> | ||
#include "oneapi/tbb/concurrent_unordered_map.h" | ||
|
||
// user include files | ||
#include "FWCore/Reflection/interface/DataProductReflectionInfo.h" | ||
|
||
// forward declarations | ||
namespace edm { | ||
class DataProductReflectionInfoRegistry { | ||
public: | ||
~DataProductReflectionInfoRegistry(); | ||
|
||
DataProductReflectionInfoRegistry(const DataProductReflectionInfoRegistry&) = delete; // stop default | ||
const DataProductReflectionInfoRegistry& operator=(const DataProductReflectionInfoRegistry&) = | ||
delete; // stop default | ||
|
||
// ---------- const member functions --------------------- | ||
DataProductReflectionInfo const* findType(std::type_index) const; | ||
|
||
// ---------- static member functions -------------------- | ||
static DataProductReflectionInfoRegistry& instance(); | ||
|
||
// ---------- member functions --------------------------- | ||
void registerDataProduct(std::type_index, DataProductReflectionInfo); | ||
|
||
private: | ||
// ---------- member data -------------------------------- | ||
DataProductReflectionInfoRegistry(); | ||
|
||
oneapi::tbb::concurrent_unordered_map<std::type_index, DataProductReflectionInfo const> m_registry; | ||
}; | ||
|
||
template <typename T> | ||
struct RegisterDataProductReflectionInfo { | ||
RegisterDataProductReflectionInfo() { | ||
DataProductReflectionInfoRegistry::instance().registerDataProduct(std::type_index(typeid(T)), | ||
makeDataProductReflectionInfo<T>()); | ||
} | ||
}; | ||
|
||
} // namespace edm | ||
|
||
#define EDM_DATAPRODUCTINFO_SYM(x, y) EDM_DATAPRODUCTINFO_SYM2(x, y) | ||
#define EDM_DATAPRODUCTINFO_SYM2(x, y) x##y | ||
|
||
#define DEFINE_DATA_PRODUCT_INFO(type, ...) \ | ||
namespace edm { \ | ||
template <> \ | ||
struct StaticDataProductReflection<type> \ | ||
: public StaticDataProductReflectionBase<type __VA_OPT__(, ) __VA_ARGS__> {}; \ | ||
static const RegisterDataProductReflectionInfo<type> EDM_DATAPRODUCTINFO_SYM(s_registry, __LINE__); \ | ||
} \ | ||
using require_semicolon = int | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#ifndef FWCore_Reflection_InheritanceReflection_h | ||
#define FWCore_Reflection_InheritanceReflection_h | ||
// -*- C++ -*- | ||
// | ||
// Package: FWCore/Reflection | ||
// Class : InheritanceReflection | ||
// | ||
/**\class InheritanceReflection InheritanceReflection.h "FWCore/Reflection/interface/InheritanceReflection.h" | ||
Description: A type-agnostic holder of inheritance information used for runtime reflection | ||
Usage: | ||
<usage> | ||
*/ | ||
// | ||
// Original Author: Christopher Jones | ||
// Created: Wed, 27 Jul 2022 20:47:16 GMT | ||
// | ||
|
||
// system include files | ||
#include <typeinfo> | ||
|
||
// user include files | ||
|
||
// forward declarations | ||
namespace edm { | ||
class InheritanceReflection { | ||
public: | ||
class BaseRange { | ||
public: | ||
using const_iterator_type = std::type_info const* const*; | ||
using element_type = std::type_info const* const; | ||
|
||
constexpr BaseRange(const_iterator_type iBegin, const_iterator_type iEnd) : m_begin(iBegin), m_end(iEnd) {} | ||
|
||
const_iterator_type begin() const { return m_begin; } | ||
const_iterator_type end() const { return m_end; } | ||
|
||
size_t size() const { return m_end - m_begin; } | ||
bool empty() const { return m_end == m_begin; } | ||
|
||
private: | ||
const_iterator_type m_begin; | ||
const_iterator_type m_end; | ||
}; | ||
|
||
constexpr InheritanceReflection(std::type_info const* iType, BaseRange iBases) : m_type(iType), m_bases(iBases) {} | ||
|
||
constexpr std::type_info const& typeInfo() const noexcept { return *m_type; } | ||
constexpr BaseRange inheritsFrom() const noexcept { return m_bases; } | ||
|
||
private: | ||
std::type_info const* m_type; | ||
BaseRange const m_bases; | ||
}; | ||
} // namespace edm | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#ifndef FWCore_Reflection_StaticDataProductReflection_h | ||
#define FWCore_Reflection_StaticDataProductReflection_h | ||
// -*- C++ -*- | ||
// | ||
// Package: FWCore/Reflection | ||
// Class : StaticDataProductReflection | ||
// | ||
/**\class StaticDataProductReflection StaticDataProductReflection.h "FWCore/Reflection/interface/StaticDataProductReflection.h" | ||
Description: template class describing compile time infor about a data product | ||
Usage: | ||
Developers must specialize a StaticDataProductReflection for each data product type. This is done by inheriting from | ||
StaticDataProductReflectionBase and declaring all inherited classes in the template arguments | ||
template<> class StaticDataProductReflection<Foo> : public StaticDataProductReflectionBase<Foo, Bar> {}; | ||
*/ | ||
// | ||
// Original Author: Christopher Jones | ||
// Created: Wed, 27 Jul 2022 20:39:27 GMT | ||
// | ||
|
||
// system include files | ||
#include <vector> | ||
#include <array> | ||
#include <typeinfo> | ||
|
||
// user include files | ||
#include "FWCore/Reflection/interface/TypeInfoList.h" | ||
|
||
// forward declarations | ||
|
||
namespace edm { | ||
template <typename T, typename... BASES> | ||
struct StaticDataProductReflectionBase { | ||
static constexpr bool is_container = false; | ||
using element_type = T; | ||
using Inheritance = TypeInfoList<BASES...>; | ||
|
||
static constexpr unsigned int nBases = Inheritance::nTypes; | ||
static constexpr std::array<std::type_info const*, nBases> inherits_from() noexcept { | ||
Inheritance::test_inheritance(static_cast<T const*>(nullptr)); | ||
return Inheritance::list(); | ||
}; | ||
}; | ||
|
||
template <typename T> | ||
struct StaticDataProductReflectionBase<T> { | ||
static constexpr bool is_container = false; | ||
using element_type = T; | ||
|
||
static constexpr unsigned int nBases = 0; | ||
static constexpr std::array<std::type_info const*, 0> inherits_from() noexcept { return {}; }; | ||
|
||
static constexpr std::array<std::type_info const*, 1> class_and_inherits_from() noexcept { return {{&typeid(T)}}; }; | ||
}; | ||
|
||
template <typename T, typename... U> | ||
struct StaticDataProductReflectionBase<std::vector<T, U...>> { | ||
static constexpr bool is_container = true; | ||
|
||
using element_type = typename std::vector<T, U...>::value_type; | ||
|
||
static constexpr unsigned int nBases = 0; | ||
static constexpr std::array<std::type_info const*, 0> inherits_from() noexcept { return {}; }; | ||
}; | ||
|
||
template <typename T> | ||
struct StaticDataProductReflection; | ||
|
||
} // namespace edm | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#ifndef FWCore_Reflection_TypeInfoList_h | ||
#define FWCore_Reflection_TypeInfoList_h | ||
// -*- C++ -*- | ||
// | ||
// Package: FWCore/Reflection | ||
// Class : TypeInfoList | ||
// | ||
/**\class TypeInfoList TypeInfoList.h "FWCore/Reflection/interface/TypeInfoList.h" | ||
Description: Converts types in template argument to a container of std::type_infos | ||
Usage: | ||
<usage> | ||
*/ | ||
// | ||
// Original Author: Christopher Jones | ||
// Created: Wed, 27 Jul 2022 20:36:03 GMT | ||
// | ||
|
||
// system include files | ||
#include <array> | ||
#include <algorithm> | ||
|
||
// user include files | ||
|
||
// forward declarations | ||
|
||
namespace edm { | ||
template <typename... T> | ||
struct TypeInfoList; | ||
|
||
template <typename T, typename... REMAINING> | ||
struct TypeInfoList<T, REMAINING...> { | ||
static constexpr unsigned int nTypes = TypeInfoList<REMAINING...>::nTypes + 1; | ||
static constexpr std::array<std::type_info const*, nTypes> list() noexcept { | ||
auto i = previous_list(); | ||
std::array<std::type_info const*, nTypes> v = {{&typeid(T)}}; | ||
std::copy(i.begin(), i.end(), v.begin() + 1); | ||
return v; | ||
}; | ||
template <typename D> | ||
static constexpr void test_inheritance(D const* iD) { | ||
test_inheritance_(iD); | ||
TypeInfoList<REMAINING...>::test_inheritance(iD); | ||
} | ||
|
||
private: | ||
static constexpr std::array<std::type_info const*, nTypes - 1> previous_list() noexcept { | ||
return TypeInfoList<REMAINING...>::list(); | ||
} | ||
static constexpr void test_inheritance_(T const*) {} | ||
}; | ||
|
||
template <> | ||
struct TypeInfoList<> { | ||
static constexpr unsigned int nTypes = 0; | ||
static constexpr std::array<std::type_info const*, 0> list() noexcept { return {}; }; | ||
template <typename D> | ||
static constexpr void test_inheritance(D const* iD) {} | ||
}; | ||
} // namespace edm | ||
#endif |
Oops, something went wrong.