Skip to content

Commit b4e949a

Browse files
committed
templates
1 parent 58d10dd commit b4e949a

File tree

2 files changed

+124
-1
lines changed

2 files changed

+124
-1
lines changed

include/signalrclient/converters.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#pragma once
2+
3+
#include "signalr_value.h"
4+
#include <stdexcept>
5+
6+
namespace signalr
7+
{
8+
template <typename T>
9+
class is_map
10+
{
11+
public:
12+
static const bool value = false;
13+
};
14+
15+
template <typename T>
16+
class is_map<std::map<std::string, T>>
17+
{
18+
public:
19+
static const bool value = true;
20+
};
21+
22+
template <typename T>
23+
class is_vector
24+
{
25+
public:
26+
static const bool value = false;
27+
};
28+
29+
template <typename T>
30+
class is_vector<std::vector<T>>
31+
{
32+
public:
33+
static const bool value = true;
34+
};
35+
36+
template <typename T, std::enable_if_t<!is_map<std::enable_if_t<!is_vector<T>::value, T>>::value, int> = 0>
37+
T convert_value(const signalr::value& value)
38+
{
39+
static_assert(false, "type conversion not defined");
40+
throw std::runtime_error("failed");
41+
}
42+
43+
template <>
44+
inline int convert_value<int>(const signalr::value& value)
45+
{
46+
if (value.is_double())
47+
{
48+
return (int)value.as_double();
49+
}
50+
throw std::runtime_error("not type");
51+
}
52+
53+
template <>
54+
inline std::string convert_value<std::string>(const signalr::value& value)
55+
{
56+
if (value.is_string())
57+
{
58+
return value.as_string();
59+
}
60+
throw std::runtime_error("not type");
61+
}
62+
63+
template <typename T>
64+
typename std::enable_if_t<is_map<T>::value, T> convert_value(const signalr::value& value)
65+
{
66+
if (value.is_map())
67+
{
68+
T map{};
69+
for (auto& v : value.as_map())
70+
{
71+
map.insert(std::make_pair(v.first, convert_value<typename T::mapped_type>(v.second)));
72+
}
73+
return map;
74+
}
75+
throw std::runtime_error("not type");
76+
}
77+
78+
template <typename T>
79+
typename std::enable_if_t<is_vector<T>::value, T> convert_value(const signalr::value& value)
80+
{
81+
if (value.is_array())
82+
{
83+
T vec{};
84+
for (auto& v : value.as_array())
85+
{
86+
vec.push_back(convert_value<typename T::value_type>(v));
87+
}
88+
return vec;
89+
}
90+
throw std::runtime_error("not type");
91+
}
92+
}

include/signalrclient/hub_connection.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "log_writer.h"
1313
#include "signalr_client_config.h"
1414
#include "signalr_value.h"
15+
#include "converters.h"
1516

1617
namespace signalr
1718
{
@@ -21,6 +22,24 @@ namespace signalr
2122
class hub_connection_builder;
2223
class hub_protocol;
2324

25+
/*template <typename T, int = 0>
26+
T convert_value(const signalr::value& value);*/
27+
28+
/*template <typename T, std::enable_if_t<!is_map<std::enable_if_t<!is_vector<T>::value, T>>::value, int> = 0>
29+
T convert_value(const signalr::value& value);
30+
31+
template <>
32+
int convert_value<int>(const signalr::value& value);
33+
34+
template <>
35+
std::string convert_value<std::string>(const signalr::value& value);
36+
37+
template <typename T>
38+
typename std::enable_if_t<is_map<T>::value, T> convert_value(const signalr::value& value);
39+
40+
template <typename T>
41+
typename std::enable_if_t<is_vector<T>::value, T> convert_value(const signalr::value& value);*/
42+
2443
class hub_connection
2544
{
2645
public:
@@ -48,6 +67,18 @@ namespace signalr
4867

4968
SIGNALRCLIENT_API void __cdecl on(const std::string& event_name, const method_invoked_handler& handler);
5069

70+
template <typename T>
71+
SIGNALRCLIENT_API void on(const std::string& event_name, std::function<void(T)> handler)
72+
{
73+
return on(event_name, [handler](const std::vector<signalr::value>& args)
74+
{
75+
handler(convert_value<T>(args[0]));
76+
});
77+
}
78+
79+
/*template <typename T>
80+
SIGNALRCLIENT_API void on(const std::string& event_name, std::function<void (T)> handler);*/
81+
5182
SIGNALRCLIENT_API void invoke(const std::string& method_name, const std::vector<signalr::value>& arguments = std::vector<signalr::value>(), std::function<void(const signalr::value&, std::exception_ptr)> callback = [](const signalr::value&, std::exception_ptr) {}) noexcept;
5283

5384
SIGNALRCLIENT_API void send(const std::string& method_name, const std::vector<signalr::value>& arguments = std::vector<signalr::value>(), std::function<void(std::exception_ptr)> callback = [](std::exception_ptr) {}) noexcept;
@@ -63,4 +94,4 @@ namespace signalr
6394

6495
std::shared_ptr<hub_connection_impl> m_pImpl;
6596
};
66-
}
97+
}

0 commit comments

Comments
 (0)