Skip to content

Commit

Permalink
New limited Reflection system
Browse files Browse the repository at this point in the history
Allows specifying the specific information the Framework wants to
know: relevant inheritance and container information.
  • Loading branch information
Dr15Jones committed Aug 1, 2022
1 parent db4ff9a commit 9fe8552
Show file tree
Hide file tree
Showing 9 changed files with 484 additions and 0 deletions.
65 changes: 65 additions & 0 deletions FWCore/Reflection/interface/DataProductReflectionInfo.h
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 FWCore/Reflection/interface/DataProductReflectionInfoRegistry.h
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
59 changes: 59 additions & 0 deletions FWCore/Reflection/interface/InheritanceReflection.h
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
73 changes: 73 additions & 0 deletions FWCore/Reflection/interface/StaticDataProductReflection.h
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
63 changes: 63 additions & 0 deletions FWCore/Reflection/interface/TypeInfoList.h
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
Loading

0 comments on commit 9fe8552

Please sign in to comment.