LSSTApplications  20.0.0
LSSTDataManagementBasePackage
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 
98 template <typename U>
99 struct FieldBase<Array<U> > {
100  typedef ndarray::Array<U const, 1, 1> Value;
101 
103  typedef ndarray::ArrayRef<U, 1, 1> Reference;
104 
106  typedef ndarray::ArrayRef<U const, 1, 1> ConstReference;
107 
108  typedef U Element;
109 
123  FieldBase(int size = 0) : _size(size) {
124  if (size < 0)
126  "A non-negative size must be provided when constructing an array field.");
127  }
128 
129  FieldBase(FieldBase const &) noexcept = default;
130  FieldBase(FieldBase &&) noexcept = default;
131  FieldBase &operator=(FieldBase const &) noexcept = default;
132  FieldBase &operator=(FieldBase &&) noexcept = default;
133  ~FieldBase() noexcept = default;
134 
136  static std::string getTypeString();
137 
140  int getElementCount() const noexcept { return _size; }
141 
144  int getSize() const noexcept { return _size; }
145 
147  bool isVariableLength() const noexcept { return _size == 0; }
148 
149 protected:
151  static FieldBase makeDefault() noexcept { return FieldBase(0); }
152 
154  void stream(std::ostream &os) const { os << ", size=" << _size; }
155 
157  Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const {
158  if (isVariableLength()) {
159  return reinterpret_cast<ndarray::Array<Element, 1, 1> *>(p)->deep();
160  }
161  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
162  }
163 
165  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const {
166  if (isVariableLength()) {
167  return reinterpret_cast<ndarray::Array<Element, 1, 1> const *>(p)->deep();
168  }
169  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
170  }
171 
173  Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const {
174  if (isVariableLength()) {
175  return *reinterpret_cast<ndarray::Array<Element, 1, 1> const *>(p);
176  }
177  return ndarray::external(p, ndarray::makeVector(_size), ndarray::ROW_MAJOR, m);
178  }
179 
186  void setValue(Element *p, ndarray::Manager::Ptr const &,
187  ndarray::Array<Element, 1, 1> const &value) const {
188  if (isVariableLength()) {
189  *reinterpret_cast<ndarray::Array<Element, 1, 1> *>(p) = value;
190  } else {
191  setValueDeep(p, value);
192  }
193  }
194 
196  template <typename Derived>
197  void setValue(Element *p, ndarray::Manager::Ptr const &,
198  ndarray::ExpressionBase<Derived> const &value) const {
199  if (isVariableLength()) {
200  throw LSST_EXCEPT(
202  "Assignment to a variable-length array must use a non-const array of the correct type.");
203  }
204  setValueDeep(p, value);
205  }
206 
207 private:
208  template <typename Derived>
209  void setValueDeep(Element *p, ndarray::ExpressionBase<Derived> const &value) const {
210  if (value.template getSize<0>() != static_cast<std::size_t>(_size)) {
212  "Incorrect size in array field assignment.");
213  }
214  for (int i = 0; i < _size; ++i) p[i] = value[i];
215  }
216 
217  int _size;
218 };
219 
223 template <>
224 struct FieldBase<std::string> {
225  typedef std::string Value;
226 
228  typedef char *Reference;
229 
231  typedef char const *ConstReference;
232 
233  typedef char Element;
234 
248  FieldBase(int size = -1);
249 
250  FieldBase(FieldBase const &) noexcept = default;
251  FieldBase(FieldBase &&) noexcept = default;
252  FieldBase &operator=(FieldBase const &) noexcept = default;
253  FieldBase &operator=(FieldBase &&) noexcept = default;
254  ~FieldBase() noexcept = default;
255 
257  static std::string getTypeString();
258 
261  int getElementCount() const noexcept { return _size; }
262 
265  int getSize() const noexcept { return _size; }
266 
268  bool isVariableLength() const noexcept { return _size == 0; }
269 
270 protected:
272  static FieldBase makeDefault() noexcept { return FieldBase(0); }
273 
275  void stream(std::ostream &os) const { os << ", size=" << _size; }
276 
278  Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const {
279  if (isVariableLength()) {
280  // Can't be done until C++17, which allows read/write access to std::string's internal buffer
282  "non-const operator[] not supported for variable-length strings");
283  } else {
284  return p;
285  }
286  }
287 
289  ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const {
290  if (isVariableLength()) {
291  return reinterpret_cast<std::string const *>(p)->data();
292  } else {
293  return p;
294  }
295  }
296 
298  Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const;
299 
305  void setValue(Element *p, ndarray::Manager::Ptr const &, std::string const &value) const;
306 
307 private:
308  int _size;
309 };
310 } // namespace table
311 } // namespace afw
312 } // namespace lsst
313 
314 #endif // !AFW_TABLE_FieldBase_h_INCLUDED
lsst::afw::table::FieldBase< Array< U > >::makeDefault
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:151
lsst::afw::table::FieldBase::Reference
T & Reference
the type returned by BaseRecord::operator[] (non-const)
Definition: FieldBase.h:45
lsst::afw::table::detail::indexCovariance
int indexCovariance(int i, int j)
Defines the ordering of packed covariance matrices.
Definition: FieldBase.h:32
lsst::afw::table::FieldBase< std::string >::Reference
char * Reference
the type returned by BaseRecord::operator[]
Definition: FieldBase.h:228
lsst::afw::table::FieldBase::FieldBase
FieldBase()=default
std::string
STL class.
lsst::afw::table::FieldBase::setValue
void setValue(Element *p, ndarray::Manager::Ptr const &, Value v) const
Used to implement BaseRecord::set.
Definition: FieldBase.h:86
lsst::afw::table::FieldBase< std::string >::getConstReference
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:289
types.h
lsst::afw::table::FieldBase< Array< U > >::isVariableLength
bool isVariableLength() const noexcept
Return true if the field is variable-length (each record can have a different size array).
Definition: FieldBase.h:147
lsst::afw
Definition: imageAlgorithm.dox:1
lsst::afw::table::FieldBase< Array< U > >::setValue
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:197
lsst::afw::table::FieldBase< Array< U > >::Value
ndarray::Array< U const, 1, 1 > Value
the type returned by BaseRecord::get
Definition: FieldBase.h:100
lsst::afw::table::FieldBase::FieldBase
FieldBase(FieldBase &&) noexcept=default
lsst::afw::table::FieldBase< std::string >::isVariableLength
bool isVariableLength() const noexcept
Return true if the field is variable-length (each record can have a different size array).
Definition: FieldBase.h:268
lsst::afw::table::FieldBase< std::string >::stream
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:275
lsst::afw::table::FieldBase< Array< U > >::setValue
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:186
lsst::afw::table::FieldBase< Array< U > >::getReference
Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:157
lsst::afw::table::FieldBase::getElementCount
int getElementCount() const noexcept
Return the number of subfield elements (always one for scalars).
Definition: FieldBase.h:50
lsst::afw::table::FieldBase< Array< U > >::getSize
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:144
lsst::afw::table::FieldBase< Array< U > >::getValue
Value getValue(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::get.
Definition: FieldBase.h:173
_size
table::Key< table::Array< int > > _size
Definition: PsfexPsf.cc:364
lsst::afw::table::FieldBase< std::string >::FieldBase
FieldBase(FieldBase &&) noexcept=default
data
char * data
Definition: BaseRecord.cc:62
misc.h
std::ostream
STL class.
lsst::afw::table::FieldBase::FieldBase
FieldBase(int)
Definition: FieldBase.h:59
lsst::afw::table::FieldBase< std::string >::ConstReference
char const * ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:231
lsst::pex::exceptions::LengthError
Reports attempts to exceed implementation-defined length limits for some classes.
Definition: Runtime.h:76
lsst::pex::exceptions::LogicError
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
lsst::afw::table::FieldBase< Array< U > >::Element
U Element
the type of subfields and array elements
Definition: FieldBase.h:108
lsst::afw::table::FieldBase::getReference
Reference getReference(Element *p, ndarray::Manager::Ptr const &) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:77
lsst::afw::table::Array
Tag types used to declare specialized field types.
Definition: misc.h:32
lsst::afw::table::FieldBase< std::string >::getReference
Reference getReference(Element *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (non-const).
Definition: FieldBase.h:278
lsst::afw::table::FieldBase< Array< U > >::FieldBase
FieldBase(FieldBase const &) noexcept=default
lsst::afw::table::FieldBase::getConstReference
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:80
base.h
lsst::afw::table::FieldBase::ConstReference
T const & ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:46
lsst::afw::table::FieldBase::Element
T Element
the type of subfields (the same as the type itself for scalars)
Definition: FieldBase.h:47
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
lsst::afw::table::FieldBase< std::string >::getSize
int getSize() const noexcept
Return the maximum length of the string, including a null terminator (equal to the number of subfield...
Definition: FieldBase.h:265
os
std::ostream * os
Definition: Schema.cc:746
lsst::afw::table::FieldBase
Field base class default implementation (used for numeric scalars and lsst::geom::Angle).
Definition: FieldBase.h:43
lsst::afw::table::FieldBase< std::string >::makeDefault
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:272
lsst::afw::table::FieldBase< std::string >::Value
std::string Value
the type returned by BaseRecord::get
Definition: FieldBase.h:225
lsst::afw::table::FieldBase< Array< U > >::ConstReference
ndarray::ArrayRef< U const, 1, 1 > ConstReference
the type returned by BaseRecord::operator[] (const)
Definition: FieldBase.h:106
lsst::afw::table::FieldBase< Array< U > >::getConstReference
ConstReference getConstReference(Element const *p, ndarray::Manager::Ptr const &m) const
Used to implement BaseRecord::operator[] (const).
Definition: FieldBase.h:165
lsst::afw::table::FieldBase< std::string >::Element
char Element
the type of subfields and array elements
Definition: FieldBase.h:233
lsst::afw::table::FieldBase::getTypeString
static std::string getTypeString()
Return a string description of the field type.
Definition: FieldBase.cc:56
std
STL namespace.
lsst::afw::table::FieldBase::makeDefault
static FieldBase makeDefault() noexcept
Needed to allow Keys to be default-constructed.
Definition: FieldBase.h:71
KeyBase.h
lsst::afw::table::FieldBase::stream
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:74
lsst::afw::table::FieldBase< Array< U > >::FieldBase
FieldBase(int size=0)
Construct a FieldBase with the given size.
Definition: FieldBase.h:123
lsst::afw::table::detail::computeCovariancePackedSize
int computeCovariancePackedSize(int size)
Defines the packed size of a covariance matrices.
Definition: FieldBase.h:35
lsst::afw::table::FieldBase::getValue
Value getValue(Element const *p, ndarray::Manager::Ptr const &) const
Used to implement BaseRecord::get.
Definition: FieldBase.h:83
lsst::afw::table::FieldBase::Value
T Value
the type returned by BaseRecord::get
Definition: FieldBase.h:44
std::size_t
lsst::afw::table::FieldBase< Array< U > >::Reference
ndarray::ArrayRef< U, 1, 1 > Reference
the type returned by BaseRecord::operator[]
Definition: FieldBase.h:103
lsst::afw::table::FieldBase< Array< U > >::FieldBase
FieldBase(FieldBase &&) noexcept=default
lsst::afw::table::FieldBase< Array< U > >::stream
void stream(std::ostream &os) const
Defines how Fields are printed.
Definition: FieldBase.h:154
exceptions.h
lsst::afw::table::FieldBase< std::string >::FieldBase
FieldBase(FieldBase const &) noexcept=default
m
int m
Definition: SpanSet.cc:49
lsst::afw::table::FieldBase::FieldBase
FieldBase(FieldBase const &) noexcept=default