File: VariantReader.hpp

package info (click to toggle)
reflect-cpp 0.18.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 12,524 kB
  • sloc: cpp: 44,484; python: 131; makefile: 30; sh: 3
file content (44 lines) | stat: -rw-r--r-- 1,428 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef RFL_PARSING_SCHEMAFUL_VARIANTREADER_HPP_
#define RFL_PARSING_SCHEMAFUL_VARIANTREADER_HPP_

#include <type_traits>
#include <utility>

#include "../../Result.hpp"
#include "../../internal/nth_element_t.hpp"

namespace rfl::parsing::schemaful {

template <class R, class W, class VariantType, class ProcessorsType,
          class... AlternativeTypes>
class VariantReader {
 public:
  static Result<VariantType> read(
      const R& _r, const size_t _index,
      const typename R::InputVarType& _var) noexcept {
    return [&]<size_t... _is>(std::integer_sequence<size_t, _is...>) {
      Result<VariantType> result =
          error("Could not parse union: Index out of bounds.");
      (try_one_type<_is>(_r, _index, _var, &result), ...);
      return result;
    }(std::make_integer_sequence<size_t, sizeof...(AlternativeTypes)>());
  }

 private:
  template <size_t _i>
  static void try_one_type(const R& _r, const size_t _index,
                           const typename R::InputVarType& _var,
                           Result<VariantType>* _result) noexcept {
    if (_index == _i) {
      using T = internal::nth_element_t<_i, AlternativeTypes...>;
      *_result =
          Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::read(_r, _var)
              .transform(
                  [](auto&& _val) -> VariantType { return std::move(_val); });
    }
  }
};

}  // namespace rfl::parsing::schemaful

#endif