lsst.afw  22.0.0-22-gf1d71818e+0d6c1a9e28
FieldBase.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 #ifndef AFW_TABLE_FieldBase_h_INCLUDED
3 #define AFW_TABLE_FieldBase_h_INCLUDED
4 
5 #include <cstring>
6 #include <iostream>
7 
8 #include "boost/mpl/vector.hpp"
9 #include "boost/preprocessor/punctuation/paren.hpp"
10 #include "Eigen/Core"
11 
12 #include "lsst/base.h"
13 #include "lsst/pex/exceptions.h"
14 #include "ndarray.h"
15 #include "lsst/afw/table/misc.h"
16 #include "lsst/afw/table/KeyBase.h"
17 #include "lsst/afw/table/types.h"
18 
19 namespace lsst {
20 namespace afw {
21 namespace table {
22 
23 namespace detail {
24 
25 class TableImpl;
26 
32 inline int indexCovariance(int i, int j) { return (i < j) ? (i + j * (j + 1) / 2) : (j + i * (i + 1) / 2); }
33 
35 inline int computeCovariancePackedSize(int size) { return size * (size + 1) / 2; }
36 
37 } // namespace detail
38 
42 template <typename T>
43 struct FieldBase {
44  typedef T Value;
45  typedef T &Reference;
46  typedef T const &ConstReference;
47  typedef T Element;
48 
50  int getElementCount() const noexcept { return 1; }
51 
53  static std::string getTypeString();
54 
55  // Only the first of these constructors is valid for this specializations, but
56  // it's convenient to be able to instantiate both, since the other is used
57  // by other specializations.
58  FieldBase() = default;
59  FieldBase(int) {
61  "Constructor disabled (this Field type is not sized).");
62  }
63  FieldBase(FieldBase const &) noexcept = default;
64  FieldBase(FieldBase &&) noexcept = default;
65  FieldBase &operator=(FieldBase const &) noexcept = default;
66  FieldBase &operator=(FieldBase &&) noexcept = default;
67  ~FieldBase() noexcept = default;
68 
69 protected:
71  static FieldBase makeDefault() noexcept { return FieldBase(); }
72 
74  void stream(std::ostream &os) const {}
75 
77  Reference getReference(Element *p, ndarray::Manager::Ptr const &) const { return *p; }
78 
80  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &) const { return *p; }
81 
83  Value getValue(Element const *p, ndarray::Manager::Ptr const &) const { return *p; }
84 
86  void setValue(Element *p, ndarray::Manager::Ptr const &, Value v) const { *p = v; }
87 };
88 
97 template <typename U>
98 struct FieldBase<Array<U> > {
99  typedef ndarray::Array<U const, 1, 1> Value;
100 
102  typedef ndarray::ArrayRef<U, 1, 1> Reference;
103 
105  typedef ndarray::ArrayRef<U const, 1, 1> ConstReference;
106 
107  typedef U Element;
108 
122  FieldBase(int size = 0) : _size(size) {
123  if (size < 0)
125  "A non-negative size must be provided when constructing an array field.");
126  }
127 
128  FieldBase(FieldBase const &) noexcept = default;
129  FieldBase(FieldBase &&) noexcept = default;
130  FieldBase &operator=(FieldBase const &) noexcept = default;
131  FieldBase &operator=(FieldBase &&) noexcept = default;
132  ~FieldBase() noexcept = default;
133 
135  static std::string getTypeString();
136 
139  int getElementCount() const noexcept { return _size; }
140 
143  int getSize() const noexcept { return _size; }
144 
146  bool isVariableLength() const noexcept { return _size == 0; }
147 
148 protected:
150  static FieldBase makeDefault() noexcept { return FieldBase(0); }
151 
153  void stream(std::ostream &os) const { os << ", size=" << _size; }
154 
156  Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const {
157  if (isVariableLength()) {
158  return reinterpret_cast<ndarray::Array<Element, 1, 1> *>(p)->deep();
159  }
160  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
161  }
162 
164  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const {
165  if (isVariableLength()) {
166  return reinterpret_cast<ndarray::Array<Element, 1, 1> const *>(p)->deep();
167  }
168  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
169  }
170 
172  Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const {
173  if (isVariableLength()) {
174  return *reinterpret_cast<ndarray::Array<Element, 1, 1> const *>(p);
175  }
176  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
177  }
178 
185  void setValue(Element *p, ndarray::Manager::Ptr const &,
186  ndarray::Array<Element, 1, 1> const &value) const {
187  if (isVariableLength()) {
188  *reinterpret_cast<ndarray::Array<Element, 1, 1> *>(p) = value;
189  } else {
190  setValueDeep(p, value);
191  }
192  }
193 
195  template <typename Derived>
196  void setValue(Element *p, ndarray::Manager::Ptr const &,
197  ndarray::ExpressionBase<Derived> const &value) const {
198  if (isVariableLength()) {
199  throw LSST_EXCEPT(
201  "Assignment to a variable-length array must use a non-const array of the correct type.");
202  }
203  setValueDeep(p, value);
204  }
205 
206 private:
207  template <typename Derived>
208  void setValueDeep(Element *p, ndarray::ExpressionBase<Derived> const &value) const {
209  if (value.template getSize<0>() != static_cast<std::size_t>(_size)) {
211  "Incorrect size in array field assignment.");
212  }
213  for (int i = 0; i < _size; ++i) p[i] = value[i];
214  }
215 
216  int _size;
217 };
218 
222 template <>
223 struct FieldBase<std::string> {
224  typedef std::string Value;
225 
227  typedef char *Reference;
228 
230  typedef char const *ConstReference;
231 
232  typedef char Element;
233 
247  FieldBase(int size = -1);
248 
249  FieldBase(FieldBase const &) noexcept = default;
250  FieldBase(FieldBase &&) noexcept = default;
251  FieldBase &operator=(FieldBase const &) noexcept = default;
252  FieldBase &operator=(FieldBase &&) noexcept = default;
253  ~FieldBase() noexcept = default;
254 
256  static std::string getTypeString();
257 
260  int getElementCount() const noexcept { return _size; }
261 
264  int getSize() const noexcept { return _size; }
265 
267  bool isVariableLength() const noexcept { return _size == 0; }
268 
269 protected:
271  static FieldBase makeDefault() noexcept { return FieldBase(0); }
272 
274  void stream(std::ostream &os) const { os << ", size=" << _size; }
275 
277  Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const {
278  if (isVariableLength()) {
279  // Can't be done until C++17, which allows read/write access to std::string's internal buffer
281  "non-const operator[] not supported for variable-length strings");
282  } else {
283  return p;
284  }
285  }
286 
288  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const {
289  if (isVariableLength()) {
290  return reinterpret_cast<std::string const *>(p)->data();
291  } else {
292  return p;
293  }
294  }
295 
297  Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const;
298 
304  void setValue(Element *p, ndarray::Manager::Ptr const &, std::string const &value) const;
305 
306 private:
307  int _size;
308 };
309 } // namespace table
310 } // namespace afw
311 } // namespace lsst
312 
313 #endif // !AFW_TABLE_FieldBase_h_INCLUDED
char * data
Definition: BaseRecord.cc:62
#define LSST_EXCEPT(type,...)
std::ostream * os
Definition: Schema.cc:557
int m
Definition: SpanSet.cc:49
Tag types used to declare specialized field types.
Definition: misc.h:32
int computeCovariancePackedSize(int size)
Defines the packed size of a covariance matrices.
Definition: FieldBase.h:35
int indexCovariance(int i, int j)
Defines the ordering of packed covariance matrices.
Definition: FieldBase.h:32
A base class for image defects.
STL namespace.
void setValue(Element *p, ndarray::Manager::Ptr const &, ndarray::Array< Element, 1, 1 > const &value) const
Used to implement BaseRecord::set; accepts only non-const arrays of the right type.
Definition: FieldBase.h:185
Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::get.
Definition: FieldBase.h:172
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:153
FieldBase(FieldBase const &) noexcept=default
ndarray::Array< U const, 1, 1 > Value
the type returned by BaseRecord::get
Definition: FieldBase.h:99
U Element
the type of subfields and array elements
Definition: FieldBase.h:107
void setValue(Element *p, ndarray::Manager::Ptr const &, ndarray::ExpressionBase< Derived > const &value) const
Used to implement BaseRecord::set; accepts any ndarray expression.
Definition: FieldBase.h:196
int getSize() const noexcept
Return the size of the array (equal to the number of subfield elements), or 0 for a variable-length a...
Definition: FieldBase.h:143
FieldBase(int size=0)
Construct a FieldBase with the given size.
Definition: FieldBase.h:122
ndarray::ArrayRef< U, 1, 1 > Reference
the type returned by BaseRecord::operator[]
Definition: FieldBase.h:102
bool isVariableLength() const noexcept
Return true if the field is variable-length (each record can have a different size array).
Definition: FieldBase.h:146
FieldBase(FieldBase &&) noexcept=default
Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:156
ndarray::ArrayRef< U const, 1, 1 > ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:105
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:150
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:164
std::string Value
the type returned by BaseRecord::get
Definition: FieldBase.h:224
char const * ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:230
char Element
the type of subfields and array elements
Definition: FieldBase.h:232
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:271
bool isVariableLength() const noexcept
Return true if the field is variable-length (each record can have a different size array).
Definition: FieldBase.h:267
FieldBase(FieldBase &&) noexcept=default
FieldBase(FieldBase const &) noexcept=default
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:288
int getSize() const noexcept
Return the maximum length of the string, including a null terminator (equal to the number of subfield...
Definition: FieldBase.h:264
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:274
char * Reference
the type returned by BaseRecord::operator[]
Definition: FieldBase.h:227
Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:277
Field base class default implementation (used for numeric scalars and lsst::geom::Angle).
Definition: FieldBase.h:43
T & Reference
the type returned by BaseRecord::operator[] (non-const)
Definition: FieldBase.h:45
T const & ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:46
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:80
FieldBase(FieldBase const &) noexcept=default
static std::string getTypeString()
Return a string description of the field type.
Definition: FieldBase.cc:56
Value getValue(Element const *p, ndarray::Manager::Ptr const &) const
Used to implement BaseRecord::get.
Definition: FieldBase.h:83
T Element
the type of subfields (the same as the type itself for scalars)
Definition: FieldBase.h:47
T Value
the type returned by BaseRecord::get
Definition: FieldBase.h:44
void setValue(Element *p, ndarray::Manager::Ptr const &, Value v) const
Used to implement BaseRecord::set.
Definition: FieldBase.h:86
Reference getReference(Element *p, ndarray::Manager::Ptr const &) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:77
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:71
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:74
int getElementCount() const noexcept
Return the number of subfield elements (always one for scalars).
Definition: FieldBase.h:50
FieldBase(FieldBase &&) noexcept=default