Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use modern C++ constructs in EventSetup #24270

Merged
merged 9 commits into from
Aug 13, 2018
28 changes: 12 additions & 16 deletions FWCore/Framework/interface/Callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

// system include files
#include <vector>
#include <type_traits>
// user include files
#include "FWCore/Framework/interface/produce_helpers.h"
#include "FWCore/Utilities/interface/propagate_const.h"
Expand Down Expand Up @@ -47,12 +48,12 @@ namespace edm {
=CallbackSimpleDecorator<TRecord> >
class Callback : public CallbackBase {
public:
typedef TReturn (T ::* method_type)(const TRecord&);
using method_type = TReturn (T ::*)(const TRecord&);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Dr15Jones for my own education, is there a functional difference between these two syntaxes, or is it just aesthetics? Browsing around https://en.cppreference.com/w/cpp/language/type_alias I would say the latter, but I would like to know your motivation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The using directive can do everything the typedef can do and then even more. The modern C++ community seems to favor deprecating the use of typedef in favor of the more flexible using. That is why I've been converting code from using one to the other.


Callback(T* iProd,
method_type iMethod,
const TDecorator& iDec = TDecorator()) :
proxyData_(produce::size< TReturn >::value, static_cast<void*>(nullptr)),
proxyData_{},
producer_(iProd),
method_(iMethod),
wasCalledForThisRecord_(false),
Expand Down Expand Up @@ -82,23 +83,18 @@ namespace edm {

void storeReturnedValues(TReturn iReturn) {
//std::cout <<" storeReturnedValues "<< iReturn <<" " <<iReturn->value_ <<std::endl;
typedef typename produce::product_traits<TReturn>::type type;
setData(iReturn, static_cast<typename type::head_type*>(nullptr), static_cast<const typename type::tail_type *>(nullptr));
using type = typename produce::product_traits<TReturn>::type;
setData<typename type::head_type, typename type::tail_type>(iReturn);
}

template<class RemainingContainerT, class DataT, class ProductsT>
void setData(ProductsT& iProducts, const RemainingContainerT*, const DataT*) {
void setData(ProductsT& iProducts) {
DataT* temp = reinterpret_cast< DataT*>(proxyData_[produce::find_index<TReturn,DataT>::value]) ;
if(nullptr != temp) { copyFromTo(iProducts, *temp); }
setData(iProducts, static_cast< const typename RemainingContainerT::head_type *>(nullptr),
static_cast< const typename RemainingContainerT::tail_type *>(nullptr));
}
template<class DataT, class ProductsT>
void setData(ProductsT& iProducts, const produce::Null*, const DataT*) {

DataT* temp = reinterpret_cast< DataT*>(proxyData_[produce::find_index<TReturn,DataT>::value]) ;
//std::cout <<" setData["<< produce::find_index<TReturn,DataT>::value<<"] "<< temp <<std::endl;
if(nullptr != temp) { copyFromTo(iProducts, *temp); }
if(nullptr != temp) { moveFromTo(iProducts, *temp); }
if constexpr( not std::is_same_v<produce::Null,RemainingContainerT> ) {
setData<typename RemainingContainerT::head_type,
typename RemainingContainerT::tail_type>(iProducts);
}
}
void newRecordComing() {
wasCalledForThisRecord_ = false;
Expand All @@ -109,7 +105,7 @@ namespace edm {

const Callback& operator=(const Callback&) = delete; // stop default

std::vector<void*> proxyData_;
std::array<void*, produce::size< TReturn >::value> proxyData_;
edm::propagate_const<T*> producer_;
method_type method_;
bool wasCalledForThisRecord_;
Expand Down
7 changes: 4 additions & 3 deletions FWCore/Framework/interface/CallbackProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ namespace edm {
class CallbackProxy : public DataProxy {

public:
typedef typename produce::smart_pointer_traits<DataT>::type value_type;
typedef RecordT record_type;
using smart_pointer_traits = produce::smart_pointer_traits<DataT>;
using value_type = typename smart_pointer_traits::type;
using record_type = RecordT;

CallbackProxy(std::shared_ptr<CallbackT>& iCallback) :
data_(),
Expand All @@ -62,7 +63,7 @@ namespace edm {
record_type rec;
rec.setImpl(&iRecord);
(*callback_)(rec);
return &(*data_);
return smart_pointer_traits::getPointer(data_);
}

void invalidateCache() override {
Expand Down
175 changes: 54 additions & 121 deletions FWCore/Framework/interface/ESProducts.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Usage:
This is used as a return type from the produce method of an ESProducer. Users are not anticipated to ever need
to directly use this class. Instead, to create an instance of the class at method return time, they should call
the helper function es::products or 'output' the values to es::produced via the '<<' operator.
the helper function es::products.

*/
//
Expand All @@ -30,93 +30,26 @@
namespace edm {
namespace eventsetup {
namespace produce {
struct Produce {
Produce() {}
};

template< typename T> struct OneHolder {
OneHolder() {}
OneHolder(const T& iValue) : value_(iValue) {}

template<typename S>
void setFromRecursive(S& iGiveValues) {
iGiveValues.setFrom(value_);
}

void assignTo(T& oValue) { oValue = value_;}
T value_;
typedef T tail_type;
typedef Null head_type;
};

template<typename T> struct OneHolder<std::unique_ptr<T>> {
typedef std::unique_ptr<T> Type;
OneHolder() {}
OneHolder(OneHolder<Type> const& iOther): value_(const_cast<OneHolder<Type>&>(iOther).value_) {}
OneHolder(Type iPtr): value_(iPtr) {}


OneHolder<Type> const& operator=(OneHolder<Type> iRHS) { value_ = iRHS.value_; return *this; }
template<typename S>
void setFromRecursive(S& iGiveValues) {
iGiveValues.setFrom(value_);
}

void assignTo(Type& oValue) { oValue = value_;}
mutable Type value_; //mutable needed for std::unique_ptr
typedef Type tail_type;
typedef Null head_type;
};

template<typename T> OneHolder<T> operator<<(const Produce&, T iValue) {
return OneHolder<T>(iValue);
}

template<typename T, typename U> struct MultiHolder {
MultiHolder(const T& iT, U iValue): value_(iValue), head_(iT) {
}

template<typename TTaker>
void setFromRecursive(TTaker& iGiveValues) {
iGiveValues.setFrom(value_);
head_.setFromRecursive(iGiveValues);
}


void assignTo(U& oValue) { oValue = value_;}
U value_;
T head_;

typedef U tail_type;
typedef T head_type;
};

template<typename T, typename S>
MultiHolder<OneHolder<T>, S> operator<<(const OneHolder<T>& iHolder,
const S& iValue) {
return MultiHolder<OneHolder<T>, S>(iHolder, iValue);
}
template< typename T, typename U, typename V>
MultiHolder< MultiHolder<T, U>, V >
operator<<(const MultiHolder<T,U>& iHolder, const V& iValue) {
return MultiHolder< MultiHolder<T, U>, V> (iHolder, iValue);
}

template<typename T1, typename T2, typename T3>
struct ProductHolder : public ProductHolder<T2, T3, Null> {
typedef ProductHolder<T2, T3, Null> parent_type;
template<typename T1, typename... TArgs>
struct ProductHolder : public ProductHolder<TArgs...> {
using parent_type = ProductHolder<TArgs...>;

ProductHolder() : value() {}

ProductHolder(ProductHolder<T1,TArgs...>&&) = default;
ProductHolder(ProductHolder<T1,TArgs...> const&) = default;
ProductHolder<T1, TArgs...>& operator=(ProductHolder<T1,TArgs...>&&) = default;
ProductHolder<T1, TArgs...>& operator=(ProductHolder<T1,TArgs...> const&) = default;

template<typename T>
void setAllValues(T& iValuesFrom) {
iValuesFrom.setFromRecursive(*this);
}
using parent_type::assignTo;
void assignTo(T1& oValue) { oValue = value; }
using parent_type::moveTo;
void moveTo(T1& oValue) { oValue = std::move(value); }

using parent_type::setFrom;
void setFrom(T1& iValue) { value = iValue ; }
void setFrom(T1&& iValue) { value = std::move(iValue) ; }

template<typename T>
void setFromRecursive(T& iValuesTo) {
Expand All @@ -125,83 +58,83 @@ namespace edm {
}

template<typename T>
void assignToRecursive(T& iValuesTo) {
iValuesTo.assignTo(value);
parent_type::assignToRecursive(iValuesTo);
void moveToRecursive(T& iValuesTo) {
iValuesTo.moveTo(value);
parent_type::moveToRecursive(iValuesTo);
}
T1 value;

typedef T1 tail_type;
typedef parent_type head_type;
using tail_type = T1;
using head_type = parent_type;
};

template<typename T1>
struct ProductHolder<T1, Null, Null> {
struct ProductHolder<T1> {

ProductHolder() : value() {}
ProductHolder(ProductHolder<T1>&&) = default;
ProductHolder(ProductHolder<T1> const&) = default;
ProductHolder<T1>& operator=(ProductHolder<T1>&&) = default;
ProductHolder<T1>& operator=(ProductHolder<T1> const&) = default;

template<typename T>
void setAllValues(T& iValuesFrom) {
iValuesFrom.assignToRecursive(*this);
iValuesFrom.moveToRecursive(*this);
}
void assignTo(T1& oValue) { oValue = value; }
void moveTo(T1& oValue) { oValue = std::move(value); }
void setFrom(T1& iValue) { value = iValue ; }
void setFrom(T1&& iValue) { value = std::move(iValue) ; }
template<typename T>
void assignToRecursive(T& iValuesTo) {
iValuesTo.assignTo(value);
void moveToRecursive(T& iValuesTo) {
iValuesTo.moveTo(value);
}
template<typename T>
void setFromRecursive(T& iValuesTo) {
iValuesTo.setFrom(value);
}
T1 value;

typedef T1 tail_type;
typedef Null head_type;
using tail_type = T1;
using head_type = Null;
};

template<>
struct ProductHolder<Null, Null, Null > {
void setAllValues(Null&) {}
void assignTo(void*) {}
void setFrom(void*) {}

typedef Null tail_type;
typedef Null head_type;
};
}
}
template<typename T1, typename T2 = eventsetup::produce::Null, typename T3 = eventsetup::produce::Null >
struct ESProducts : public eventsetup::produce::ProductHolder<T1, T2, T3> {
typedef eventsetup::produce::ProductHolder<T1, T2, T3> parent_type;
template<typename S1, typename S2, typename S3>
ESProducts(const ESProducts<S1, S2, S3>& iProducts) {
parent_type::setAllValues(const_cast<ESProducts<S1, S2, S3>&>(iProducts));
struct ESFillDirectly {};

template<typename ...TArgs>
struct ESProducts : public eventsetup::produce::ProductHolder<TArgs...> {
typedef eventsetup::produce::ProductHolder<TArgs...> parent_type;
template<typename... S>
ESProducts(ESProducts<S...>&& iProducts) {
parent_type::setAllValues(iProducts);
}
template<typename T>
/*explicit*/ ESProducts(const T& iValues) {
parent_type::setAllValues(const_cast<T&>(iValues));
/*explicit*/ ESProducts(T&& iValues) {
parent_type::setAllValues(iValues);
}
template<typename ...Vars>
ESProducts(ESFillDirectly, Vars&&... vars) {
(this->setFrom(std::forward<Vars>(vars)), ...);
}

ESProducts(ESProducts<TArgs...> const&) = default;
ESProducts(ESProducts<TArgs...>&&) = default;
ESProducts<TArgs...>& operator=(ESProducts<TArgs...> const&) = default;
ESProducts<TArgs...>& operator=(ESProducts<TArgs...>&&) = default;
};

namespace es {
extern const eventsetup::produce::Produce produced;

template<typename T, typename S>
ESProducts<T,S> products(const T& i1, const S& i2) {
return ESProducts<T,S>(produced << i1 << i2);
template<typename ...TArgs>
ESProducts<std::remove_reference_t<TArgs>...> products(TArgs&&... args) {
return ESProducts<std::remove_reference_t<TArgs>...>(edm::ESFillDirectly{}, std::forward<TArgs>(args)...);
}

template<typename T, typename S, typename U>
ESProducts<T,S, U> products(const T& i1, const S& i2, const U& i3) {
return ESProducts<T,S,U>(produced << i1 << i2 << i3);
}
}

template<typename T1, typename T2, typename T3, typename ToT>
void copyFromTo(ESProducts<T1,T2,T3>& iFrom,
template<typename ...TArgs, typename ToT>
void moveFromTo(ESProducts<TArgs...>& iFrom,
ToT& iTo) {
iFrom.assignTo(iTo);
iFrom.moveTo(iTo);
}
}

Expand Down
Loading