Skip to content

Commit f7b4ec2

Browse files
authored
Merge pull request #239 from anarthal/bugfix/238-int-conversions
Responses now admit all integer types again
2 parents ac4e6e2 + c4e31e5 commit f7b4ec2

File tree

3 files changed

+136
-6
lines changed

3 files changed

+136
-6
lines changed

include/boost/redis/adapter/detail/adapters.hpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <set>
1818
#include <optional>
19+
#include <type_traits>
1920
#include <unordered_set>
2021
#include <forward_list>
2122
#include <system_error>
@@ -37,13 +38,18 @@
3738
namespace boost::redis::adapter::detail
3839
{
3940

40-
template <class> struct is_integral : std::false_type {};
41-
42-
template <> struct is_integral<long long int > : std::true_type {};
43-
template <> struct is_integral<unsigned long long int> : std::true_type {};
44-
template <> struct is_integral<int > : std::true_type {};
41+
// Exclude bools, char and charXY_t types
42+
template <class T> struct is_integral_number : std::is_integral<T> {};
43+
template <> struct is_integral_number<bool> : std::false_type {};
44+
template <> struct is_integral_number<char> : std::false_type {};
45+
template <> struct is_integral_number<char16_t> : std::false_type {};
46+
template <> struct is_integral_number<char32_t> : std::false_type {};
47+
template <> struct is_integral_number<wchar_t> : std::false_type {};
48+
#ifdef __cpp_char8_t
49+
template <> struct is_integral_number<char8_t> : std::false_type {};
50+
#endif
4551

46-
template<class T, bool = is_integral<T>::value>
52+
template<class T, bool = is_integral_number<T>::value>
4753
struct converter;
4854

4955
template<class T>

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ make_test(test_conn_exec_cancel 20)
4747
make_test(test_conn_exec_cancel2 20)
4848
make_test(test_conn_echo_stress 20)
4949
make_test(test_any_adapter 17)
50+
make_test(test_conversions 17)
5051
make_test(test_issue_50 20)
5152
make_test(test_issue_181 17)
5253

test/test_conversions.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/* Copyright (c) 2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
2+
*
3+
* Distributed under the Boost Software License, Version 1.0. (See
4+
* accompanying file LICENSE.txt)
5+
*/
6+
7+
#include "boost/redis/ignore.hpp"
8+
#include "boost/system/detail/error_code.hpp"
9+
#define BOOST_TEST_MODULE conversions
10+
#include <boost/redis/connection.hpp>
11+
#include <boost/test/included/unit_test.hpp>
12+
13+
#include "common.hpp"
14+
15+
namespace net = boost::asio;
16+
using boost::redis::connection;
17+
using boost::redis::ignore_t;
18+
using boost::redis::request;
19+
using boost::redis::response;
20+
using boost::system::error_code;
21+
22+
BOOST_AUTO_TEST_CASE(ints)
23+
{
24+
// Setup
25+
net::io_context ioc;
26+
auto conn = std::make_shared<connection>(ioc);
27+
run(conn);
28+
29+
// Get an integer key as all possible C++ integral types
30+
request req;
31+
req.push("SET", "key", 42);
32+
for (int i = 0; i < 10; ++i)
33+
req.push("GET", "key");
34+
35+
response<
36+
ignore_t,
37+
signed char,
38+
unsigned char,
39+
short,
40+
unsigned short,
41+
int,
42+
unsigned int,
43+
long,
44+
unsigned long,
45+
long long,
46+
unsigned long long
47+
> resp;
48+
49+
conn->async_exec(req, resp, [conn](error_code ec, std::size_t) {
50+
BOOST_TEST(!ec);
51+
conn->cancel();
52+
});
53+
54+
// Run the operations
55+
ioc.run();
56+
57+
// Check
58+
BOOST_TEST(std::get<1>(resp).value() == 42);
59+
BOOST_TEST(std::get<2>(resp).value() == 42);
60+
BOOST_TEST(std::get<3>(resp).value() == 42);
61+
BOOST_TEST(std::get<4>(resp).value() == 42);
62+
BOOST_TEST(std::get<5>(resp).value() == 42);
63+
BOOST_TEST(std::get<6>(resp).value() == 42);
64+
BOOST_TEST(std::get<7>(resp).value() == 42);
65+
BOOST_TEST(std::get<8>(resp).value() == 42);
66+
BOOST_TEST(std::get<9>(resp).value() == 42);
67+
BOOST_TEST(std::get<10>(resp).value() == 42);
68+
}
69+
70+
BOOST_AUTO_TEST_CASE(bools)
71+
{
72+
// Setup
73+
net::io_context ioc;
74+
auto conn = std::make_shared<connection>(ioc);
75+
run(conn);
76+
77+
// Get a boolean
78+
request req;
79+
req.push("SET", "key_true", "t");
80+
req.push("SET", "key_false", "f");
81+
req.push("GET", "key_true");
82+
req.push("GET", "key_false");
83+
84+
response<ignore_t, ignore_t, bool, bool> resp;
85+
86+
conn->async_exec(req, resp, [conn](error_code ec, std::size_t) {
87+
BOOST_TEST(!ec);
88+
conn->cancel();
89+
});
90+
91+
// Run the operations
92+
ioc.run();
93+
94+
// Check
95+
BOOST_TEST(std::get<2>(resp).value() == true);
96+
BOOST_TEST(std::get<3>(resp).value() == false);
97+
}
98+
99+
BOOST_AUTO_TEST_CASE(floating_points)
100+
{
101+
// Setup
102+
net::io_context ioc;
103+
auto conn = std::make_shared<connection>(ioc);
104+
run(conn);
105+
106+
// Get a boolean
107+
request req;
108+
req.push("SET", "key", "4.12");
109+
req.push("GET", "key");
110+
111+
response<ignore_t, double> resp;
112+
113+
conn->async_exec(req, resp, [conn](error_code ec, std::size_t) {
114+
BOOST_TEST(!ec);
115+
conn->cancel();
116+
});
117+
118+
// Run the operations
119+
ioc.run();
120+
121+
// Check
122+
BOOST_TEST(std::get<1>(resp).value() == 4.12);
123+
}

0 commit comments

Comments
 (0)