-
Notifications
You must be signed in to change notification settings - Fork 118
Expand file tree
/
Copy pathfield_mref.h
More file actions
146 lines (127 loc) · 4.86 KB
/
field_mref.h
File metadata and controls
146 lines (127 loc) · 4.86 KB
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (c) 2016, Huang-Ming Huang, Object Computing, Inc.
// All rights reserved.
//
// This file is part of mFAST.
// See the file license.txt for licensing information.
#pragma once
#include "int_ref.h"
#include "decimal_ref.h"
#include "string_ref.h"
#include <boost/exception/all.hpp>
namespace mfast {
struct tag_input_type;
struct tag_output_type;
typedef boost::error_info<tag_input_type, std::string> input_type_info;
typedef boost::error_info<tag_output_type, std::string> output_type_info;
class incompatible_type_conversion_error : public virtual boost::exception,
public virtual std::exception {
public:
incompatible_type_conversion_error(const char *input_type_name,
const char *output_type_name) {
*this << input_type_info(input_type_name)
<< output_type_info(output_type_name);
}
};
class field_mref : public field_mref_base {
public:
field_mref() {}
field_mref(allocator_type *alloc, value_storage *storage,
instruction_cptr instruction)
: field_mref_base(alloc, storage, instruction) {}
template <typename T>
field_mref(const make_field_mref<T> &other)
: field_mref_base(other.allocator(),
field_mref_core_access::storage_of(other),
other.instruction()) {}
field_mref(const exponent_mref &other)
: field_mref_base(static_cast<allocator_type *>(nullptr), other.storage(),
other.instruction()) {}
template <typename T> void as(T t);
void as(const char *);
void as(const decimal &);
template <int SIZE> void as(unsigned char(&value)[SIZE]);
void as(const std::vector<unsigned char> &value);
template <typename FieldMutator> void accept_mutator(FieldMutator &) const;
};
template <> struct mref_of<field_cref> { typedef field_mref type; };
template <typename T> void field_mref::as(T value) {
switch (this->instruction()->field_type()) {
case field_type_int32:
static_cast<int32_mref>(*this).as(static_cast<int32_t>(value));
break;
case field_type_uint32:
static_cast<uint32_mref>(*this).as(static_cast<uint32_t>(value));
break;
case field_type_int64:
static_cast<int64_mref>(*this).as(static_cast<int64_t>(value));
break;
case field_type_uint64:
case field_type_enum:
static_cast<uint64_mref>(*this).as(static_cast<uint64_t>(value));
break;
case field_type_decimal:
case field_type_exponent:
static_cast<decimal_mref>(*this).as(value);
break;
default:
BOOST_THROW_EXCEPTION(incompatible_type_conversion_error(
typeid(value).name(), this->instruction()->field_type_name()));
}
}
inline void field_mref::as(const char *value) {
switch (this->instruction()->field_type()) {
case field_type_ascii_string:
static_cast<ascii_string_mref>(*this).as(value);
break;
case field_type_unicode_string:
static_cast<unicode_string_mref>(*this).as(value);
break;
default:
BOOST_THROW_EXCEPTION(incompatible_type_conversion_error(
"const char*", this->instruction()->field_type_name()));
}
}
inline void field_mref::as(const decimal &value) {
if (this->instruction()->field_type() == field_type_decimal)
static_cast<decimal_mref>(*this).as(value);
else
BOOST_THROW_EXCEPTION(incompatible_type_conversion_error(
"decimal", this->instruction()->field_type_name()));
}
template <int SIZE> void field_mref::as(unsigned char(&value)[SIZE]) {
if (this->instruction()->field_type() == field_type_byte_vector)
static_cast<byte_vector_mref>(*this).as(value);
else
BOOST_THROW_EXCEPTION(incompatible_type_conversion_error(
"unsigned char array", this->instruction()->field_type_name()));
}
inline void field_mref::as(const std::vector<unsigned char> &value) {
if (this->instruction()->field_type() == field_type_byte_vector)
static_cast<byte_vector_mref>(*this).as(value);
else
BOOST_THROW_EXCEPTION(incompatible_type_conversion_error(
"std::vector<unsigned char>", this->instruction()->field_type_name()));
}
namespace detail {
inline field_mref field_ref_with_id(value_storage *storage,
const group_field_instruction *helper,
allocator *alloc, uint32_t id) {
if (helper) {
int index = helper->find_subinstruction_index_by_id(id);
if (index >= 0)
return field_mref(alloc, &storage[index], helper->subinstruction(index));
}
return field_mref();
}
inline field_mref field_ref_with_name(value_storage *storage,
const group_field_instruction *helper,
allocator *alloc, const char *name) {
if (helper) {
int index = helper->find_subinstruction_index_by_name(name);
if (index >= 0)
return field_mref(alloc, &storage[index], helper->subinstruction(index));
}
return field_mref();
}
}
}