Gamgee
You miserable little maggot. I'll stove your head in!
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shared_field.h
Go to the documentation of this file.
1 #ifndef gamgee__shared_field__guard
2 #define gamgee__shared_field__guard
3 
5 
6 #include "../utils/utils.h"
7 
8 #include "htslib/vcf.h"
9 
10 #include <memory>
11 #include <sstream>
12 #include <stdexcept>
13 
14 namespace gamgee {
15 
56 template<class TYPE>
57 class SharedField {
58  public:
59 
65  SharedField() : m_body {nullptr}, m_info_ptr {nullptr}, m_bytes_per_value {0} {}
66 
72  explicit SharedField(const std::shared_ptr<bcf1_t>& body, const bcf_info_t* const info_ptr) :
73  m_body {body},
74  m_info_ptr {info_ptr},
75  m_bytes_per_value {utils::size_for_type(static_cast<utils::VariantFieldType>(info_ptr->type), info_ptr)}
76  {}
77 
78  SharedField(const SharedField& other) = delete;
79  SharedField& operator=(const SharedField& other) = delete;
80  SharedField(SharedField&& other) = default;
81  SharedField& operator=(SharedField&& other) = default;
82 
88  bool operator==(const SharedField& other) const {
89  if (this == &other)
90  return true;
91  //Use iterators where possible as they take care of field sizes, bcf_*_vector_end
92  auto other_iter = other.begin();
93  auto other_end = other.end();
94  for(const auto& curr_val : *this)
95  {
96  if(other_iter == other_end) //different length, this is longer (more valid values) than other
97  return false;
98  if(!utils::bcf_check_equal_element(curr_val, *other_iter))
99  return false;
100  ++other_iter;
101  }
102  //Check if other still has more valid values
103  if(other_iter != other_end)
104  return false;
105  return true;
106  }
107 
113  bool operator!=(const SharedField& other) const {
114  return !(*this == other);
115  }
116 
117 
125  TYPE operator[](const uint32_t index) const {
126  if (empty())
127  throw std::out_of_range("Tried to index a shared field that is missing with operator[]");
128  utils::check_max_boundary(index, m_info_ptr->len);
129  return convert_from_byte_array(index);
130  }
131 
134  if (empty()) return SharedFieldIterator<TYPE>();
135  return SharedFieldIterator<TYPE>{m_body, m_info_ptr->vptr, m_info_ptr->vptr + size() * m_bytes_per_value, m_bytes_per_value, static_cast<utils::VariantFieldType>(m_info_ptr->type)};
136  }
137 
140  if (empty()) return SharedFieldIterator<TYPE>();
141  return SharedFieldIterator<TYPE>{m_body, m_info_ptr->vptr + size() * m_bytes_per_value, m_bytes_per_value, static_cast<utils::VariantFieldType>(m_info_ptr->type)};
142  }
143 
144  uint32_t size() const { return m_info_ptr->len; }
145  bool empty() const { return m_body == nullptr; }
146  bool missing() const { return empty(); }
147  TYPE front() const { return operator[](0); }
148  TYPE back() const { return operator[](m_info_ptr->len - 1); }
149 
150  private:
151  std::shared_ptr<bcf1_t> m_body;
152  const bcf_info_t* m_info_ptr;
153  uint8_t m_bytes_per_value;
154 
155  TYPE convert_from_byte_array(int index) const;
156 };
157 
158 template<> inline
159 uint32_t SharedField<std::string>::size() const { return empty() ? 0 : 1; }
160 
164 template<> inline
165 int32_t SharedField<int32_t>::convert_from_byte_array(int index) const {
166  return utils::convert_data_to_integer(m_info_ptr->vptr, index, m_bytes_per_value, static_cast<utils::VariantFieldType>(m_info_ptr->type));
167 }
168 
172 template<> inline
173 float SharedField<float>::convert_from_byte_array(int index) const {
174  return utils::convert_data_to_float(m_info_ptr->vptr, index, m_bytes_per_value, static_cast<utils::VariantFieldType>(m_info_ptr->type));
175 }
176 
180 template<> inline
181 std::string SharedField<std::string>::convert_from_byte_array(int index) const {
182  return utils::convert_data_to_string(m_info_ptr->vptr, index, m_bytes_per_value, static_cast<utils::VariantFieldType>(m_info_ptr->type));
183 }
184 
189 template<> inline
190 std::string SharedField<std::string>::operator[](const uint32_t index) const {
191  if (empty())
192  throw std::out_of_range("Tried to index a shared field that is missing with operator[]");
193  auto is_string_type = utils::is_string_type(m_info_ptr->type);
194  auto limit = m_info_ptr->len; //cannot use size here as size<string> is specialized to return 1
195  auto prefix_msg = "";
196  if(is_string_type)
197  {
198  limit = 1u;
199  prefix_msg = "INFO fields of type string in VCFs have only 1 element per sample :: ";
200  }
201  utils::check_max_boundary(index, limit, prefix_msg);
202  return convert_from_byte_array(index);
203 }
204 
205 } // end of namespace gamgee
206 
207 #endif // gamgee__shared_field__guard
bool operator==(const SharedField &other) const
compares two SharedField objects in the following order: memory address, size and values...
Definition: shared_field.h:88
int len
Definition: vcf.h:146
SharedFieldIterator< TYPE > begin() const
create a new iterator pointing to the begining of the values of this field
Definition: shared_field.h:133
VariantFieldType
an enumeration of the types in htslib for the format field values
Definition: variant_field_type.h:16
SharedField & operator=(const SharedField &other)=delete
copying of the SharedField object is not allowed. Use move constructor instead.
void check_max_boundary(const uint32_t index, const uint32_t size, const std::string &prefix_msg)
checks that an index is greater than or equal to size
Definition: utils.h:63
bool empty() const
checks if the object is empty.
Definition: shared_field.h:145
std::string convert_data_to_string(const uint8_t *data_ptr, const int index, const uint8_t num_bytes_per_value, const VariantFieldType &type)
converts the value in an index from the byte array into string
Definition: variant_field_type.cpp:77
bool operator!=(const SharedField &other) const
compares two SharedField objects in the following order: memory address, size and values...
Definition: shared_field.h:113
bool is_string_type(const int32_t &type)
check if type is of type string
Definition: variant_field_type.h:59
bool missing() const
simple overload of empty to work with gamgee's missing API
Definition: shared_field.h:146
TYPE back() const
convenience function to access the last element
Definition: shared_field.h:148
A class template to hold the values of a specific Variant's shared field.
Definition: shared_field.h:57
Definition: vcf.h:144
TYPE front() const
convenience function to access the first element
Definition: shared_field.h:147
uint32_t size() const
the number of values in this SharedField (values per sample)
Definition: shared_field.h:144
uint8_t * vptr
Definition: vcf.h:151
bool bcf_check_equal_element(const TYPE &x, const TYPE &y)
Check whether two values from VCF fields of primitive types (for which the == operator is defined) * ...
Definition: utils.h:85
SharedFieldIterator< TYPE > end() const
create a new iterator pointing to the end of the values of this field
Definition: shared_field.h:139
Definition: exceptions.h:9
SharedField()
default constructor of an empty SharedField
Definition: shared_field.h:65
int type
Definition: vcf.h:146
uint8_t size_for_type(const VariantFieldType &type, const bcf_fmt_t *const format_ptr)
returns the number of bytes for a given VariantFieldType
Definition: variant_field_type.cpp:102
SharedField(const std::shared_ptr< bcf1_t > &body, const bcf_info_t *const info_ptr)
creates a new SharedField pointing to the shared byte array inside the variant object ...
Definition: shared_field.h:72
TYPE operator[](const uint32_t index) const
random access to a given value for reading or writing
Definition: shared_field.h:125
int32_t convert_data_to_integer(const uint8_t *data_ptr, const int index, const uint8_t num_bytes_per_value, const VariantFieldType &type)
converts the value in an index from the byte array into int32_t
Definition: variant_field_type.cpp:11
iterator for SharedField objects.
Definition: shared_field_iterator.h:28
float convert_data_to_float(const uint8_t *data_ptr, const int index, const uint8_t num_bytes_per_value, const VariantFieldType &type)
converts the value in an index from the byte array into float
Definition: variant_field_type.cpp:41