lsst.afw  22.0.1-24-g2e899d296+b05a4897c9
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 std::size_t indexCovariance(std::size_t i, std::size_t j) { return (i < j) ? (i + j * (j + 1) / 2) : (j + i * (i + 1) / 2); }
33 
35 inline std::size_t computeCovariancePackedSize(std::size_t 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  std::size_t 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;
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(size_t size = 0) : _size(size) {
123  }
124 
125  FieldBase(FieldBase const &) noexcept = default;
126  FieldBase(FieldBase &&) noexcept = default;
127  FieldBase &operator=(FieldBase const &) noexcept = default;
128  FieldBase &operator=(FieldBase &&) noexcept = default;
129  ~FieldBase() noexcept = default;
130 
132  static std::string getTypeString();
133 
136  std::size_t getElementCount() const noexcept { return _size; }
137 
140  std::size_t getSize() const noexcept { return _size; }
141 
143  bool isVariableLength() const noexcept { return _size == 0; }
144 
145 protected:
147  static FieldBase makeDefault() noexcept { return FieldBase(0); }
148 
150  void stream(std::ostream &os) const { os << ", size=" << _size; }
151 
153  Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const {
154  if (isVariableLength()) {
155  return reinterpret_cast<ndarray::Array<Element, 1, 1> *>(p)->deep();
156  }
157  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
158  }
159 
161  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const {
162  if (isVariableLength()) {
163  return reinterpret_cast<ndarray::Array<Element, 1, 1> const *>(p)->deep();
164  }
165  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
166  }
167 
169  Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const {
170  if (isVariableLength()) {
171  return *reinterpret_cast<ndarray::Array<Element, 1, 1> const *>(p);
172  }
173  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
174  }
175 
182  void setValue(Element *p, ndarray::Manager::Ptr const &,
183  ndarray::Array<Element, 1, 1> const &value) const {
184  if (isVariableLength()) {
185  *reinterpret_cast<ndarray::Array<Element, 1, 1> *>(p) = value;
186  } else {
187  setValueDeep(p, value);
188  }
189  }
190 
192  template <typename Derived>
193  void setValue(Element *p, ndarray::Manager::Ptr const &,
194  ndarray::ExpressionBase<Derived> const &value) const {
195  if (isVariableLength()) {
196  throw LSST_EXCEPT(
198  "Assignment to a variable-length array must use a non-const array of the correct type.");
199  }
200  setValueDeep(p, value);
201  }
202 
203 private:
204  template <typename Derived>
205  void setValueDeep(Element *p, ndarray::ExpressionBase<Derived> const &value) const {
206  if (value.template getSize<0>() != static_cast<std::size_t>(_size)) {
208  "Incorrect size in array field assignment.");
209  }
210  for (std::size_t i = 0; i < _size; ++i) p[i] = value[i];
211  }
212 
213  std::size_t _size;
214 };
215 
219 template <>
220 struct FieldBase<std::string> {
221  typedef std::string Value;
222 
224  typedef char *Reference;
225 
227  typedef char const *ConstReference;
228 
229  typedef char Element;
230 
245 
246  FieldBase(FieldBase const &) noexcept = default;
247  FieldBase(FieldBase &&) noexcept = default;
248  FieldBase &operator=(FieldBase const &) noexcept = default;
249  FieldBase &operator=(FieldBase &&) noexcept = default;
250  ~FieldBase() noexcept = default;
251 
253  static std::string getTypeString();
254 
257  std::size_t getElementCount() const noexcept { return _size; }
258 
261  std::size_t getSize() const noexcept { return _size; }
262 
264  bool isVariableLength() const noexcept { return _size == 0; }
265 
266 protected:
268  static FieldBase makeDefault() noexcept { return FieldBase(0); }
269 
271  void stream(std::ostream &os) const { os << ", size=" << _size; }
272 
274  Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const {
275  if (isVariableLength()) {
276  // Can't be done until C++17, which allows read/write access to std::string's internal buffer
278  "non-const operator[] not supported for variable-length strings");
279  } else {
280  return p;
281  }
282  }
283 
285  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const {
286  if (isVariableLength()) {
287  return reinterpret_cast<std::string const *>(p)->data();
288  } else {
289  return p;
290  }
291  }
292 
294  Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const;
295 
301  void setValue(Element *p, ndarray::Manager::Ptr const &, std::string const &value) const;
302 
303 private:
304  std::size_t _size;
305 };
306 } // namespace table
307 } // namespace afw
308 } // namespace lsst
309 
310 #endif // !AFW_TABLE_FieldBase_h_INCLUDED
char * data
Definition: BaseRecord.cc:62
#define LSST_EXCEPT(type,...)
std::ostream * os
Definition: Schema.cc:558
int m
Definition: SpanSet.cc:49
Tag types used to declare specialized field types.
Definition: misc.h:32
std::size_t computeCovariancePackedSize(std::size_t size)
Defines the packed size of a covariance matrices.
Definition: FieldBase.h:35
std::size_t indexCovariance(std::size_t i, std::size_t 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:182
std::size_t 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:140
Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::get.
Definition: FieldBase.h:169
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:150
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:193
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:143
FieldBase(FieldBase &&) noexcept=default
Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:153
ndarray::ArrayRef< U const, 1, 1 > ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:105
FieldBase(size_t size=0)
Construct a FieldBase with the given size.
Definition: FieldBase.h:122
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:147
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:161
std::string Value
the type returned by BaseRecord::get
Definition: FieldBase.h:221
char const * ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:227
char Element
the type of subfields and array elements
Definition: FieldBase.h:229
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:268
bool isVariableLength() const noexcept
Return true if the field is variable-length (each record can have a different size array).
Definition: FieldBase.h:264
FieldBase(FieldBase &&) noexcept=default
std::size_t getSize() const noexcept
Return the maximum length of the string, including a null terminator (equal to the number of subfield...
Definition: FieldBase.h:261
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:285
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:271
char * Reference
the type returned by BaseRecord::operator[]
Definition: FieldBase.h:224
Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:274
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
std::size_t getElementCount() const noexcept
Return the number of subfield elements (always one for scalars).
Definition: FieldBase.h:50
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
FieldBase(FieldBase &&) noexcept=default