GNU Radio Manual and C++ API Reference 3.8.5.0
The Free & Open Software Radio Ecosystem
 
Loading...
Searching...
No Matches
rpc_shared_ptr_selection.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright 2019 Free Software Foundation, Inc.
4 *
5 * This file is part of GNU Radio
6 *
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
11 *
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#ifndef RPC_SHARED_PTR_SELECTION_H
24#define RPC_SHARED_PTR_SELECTION_H
25
26#include <memory>
27
28#include "gnuradio/config.h"
29#ifdef GR_RPCSERVER_THRIFT
30#ifdef THRIFT_HAS_VERSION_H
31#include <thrift/version.h>
32#endif
33// to get boost includes, if and only if they're still in Thrift:
34#include <thrift/concurrency/Thread.h>
35#endif
36
37// select a "shared_ptr" type to use: std:: or boost::
38//
39// Dear Thrift maintainers, should you read this, here's a haiku:
40//
41// Version numbers carved in strings
42// C Preprocessor can't
43// Templates can't
44// Sadness
45
46
47namespace gr {
48
49//! \brief constexpr check for whether a character is a digit
50constexpr bool digit(char d) { return !(d < '0' || d > '9'); }
51
52/* \brief Convert C string to a Version magic, constexpr.
53 *
54 * Converts "5.10.3" to 5·10⁶ + 10·10³+ 3 = 5 010 003
55 */
56constexpr uint64_t cstr_to_version_magic(const char* cstr, uint64_t magicsofar)
57{
58 // OK, we go: check for the current character being a zero byte, in that case,
59 // return magicsofar
60 return *cstr ?
61 // next, check whether a digit, in that case, multiply magicsofar with
62 // 10, and parse on into the sunset
63 (digit(*cstr)
64 ? cstr_to_version_magic(cstr + 1, magicsofar * 10 + (*cstr - '0'))
65 :
66 // if it's not a digit, maybe it's a dot? throw
67 ((*cstr) == '.' ?
68 // it's a dot -> multiply by one hundred, move on
69 cstr_to_version_magic(cstr + 1, magicsofar * 100)
70 :
71 // not a dot, not a digit, not an end byte
72 (throw "String is not a x.y.z version string")))
73 : magicsofar;
74}
75
76/* \brief Convert three-element version numbers to a single unsigned integer. constexpr.
77 *
78 * Converts 5, 10, 3 to 5·10⁶ + 10·10³+ 3 = 5 010 003
79 */
80constexpr uint64_t
81version_to_version_magic(unsigned int x, unsigned int y, unsigned int z)
82{
83 return (uint64_t)x * 1000 * 1000 + y * 1000 + z;
84}
85
86/* \brief Thrift-specific version check
87 *
88 * Evaluates THRIFT_VERSION as string by converting it to a version magic.
89 *
90 * Then, compares that to 0.11.0, which is the first release where Thrift might use
91 * std::shared_ptrs.
92 *
93 * Then, compares to 0.13.0, which is the release where Thrift only uses
94 * std::shared_ptr.
95 *
96 * If inbetween, do the same check that Thrift does in their 0.11-0.12
97 * stdcxx.h headers, minus the redundant MSVC check, which is guaranteed by our MSVC
98 * minimum requirement, anyway
99 */
101{
102#ifndef THRIFT_VERSION
103 // if there's no thrift, then that doesn't use boost
104 return false;
105#else // THRIFT_VERSION
106 return (cstr_to_version_magic(THRIFT_VERSION, 0) <
107 version_to_version_magic(0, 11, 0)) ||
108 (cstr_to_version_magic(THRIFT_VERSION, 0) <
109 version_to_version_magic(0, 13, 0) &&
110 /* This is the internal check that thrift does in 0.11 and 0.12 to decide whether to
111 use std:: or boost::shared_ptr. As soon as we require Thrift >= 0.13.0 this
112 #define-based check is to be removed. */
113#if defined(BOOST_NO_CXX11_SMART_PTR) || defined(FORCE_BOOST_SMART_PTR)
114 true
115#else
116 false
117#endif
118 );
119#endif // THRIFT_VERSION
120}
121
122/* \brief template base class; unspecialized; specializations hold a `t` member that's
123 * actually a Thrift-compatible `shared_ptr`.
124 */
125template <bool use_std, class T>
126struct rpc_sptr_impl;
127
128//! \brief template specialization holding a `std::shared_ptr`
129template <class T>
130struct rpc_sptr_impl<true, T> {
131 using t = std::shared_ptr<T>;
132};
133
134#ifdef BOOST_SHARED_PTR_HPP_INCLUDED
135//! \brief template specialization holding a `boost::shared_ptr`
136template <class T>
137struct rpc_sptr_impl<false, T> {
138 using t = boost::shared_ptr<T>;
139};
140#endif
141
142/* \brief template class with ::t member type that is std:: or boost::shared_ptr,
143 * depending on `thrift_version_uses_boost()`.
144 */
145template <class T>
146struct rpc_sptr {
147 using t = typename rpc_sptr_impl<!thrift_version_uses_boost(), T>::t;
148};
149} // namespace gr
150#endif
GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
Definition basic_block.h:46
constexpr bool digit(char d)
constexpr check for whether a character is a digit
Definition rpc_shared_ptr_selection.h:50
constexpr uint64_t cstr_to_version_magic(const char *cstr, uint64_t magicsofar)
Definition rpc_shared_ptr_selection.h:56
constexpr bool thrift_version_uses_boost()
Definition rpc_shared_ptr_selection.h:100
constexpr uint64_t version_to_version_magic(unsigned int x, unsigned int y, unsigned int z)
Definition rpc_shared_ptr_selection.h:81