File: cpp20_containers.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (146 lines) | stat: -rw-r--r-- 3,768 bytes parent folder | download | duplicates (3)
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) 2018-2025 Marcelo Zimbres Silva (mzimbres@gmail.com)
 *
 * Distributed under the Boost Software License, Version 1.0. (See
 * accompanying file LICENSE.txt)
 */

#include <boost/redis/connection.hpp>

#include <boost/asio/co_spawn.hpp>
#include <boost/asio/consign.hpp>
#include <boost/asio/detached.hpp>

#include <iostream>
#include <map>
#include <vector>

#if defined(BOOST_ASIO_HAS_CO_AWAIT)

namespace asio = boost::asio;
using boost::redis::request;
using boost::redis::response;
using boost::redis::ignore_t;
using boost::redis::ignore;
using boost::redis::config;
using boost::redis::connection;
using boost::asio::awaitable;
using boost::asio::detached;
using boost::asio::consign;

template <class T>
std::ostream& operator<<(std::ostream& os, std::optional<T> const& opt)
{
   if (opt.has_value())
      std::cout << opt.value();
   else
      std::cout << "null";

   return os;
}

void print(std::map<std::string, std::string> const& cont)
{
   for (auto const& e : cont)
      std::cout << e.first << ": " << e.second << "\n";
}

template <class T>
void print(std::vector<T> const& cont)
{
   for (auto const& e : cont)
      std::cout << e << " ";
   std::cout << "\n";
}

// Stores the content of some STL containers in Redis.
auto store(std::shared_ptr<connection> conn) -> awaitable<void>
{
   std::vector<int> vec{1, 2, 3, 4, 5, 6};

   std::map<std::string, std::string> map{
      {"key1", "value1"},
      {"key2", "value2"},
      {"key3", "value3"}
   };

   request req;
   req.push_range("RPUSH", "rpush-key", vec);
   req.push_range("HSET", "hset-key", map);
   req.push("SET", "key", "value");

   co_await conn->async_exec(req, ignore);
}

auto hgetall(std::shared_ptr<connection> conn) -> awaitable<void>
{
   // A request contains multiple commands.
   request req;
   req.push("HGETALL", "hset-key");

   // Responses as tuple elements.
   response<std::map<std::string, std::string>> resp;

   // Executes the request and reads the response.
   co_await conn->async_exec(req, resp);

   print(std::get<0>(resp).value());
}

auto mget(std::shared_ptr<connection> conn) -> awaitable<void>
{
   // A request contains multiple commands.
   request req;
   req.push("MGET", "key", "non-existing-key");

   // Responses as tuple elements.
   response<std::vector<std::optional<std::string>>> resp;

   // Executes the request and reads the response.
   co_await conn->async_exec(req, resp);

   print(std::get<0>(resp).value());
}

// Retrieves in a transaction.
auto transaction(std::shared_ptr<connection> conn) -> awaitable<void>
{
   request req;
   req.push("MULTI");
   req.push("LRANGE", "rpush-key", 0, -1);  // Retrieves
   req.push("HGETALL", "hset-key");         // Retrieves
   req.push("MGET", "key", "non-existing-key");
   req.push("EXEC");

   response<
      ignore_t,  // multi
      ignore_t,  // lrange
      ignore_t,  // hgetall
      ignore_t,  // mget
      response<
         std::optional<std::vector<int>>,
         std::optional<std::map<std::string, std::string>>,
         std::optional<std::vector<std::optional<std::string>>>>  // exec
      >
      resp;

   co_await conn->async_exec(req, resp);

   print(std::get<0>(std::get<4>(resp).value()).value().value());
   print(std::get<1>(std::get<4>(resp).value()).value().value());
   print(std::get<2>(std::get<4>(resp).value()).value().value());
}

// Called from the main function (see main.cpp)
awaitable<void> co_main(config cfg)
{
   auto conn = std::make_shared<connection>(co_await asio::this_coro::executor);
   conn->async_run(cfg, consign(detached, conn));

   co_await store(conn);
   co_await transaction(conn);
   co_await hgetall(conn);
   co_await mget(conn);
   conn->cancel();
}

#endif  // defined(BOOST_ASIO_HAS_CO_AWAIT)