AssnsNodeAsTuple.h
Go to the documentation of this file.
1 /**
2  * @file lardata/RecoBaseProxy/ProxyBase/AssnsNodeAsTuple.h
3  * @brief Specializations of STL tuple utilities for `art::AssnsNode`.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date July 27, 2017
6  * @see lardata/RecoBaseProxy/ProxyBase.h
7  *
8  * This library is header-only.
9  */
10 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_ASSNSNODEASTUPLE_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_ASSNSNODEASTUPLE_H
13 
14 // framework libraries
15 #include "canvas/Persistency/Common/Assns.h" // art::AssnsNode
17 
18 // C/C++ standard
19 #include <tuple> // std::tuple_element_t<>, std::get()
20 #include <cstdlib> // std::size_t
21 
22 
23 // FIXME simplify this code if issue #18769 is accepted
24 namespace std {
25 
26  //----------------------------------------------------------------------------
27  //--- specializations of std::tuple interface for art::AssnsNode
28  //----------------------------------------------------------------------------
29 
30  // specialize for indices 0, 1, and 2; for all others, it's an incomplete type
31  template <typename L, typename R, typename D>
32  class tuple_element<0U, art::AssnsNode<L, R, D>> {
33  public:
34  using type = art::Ptr<L>;
35  };
36 
37  template <typename L, typename R, typename D>
38  class tuple_element<1U, art::AssnsNode<L, R, D>> {
39  public:
40  using type = art::Ptr<R>;
41  };
42 
43  template <typename L, typename R, typename D>
44  class tuple_element<2U, art::AssnsNode<L, R, D>> {
45  public:
46  using type = D const*;
47  };
48 
49 
50  //----------------------------------------------------------------------------
51  template< std::size_t I, typename L, typename R, typename D>
52  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>>&
53  get( art::AssnsNode<L, R, D>& t ) noexcept;
54 
55  template< std::size_t I, typename L, typename R, typename D>
56  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>>&&
57  get( art::AssnsNode<L, R, D>&& t ) noexcept;
58 
59  template< std::size_t I, typename L, typename R, typename D>
60  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>> const&
61  get( const art::AssnsNode<L, R, D>& t ) noexcept;
62 
63  template< std::size_t I, typename L, typename R, typename D>
64  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>> const&&
65  get( const art::AssnsNode<L, R, D>&& t ) noexcept;
66 
67  template< class T, typename L, typename R, typename D>
68  constexpr T& get(art::AssnsNode<L, R, D>& t) noexcept;
69 
70  template< class T, typename L, typename R, typename D>
71  constexpr T&& get(art::AssnsNode<L, R, D>&& t) noexcept;
72 
73  template< class T, typename L, typename R, typename D>
74  constexpr const T& get(const art::AssnsNode<L, R, D>& t) noexcept;
75 
76  template< class T, typename L, typename R, typename D>
77  constexpr const T&& get(const art::AssnsNode<L, R, D>&& t) noexcept;
78 
79  //----------------------------------------------------------------------------
80 
81 
82 } // namespace std
83 
84 
85 //------------------------------------------------------------------------------
86 //--- implementation
87 //---
88 namespace util {
89  namespace details {
90 
91  //
92  // support utilities for implementation (they live outside std namespace)
93  //
94 
95  template <std::size_t I, typename L, typename R, typename D>
96  struct AssnsNodeGetter; // incomplete type, except for specializations...
97 
98 
99  template <typename L, typename R, typename D>
100  struct AssnsNodeGetter<0U, L, R, D> {
101 
103  using Element_t = std::tuple_element_t<0U, AssnsNode_t>;
104 
105  static constexpr Element_t& get(AssnsNode_t& node) noexcept
106  { return node.first; }
107 
108  static constexpr Element_t const& get(AssnsNode_t const& node) noexcept
109  { return node.first; }
110 
111  static constexpr Element_t&& get(AssnsNode_t&& node) noexcept
112  { return std::move(node.first); }
113 
114  static constexpr Element_t const&& get(AssnsNode_t const&& node) noexcept
115  { return std::move(node.first); }
116 
117  }; // struct AssnsNodeGetter<0U>
118 
119 
120  template <typename L, typename R, typename D>
121  struct AssnsNodeGetter<1U, L, R, D> {
122 
124  using Element_t = std::tuple_element_t<1U, AssnsNode_t>;
125 
126  static constexpr Element_t& get(AssnsNode_t& node) noexcept
127  { return node.second; }
128 
129  static constexpr Element_t const& get(AssnsNode_t const& node) noexcept
130  { return node.second; }
131 
132  static constexpr Element_t&& get(AssnsNode_t&& node) noexcept
133  { return std::move(node.second); }
134 
135  static constexpr Element_t const&& get(AssnsNode_t const&& node) noexcept
136  { return std::move(node.second); }
137 
138  }; // struct AssnsNodeGetter<1U>
139 
140 
141  template <typename L, typename R, typename D>
142  struct AssnsNodeGetter<2U, L, R, D> {
143 
145  using Element_t = std::tuple_element_t<2U, AssnsNode_t>;
146 
147  static constexpr Element_t& get(AssnsNode_t& node) noexcept
148  { return node.data; }
149 
150  static constexpr Element_t const& get(AssnsNode_t const& node) noexcept
151  { return node.data; }
152 
153  static constexpr Element_t&& get(AssnsNode_t&& node) noexcept
154  { return std::move(node.data); }
155 
156  static constexpr Element_t const&& get(AssnsNode_t const&& node) noexcept
157  { return std::move(node.data); }
158 
159  }; // struct AssnsNodeGetter<2U>
160 
161 
162  } // namespace details
163 } // namespace util
164 
165 
166 namespace std {
167 
168  //----------------------------------------------------------------------------
169  //--- implementation of specializations of std::get() for art::AssnsNode
170  //----------------------------------------------------------------------------
171 
172  template< std::size_t I, typename L, typename R, typename D>
173  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>>&
174  get(art::AssnsNode<L, R, D>& node) noexcept
176 
177  template< std::size_t I, typename L, typename R, typename D>
178  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>>&&
179  get(art::AssnsNode<L, R, D>&& node) noexcept
180  {
182  }
183 
184  template< std::size_t I, typename L, typename R, typename D>
185  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>> const&
186  get(art::AssnsNode<L, R, D> const& node) noexcept
188 
189  template< std::size_t I, typename L, typename R, typename D>
190  constexpr std::tuple_element_t<I, art::AssnsNode<L, R, D>> const&&
191  get(art::AssnsNode<L, R, D> const&& node) noexcept
192  {
194  }
195 
196  // not implemented yet:
197  template< class T, typename L, typename R, typename D>
198  constexpr T& get(art::AssnsNode<L, R, D>& t) noexcept;
199 
200  template< class T, typename L, typename R, typename D>
201  constexpr T&& get(art::AssnsNode<L, R, D>&& t) noexcept;
202 
203  template< class T, typename L, typename R, typename D>
204  constexpr const T& get(const art::AssnsNode<L, R, D>& t) noexcept;
205 
206  template< class T, typename L, typename R, typename D>
207  constexpr const T&& get(const art::AssnsNode<L, R, D>&& t) noexcept;
208 
209  //----------------------------------------------------------------------------
210 
211 
212 } // namespace std
213 
214 // -----------------------------------------------------------------------------
215 
216 
217 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_ASSNSNODEASTUPLE_H
D const * data
Definition: AssnsNode.h:18
Namespace for general, non-LArSoft-specific utilities.
STL namespace.
std::tuple_element_t< 1U, AssnsNode_t > Element_t
def move(depos, offset)
Definition: depos.py:107
std::tuple_element_t< 0U, AssnsNode_t > Element_t
first_type first
Definition: AssnsNode.h:16
second_type second
Definition: AssnsNode.h:17
std::tuple_element_t< 2U, AssnsNode_t > Element_t