Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
89bf26d1
Commit
89bf26d1
authored
Feb 09, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove giant switch-case in serializer code
parent
e9946674
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
204 additions
and
169 deletions
+204
-169
libcaf_core/caf/data_processor.hpp
libcaf_core/caf/data_processor.hpp
+34
-31
libcaf_core/caf/detail/select_integer_type.hpp
libcaf_core/caf/detail/select_integer_type.hpp
+13
-10
libcaf_core/caf/stream_deserializer.hpp
libcaf_core/caf/stream_deserializer.hpp
+86
-73
libcaf_core/caf/stream_serializer.hpp
libcaf_core/caf/stream_serializer.hpp
+71
-55
No files found.
libcaf_core/caf/data_processor.hpp
View file @
89bf26d1
...
@@ -73,24 +73,6 @@ public:
...
@@ -73,24 +73,6 @@ public:
std
::
u32string
std
::
u32string
>
;
>
;
/// List of builtin types for data processors as enum.
enum
builtin
{
i8_v
,
u8_v
,
i16_v
,
u16_v
,
i32_v
,
u32_v
,
i64_v
,
u64_v
,
float_v
,
double_v
,
ldouble_v
,
string8_v
,
string16_v
,
string32_v
};
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
data_processor
(
const
data_processor
&
)
=
delete
;
data_processor
(
const
data_processor
&
)
=
delete
;
...
@@ -137,7 +119,7 @@ public:
...
@@ -137,7 +119,7 @@ public:
apply
(
T
&
x
)
{
apply
(
T
&
x
)
{
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
T
>::
value
;
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
T
>::
value
;
static_assert
(
tlindex
>=
0
,
"T not recognized as builtin type"
);
static_assert
(
tlindex
>=
0
,
"T not recognized as builtin type"
);
return
apply_
builtin
(
static_cast
<
builtin
>
(
tlindex
),
&
x
);
return
apply_
impl
(
x
);
}
}
template
<
class
T
>
template
<
class
T
>
...
@@ -147,25 +129,21 @@ public:
...
@@ -147,25 +129,21 @@ public:
error
error
>::
type
>::
type
apply
(
T
&
x
)
{
apply
(
T
&
x
)
{
using
type
=
using
type
=
detail
::
select_integer_type_t
<
sizeof
(
T
),
typename
detail
::
select_integer_type
<
std
::
is_signed
<
T
>::
value
>
;
static_cast
<
int
>
(
sizeof
(
T
))
*
(
std
::
is_signed
<
T
>::
value
?
-
1
:
1
)
return
apply_impl
(
reinterpret_cast
<
type
&>
(
x
));
>::
type
;
static
constexpr
auto
tlindex
=
detail
::
tl_index_of
<
builtin_t
,
type
>::
value
;
static_assert
(
tlindex
>=
0
,
"T not recognized as builtin type"
);
return
apply_builtin
(
static_cast
<
builtin
>
(
tlindex
),
&
x
);
}
}
error
apply
(
std
::
string
&
x
)
{
error
apply
(
std
::
string
&
x
)
{
return
apply_
builtin
(
string8_v
,
&
x
);
return
apply_
impl
(
x
);
}
}
error
apply
(
std
::
u16string
&
x
)
{
error
apply
(
std
::
u16string
&
x
)
{
return
apply_
builtin
(
string16_v
,
&
x
);
return
apply_
impl
(
x
);
}
}
error
apply
(
std
::
u32string
&
x
)
{
error
apply
(
std
::
u32string
&
x
)
{
return
apply_
builtin
(
string32_v
,
&
x
);
return
apply_
impl
(
x
);
}
}
template
<
class
D
,
atom_value
V
>
template
<
class
D
,
atom_value
V
>
...
@@ -549,8 +527,33 @@ public:
...
@@ -549,8 +527,33 @@ public:
}
}
protected
:
protected
:
/// Applies this processor to a single builtin value.
virtual
error
apply_impl
(
int8_t
&
)
=
0
;
virtual
error
apply_builtin
(
builtin
in_out_type
,
void
*
in_out
)
=
0
;
virtual
error
apply_impl
(
uint8_t
&
)
=
0
;
virtual
error
apply_impl
(
int16_t
&
)
=
0
;
virtual
error
apply_impl
(
uint16_t
&
)
=
0
;
virtual
error
apply_impl
(
int32_t
&
)
=
0
;
virtual
error
apply_impl
(
uint32_t
&
)
=
0
;
virtual
error
apply_impl
(
int64_t
&
)
=
0
;
virtual
error
apply_impl
(
uint64_t
&
)
=
0
;
virtual
error
apply_impl
(
float
&
)
=
0
;
virtual
error
apply_impl
(
double
&
)
=
0
;
virtual
error
apply_impl
(
long
double
&
)
=
0
;
virtual
error
apply_impl
(
std
::
string
&
)
=
0
;
virtual
error
apply_impl
(
std
::
u16string
&
)
=
0
;
virtual
error
apply_impl
(
std
::
u32string
&
)
=
0
;
private
:
private
:
template
<
class
T
>
template
<
class
T
>
...
...
libcaf_core/caf/detail/select_integer_type.hpp
View file @
89bf26d1
...
@@ -23,49 +23,52 @@
...
@@ -23,49 +23,52 @@
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
detail
{
template
<
int
>
template
<
int
,
bool
>
struct
select_integer_type
;
struct
select_integer_type
;
template
<
>
template
<
>
struct
select_integer_type
<
-
1
>
{
struct
select_integer_type
<
1
,
true
>
{
using
type
=
int8_t
;
using
type
=
int8_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
1
>
{
struct
select_integer_type
<
1
,
false
>
{
using
type
=
uint8_t
;
using
type
=
uint8_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
-
2
>
{
struct
select_integer_type
<
2
,
true
>
{
using
type
=
int16_t
;
using
type
=
int16_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
2
>
{
struct
select_integer_type
<
2
,
false
>
{
using
type
=
uint16_t
;
using
type
=
uint16_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
-
4
>
{
struct
select_integer_type
<
4
,
true
>
{
using
type
=
int32_t
;
using
type
=
int32_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
4
>
{
struct
select_integer_type
<
4
,
false
>
{
using
type
=
uint32_t
;
using
type
=
uint32_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
-
8
>
{
struct
select_integer_type
<
8
,
true
>
{
using
type
=
int64_t
;
using
type
=
int64_t
;
};
};
template
<
>
template
<
>
struct
select_integer_type
<
8
>
{
struct
select_integer_type
<
8
,
false
>
{
using
type
=
uint64_t
;
using
type
=
uint64_t
;
};
};
template
<
int
Size
,
bool
IsSigned
>
using
select_integer_type_t
=
typename
select_integer_type
<
Size
,
IsSigned
>::
type
;
}
// namespace detail
}
// namespace detail
}
// namespace caf
}
// namespace caf
libcaf_core/caf/stream_deserializer.hpp
View file @
89bf26d1
...
@@ -18,22 +18,21 @@
...
@@ -18,22 +18,21 @@
#pragma once
#pragma once
#include <limits>
#include <string>
#include <sstream>
#include <cstddef>
#include <cstddef>
#include <cstdint>
#include <cstdint>
#include <cstring>
#include <cstring>
#include <iomanip>
#include <iomanip>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <type_traits>
#include "caf/sec.hpp"
#include "caf/logger.hpp"
#include "caf/deserializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/logger.hpp"
#include "caf/sec.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -127,65 +126,81 @@ protected:
...
@@ -127,65 +126,81 @@ protected:
return
none
;
return
none
;
}
}
error
apply_builtin
(
builtin
type
,
void
*
val
)
override
{
error
apply_impl
(
int8_t
&
x
)
override
{
CAF_ASSERT
(
val
!=
nullptr
);
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
switch
(
type
)
{
}
default:
// i8_v or u8_v
CAF_ASSERT
(
type
==
i8_v
||
type
==
u8_v
);
error
apply_impl
(
uint8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
uint8_t
),
val
);
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
case
i16_v
:
}
case
u16_v
:
return
apply_int
(
*
reinterpret_cast
<
uint16_t
*>
(
val
));
error
apply_impl
(
int16_t
&
x
)
override
{
case
i32_v
:
return
apply_int
(
x
);
case
u32_v
:
}
return
apply_int
(
*
reinterpret_cast
<
uint32_t
*>
(
val
));
case
i64_v
:
error
apply_impl
(
uint16_t
&
x
)
override
{
case
u64_v
:
return
apply_int
(
x
);
return
apply_int
(
*
reinterpret_cast
<
uint64_t
*>
(
val
));
}
case
float_v
:
return
apply_float
(
*
reinterpret_cast
<
float
*>
(
val
));
error
apply_impl
(
int32_t
&
x
)
override
{
case
double_v
:
return
apply_int
(
x
);
return
apply_float
(
*
reinterpret_cast
<
double
*>
(
val
));
}
case
ldouble_v
:
{
// the IEEE-754 conversion does not work for long double
error
apply_impl
(
uint32_t
&
x
)
override
{
// => fall back to string serialization (even though it sucks)
return
apply_int
(
x
);
std
::
string
tmp
;
}
auto
e
=
apply
(
tmp
);
if
(
e
)
error
apply_impl
(
int64_t
&
x
)
override
{
return
e
;
return
apply_int
(
x
);
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
}
iss
>>
*
reinterpret_cast
<
long
double
*>
(
val
);
return
none
;
error
apply_impl
(
uint64_t
&
x
)
override
{
}
return
apply_int
(
x
);
case
string8_v
:
{
}
auto
&
str
=
*
reinterpret_cast
<
std
::
string
*>
(
val
);
size_t
str_size
;
error
apply_impl
(
float
&
x
)
override
{
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
return
apply_float
(
x
);
[
&
]
{
str
.
resize
(
str_size
);
}
auto
p
=
&
str
[
0
];
auto
data
=
reinterpret_cast
<
char_type
*>
(
p
);
error
apply_impl
(
double
&
x
)
override
{
auto
s
=
static_cast
<
streamsize
>
(
str_size
);
return
apply_float
(
x
);
return
range_check
(
streambuf_
.
sgetn
(
data
,
s
),
}
str_size
);
},
[
&
]
{
return
end_sequence
();
});
error
apply_impl
(
long
double
&
x
)
override
{
}
// The IEEE-754 conversion does not work for long double
case
string16_v
:
{
// => fall back to string serialization (even though it sucks).
auto
&
str
=
*
reinterpret_cast
<
std
::
u16string
*>
(
val
);
std
::
string
tmp
;
str
.
clear
();
if
(
auto
err
=
apply
(
tmp
))
size_t
ns
;
return
err
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
ns
);
},
std
::
istringstream
iss
{
std
::
move
(
tmp
)};
[
&
]
{
return
fill_range_c
<
uint16_t
>
(
str
,
ns
);
},
iss
>>
x
;
[
&
]
{
return
end_sequence
();
});
return
none
;
}
}
case
string32_v
:
{
auto
&
str
=
*
reinterpret_cast
<
std
::
u32string
*>
(
val
);
error
apply_impl
(
std
::
string
&
x
)
override
{
str
.
clear
();
size_t
str_size
;
size_t
ns
;
if
(
auto
err
=
begin_sequence
(
str_size
))
return
error
::
eval
([
&
]
{
return
begin_sequence
(
ns
);
},
return
err
;
[
&
]
{
return
fill_range_c
<
uint32_t
>
(
str
,
ns
);
},
x
.
resize
(
str_size
);
[
&
]
{
return
end_sequence
();
});
auto
s
=
static_cast
<
streamsize
>
(
str_size
);
}
auto
data
=
reinterpret_cast
<
char_type
*>
(
&
x
[
0
]);
}
if
(
auto
err
=
range_check
(
streambuf_
.
sgetn
(
data
,
s
),
str_size
))
return
err
;
return
end_sequence
();
}
error
apply_impl
(
std
::
u16string
&
x
)
override
{
size_t
str_size
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
fill_range_c
<
uint16_t
>
(
x
,
str_size
);
},
[
&
]
{
return
end_sequence
();
});
}
error
apply_impl
(
std
::
u32string
&
x
)
override
{
size_t
str_size
;
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
fill_range_c
<
uint32_t
>
(
x
,
str_size
);
},
[
&
]
{
return
end_sequence
();
});
}
}
error
range_check
(
std
::
streamsize
got
,
size_t
need
)
{
error
range_check
(
std
::
streamsize
got
,
size_t
need
)
{
...
@@ -197,20 +212,18 @@ protected:
...
@@ -197,20 +212,18 @@ protected:
template
<
class
T
>
template
<
class
T
>
error
apply_int
(
T
&
x
)
{
error
apply_int
(
T
&
x
)
{
T
tmp
;
typename
std
::
make_unsigned
<
T
>::
type
tmp
=
0
;
auto
e
=
apply_raw
(
sizeof
(
T
),
&
tmp
);
if
(
auto
err
=
apply_raw
(
sizeof
(
T
),
&
tmp
))
if
(
e
)
return
err
;
return
e
;
x
=
static_cast
<
T
>
(
detail
::
from_network_order
(
tmp
));
x
=
detail
::
from_network_order
(
tmp
);
return
none
;
return
none
;
}
}
template
<
class
T
>
template
<
class
T
>
error
apply_float
(
T
&
x
)
{
error
apply_float
(
T
&
x
)
{
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
tmp
=
0
;
typename
detail
::
ieee_754_trait
<
T
>::
packed_type
tmp
=
0
;
auto
e
=
apply_int
(
tmp
);
if
(
auto
err
=
apply_int
(
tmp
))
if
(
e
)
return
err
;
return
e
;
x
=
detail
::
unpack754
(
tmp
);
x
=
detail
::
unpack754
(
tmp
);
return
none
;
return
none
;
}
}
...
...
libcaf_core/caf/stream_serializer.hpp
View file @
89bf26d1
...
@@ -125,65 +125,81 @@ protected:
...
@@ -125,65 +125,81 @@ protected:
return
none
;
return
none
;
}
}
error
apply_builtin
(
builtin
type
,
void
*
val
)
override
{
error
apply_impl
(
int8_t
&
x
)
override
{
CAF_ASSERT
(
val
!=
nullptr
);
return
apply_raw
(
sizeof
(
int8_t
),
&
x
);
switch
(
type
)
{
}
default:
// i8_v or u8_v
CAF_ASSERT
(
type
==
i8_v
||
type
==
u8_v
);
error
apply_impl
(
uint8_t
&
x
)
override
{
return
apply_raw
(
sizeof
(
uint8_t
),
val
);
return
apply_raw
(
sizeof
(
uint8_t
),
&
x
);
case
i16_v
:
}
case
u16_v
:
return
apply_int
(
*
reinterpret_cast
<
uint16_t
*>
(
val
));
error
apply_impl
(
int16_t
&
x
)
override
{
case
i32_v
:
return
apply_int
(
x
);
case
u32_v
:
}
return
apply_int
(
*
reinterpret_cast
<
uint32_t
*>
(
val
));
case
i64_v
:
error
apply_impl
(
uint16_t
&
x
)
override
{
case
u64_v
:
return
apply_int
(
x
);
return
apply_int
(
*
reinterpret_cast
<
uint64_t
*>
(
val
));
}
case
float_v
:
return
apply_int
(
detail
::
pack754
(
*
reinterpret_cast
<
float
*>
(
val
)));
error
apply_impl
(
int32_t
&
x
)
override
{
case
double_v
:
return
apply_int
(
x
);
return
apply_int
(
detail
::
pack754
(
*
reinterpret_cast
<
double
*>
(
val
)));
}
case
ldouble_v
:
{
// the IEEE-754 conversion does not work for long double
error
apply_impl
(
uint32_t
&
x
)
override
{
// => fall back to string serialization (event though it sucks)
return
apply_int
(
x
);
std
::
ostringstream
oss
;
}
oss
<<
std
::
setprecision
(
std
::
numeric_limits
<
long
double
>::
digits
)
<<
*
reinterpret_cast
<
long
double
*>
(
val
);
error
apply_impl
(
int64_t
&
x
)
override
{
auto
tmp
=
oss
.
str
();
return
apply_int
(
x
);
return
apply
(
tmp
);
}
}
case
string8_v
:
{
error
apply_impl
(
uint64_t
&
x
)
override
{
auto
str
=
reinterpret_cast
<
std
::
string
*>
(
val
);
return
apply_int
(
x
);
auto
s
=
str
->
size
();
}
auto
data
=
reinterpret_cast
<
char_type
*>
(
const_cast
<
std
::
string
::
value_type
*>
(
str
->
data
()));
error
apply_impl
(
float
&
x
)
override
{
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
return
apply_int
(
detail
::
pack754
(
x
));
[
&
]
{
return
apply_raw
(
str
->
size
(),
data
);
},
}
[
&
]
{
return
end_sequence
();
});
}
error
apply_impl
(
double
&
x
)
override
{
case
string16_v
:
{
return
apply_int
(
detail
::
pack754
(
x
));
auto
str
=
reinterpret_cast
<
std
::
u16string
*>
(
val
);
}
auto
s
=
str
->
size
();
// the standard does not guarantee that char16_t is exactly 16 bits...
error
apply_impl
(
long
double
&
x
)
override
{
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
// The IEEE-754 conversion does not work for long double
[
&
]
{
return
consume_range_c
<
uint16_t
>
(
*
str
);
},
// => fall back to string serialization (event though it sucks).
[
&
]
{
return
end_sequence
();
});
std
::
ostringstream
oss
;
}
oss
<<
std
::
setprecision
(
std
::
numeric_limits
<
long
double
>::
digits
)
<<
x
;
case
string32_v
:
{
auto
tmp
=
oss
.
str
();
auto
str
=
reinterpret_cast
<
std
::
u32string
*>
(
val
);
return
apply_impl
(
tmp
);
auto
s
=
str
->
size
();
}
// the standard does not guarantee that char32_t is exactly 32 bits...
return
error
::
eval
([
&
]
{
return
begin_sequence
(
s
);
},
error
apply_impl
(
std
::
string
&
x
)
override
{
[
&
]
{
return
consume_range_c
<
uint32_t
>
(
*
str
);
},
auto
str_size
=
x
.
size
();
[
&
]
{
return
end_sequence
();
});
auto
data
=
const_cast
<
char
*>
(
x
.
c_str
());
}
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
}
[
&
]
{
return
apply_raw
(
x
.
size
(),
data
);
},
[
&
]
{
return
end_sequence
();
});
}
error
apply_impl
(
std
::
u16string
&
x
)
override
{
auto
str_size
=
x
.
size
();
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
consume_range_c
<
uint16_t
>
(
x
);
},
[
&
]
{
return
end_sequence
();
});
}
error
apply_impl
(
std
::
u32string
&
x
)
override
{
auto
str_size
=
x
.
size
();
return
error
::
eval
([
&
]
{
return
begin_sequence
(
str_size
);
},
[
&
]
{
return
consume_range_c
<
uint32_t
>
(
x
);
},
[
&
]
{
return
end_sequence
();
});
}
}
template
<
class
T
>
template
<
class
T
>
error
apply_int
(
T
x
)
{
error
apply_int
(
T
x
)
{
auto
y
=
detail
::
to_network_order
(
x
);
using
unsigned_type
=
typename
std
::
make_unsigned
<
T
>::
type
;
auto
y
=
detail
::
to_network_order
(
static_cast
<
unsigned_type
>
(
x
));
return
apply_raw
(
sizeof
(
T
),
&
y
);
return
apply_raw
(
sizeof
(
T
),
&
y
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment