@@ -99,6 +99,23 @@ struct AxisSpec {
9999 // first entry is assumed to be the number of bins; in case of variable size binning it must be set to zero
100100 AxisSpec (ConfigurableAxis binEdges_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt );
101101
102+ // Out of line too, and for the same reason: every registry.add() call site
103+ // materialises AxisSpec temporaries, so the *destructor* is expanded there as
104+ // well -- on both the normal and the exception-unwind path. Measured with
105+ // -Rpass=inline on a 276-histogram init(): ~optional<string> inlined 2164
106+ // times, ~vector<AxisSpec> 552, ~vector<double> 367, ~AxisSpec 279.
107+ //
108+ // Declaring a destructor suppresses the implicit move operations, so all five
109+ // are declared here to keep AxisSpec movable. The moves are explicitly
110+ // noexcept: an out-of-line defaulted function does NOT inherit the implicit
111+ // exception specification, and without it vector<AxisSpec> reallocation would
112+ // silently fall back to copying.
113+ ~AxisSpec ();
114+ AxisSpec (AxisSpec const &);
115+ AxisSpec (AxisSpec&&) noexcept ;
116+ AxisSpec& operator =(AxisSpec const &);
117+ AxisSpec& operator =(AxisSpec&&) noexcept ;
118+
102119 [[nodiscard]] long getNbins () const ;
103120
104121 // / Function to make the axis logarithmic
@@ -122,6 +139,10 @@ struct HistogramConfigSpec {
122139 HistogramConfigSpec () = default ;
123140 HistogramConfigSpec (HistogramConfigSpec const & other) = default ;
124141 HistogramConfigSpec (HistogramConfigSpec&& other) = default ;
142+ // Out of line: inlined 552 times into a single 276-histogram init().
143+ // The copy/move constructors above stay declared, so this does not suppress
144+ // them.
145+ ~HistogramConfigSpec ();
125146
126147 void addAxis (const AxisSpec& axis)
127148 {
0 commit comments