C++ Server-Side SDK
LaunchDarkly SDK
Loading...
Searching...
No Matches
c_binding_helpers.hpp
1#pragma once
2
4#include <launchdarkly/error.hpp>
5
6#include <tl/expected.hpp>
7
8#include <cassert>
9#include <functional>
10#include <optional>
11
12namespace launchdarkly::detail {
13template <typename T, typename = void>
14struct has_result_type : std::false_type {};
15
16template <typename T>
17struct has_result_type<T, std::void_t<typename T::Result>> : std::true_type {};
18
19template <typename T, typename ReturnType, typename = void>
20struct has_build_method : std::false_type {};
21
22template <typename T, typename ReturnType>
24 ReturnType,
25 std::void_t<decltype(std::declval<T>().Build())>>
26 : std::integral_constant<
27 bool,
28 std::is_same_v<decltype(std::declval<T>().Build()), ReturnType>> {};
29
30// NOLINTBEGIN cppcoreguidelines-pro-type-reinterpret-cast
31
32/*
33 * Given a Builder, calls the Build() method and converts it into an
34 * OpaqueResult if successful, or an LDError if unsuccessful.
35 *
36 * In the case of an error, out_result is set to nullptr.
37 *
38 * In all cases, the given builder is freed.
39 */
40template <typename Builder, typename OpaqueBuilder, typename OpaqueResult>
41LDStatus ConsumeBuilder(OpaqueBuilder opaque_builder,
42 OpaqueResult* out_result) {
43 using ReturnType =
44 tl::expected<typename Builder::Result, launchdarkly::Error>;
45
47 "Builder must have an associated type named Result");
48
49 static_assert(
51 "Builder must have a Build method that returns "
52 "tl::expected<typename Builder::Result, launchdarkly::Error>");
53
54 auto builder = reinterpret_cast<Builder*>(opaque_builder);
55
56 tl::expected<typename Builder::Result, launchdarkly::Error> res =
57 builder->Build();
58
59 delete builder;
60
61 if (!res) {
62 *out_result = nullptr;
63 return reinterpret_cast<LDStatus>(new launchdarkly::Error(res.error()));
64 }
65
66 *out_result = reinterpret_cast<OpaqueResult>(
67 new typename Builder::Result(std::move(res.value())));
68
69 return LDStatus_Success();
70}
71
72template <typename OptType, typename OutResult>
73bool OptReturn(std::optional<OptType> const& opt, OutResult* out_param) {
74 if (opt) {
75 *out_param = *opt;
76 return true;
77 }
78 return false;
79}
80
81template <typename OptType, typename OutResult>
82bool OptReturnStaticCast(std::optional<OptType> const& opt,
83 OutResult* out_param) {
84 if (opt) {
85 *out_param = static_cast<OutResult>(*opt);
86 return true;
87 }
88 return false;
89}
90
91template <typename OptType, typename OutResult>
92bool OptReturnReinterpretCast(std::optional<OptType>& opt,
93 OutResult* out_param) {
94 if (opt) {
95 *out_param = reinterpret_cast<OutResult>(&(opt.value()));
96 return true;
97 }
98 return false;
99}
100
101// Macro is named the same as in the C Server SDK.
102
103#ifdef LAUNCHDARKLY_USE_ASSERT
104#define LD_ASSERT(cond) assert(cond)
105#else
106#define LD_ASSERT(cond)
107#endif
108
109#define LD_ASSERT_NOT_NULL(param) LD_ASSERT(param != nullptr)
110
111} // namespace launchdarkly::detail
112// NOLINTEND cppcoreguidelines-pro-type-reinterpret-cast
LDStatus_Success(void)
Definition c_binding_helpers.hpp:20
Definition c_binding_helpers.hpp:14