artdaq_core  v1_06_00
 All Classes Namespaces Functions
BuildInfo_module.hh
1 
2 #include "art/Framework/Core/EDProducer.h"
3 #include "art/Framework/Core/ModuleMacros.h"
4 #include "art/Framework/Principal/Event.h"
5 #include "art/Framework/Principal/Run.h"
6 #include "fhiclcpp/ParameterSet.h"
7 #include "messagefacility/MessageLogger/MessageLogger.h"
8 #include "artdaq-core/Data/PackageBuildInfo.hh"
9 
10 #include <iostream>
11 
12 
13 namespace artdaq {
14 
15  template <std::string* instanceName, typename... Pkgs>
16  class BuildInfo : public art::EDProducer {
17  public:
18  explicit BuildInfo(fhicl::ParameterSet const & p);
19  virtual ~BuildInfo() {}
20 
21  void beginRun(art::Run & r) override;
22  void produce(art::Event & e) override;
23 
24  private:
25 
26  std::unique_ptr< std::vector<PackageBuildInfo> > packages_;
27  std::string instanceName_;
28 
29  template <typename... Args>
30  struct fill_packages;
31 
32  template <typename Arg>
33  struct fill_packages<Arg> {
34  static void doit(std::vector<PackageBuildInfo>& packages) {
35  packages.emplace_back( Arg::getPackageBuildInfo() );
36  }
37  };
38 
39  template <typename Arg, typename... Args>
40  struct fill_packages<Arg, Args...> {
41  static void doit(std::vector<PackageBuildInfo>& packages) {
42  packages.emplace_back( Arg::getPackageBuildInfo() );
43  fill_packages<Args...>::doit(packages);
44  }
45  };
46 
47  };
48 
49  template <std::string* instanceName, typename... Pkgs>
50  BuildInfo<instanceName, Pkgs...>::BuildInfo(fhicl::ParameterSet const & ps):
51  packages_( new std::vector<PackageBuildInfo>() ),
52  instanceName_(ps.get<std::string>( "instance_name", *instanceName ))
53  {
54 
55  fill_packages<Pkgs...>::doit(*packages_);
56 
57  produces<std::vector<PackageBuildInfo>, art::InRun>(instanceName_);
58 
59  }
60 
61  template <std::string* instanceName, typename... Pkgs>
62  void BuildInfo<instanceName, Pkgs...>::beginRun(art::Run &e) {
63 
64  // JCF, 9/22/14
65 
66  // Previously, the vector pointed to by the member variable
67  // packages_ itself got stored in output on the call to "e.put()"
68  // below; what would then happen is that at the start of a new run
69  // or subrun, when e.put() got called again an exception would be
70  // thrown because packages_ would now be null thanks to the
71  // previous call to std::move. To make sure this doesn't happen, I
72  // now stash a copy of the vector pointed to by packages_, not the
73  // original member vector
74 
75  auto packages_deep_copy_ptr = std::unique_ptr<std::vector<PackageBuildInfo>>(
76  new std::vector<PackageBuildInfo>(*packages_ ) );
77 
78  e.put( std::move(packages_deep_copy_ptr), instanceName_ );
79 
80  }
81 
82  template <std::string* instanceName, typename... Pkgs>
83  void BuildInfo<instanceName, Pkgs...>::produce(art::Event &)
84  {
85  // nothing to be done for individual events
86  }
87 
88 
89 }