Skip to content

Commit 4261ffe

Browse files
committed
Allow late status construction in StatusWrapper
1 parent 6e9ead2 commit 4261ffe

2 files changed

Lines changed: 69 additions & 12 deletions

File tree

src/fb-cpp/Exception.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ using namespace fbcpp;
3232
using namespace fbcpp::impl;
3333

3434

35+
fb::IStatus* StatusWrapper::getStatus() const
36+
{
37+
if (!status)
38+
{
39+
status = client->newStatus().release();
40+
statusOwner = true;
41+
}
42+
43+
return status;
44+
}
45+
3546
void StatusWrapper::checkException(StatusWrapper* status)
3647
{
3748
if (status->dirty && (status->getState() & fb::IStatus::STATE_ERRORS))

src/fb-cpp/Exception.h

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,52 @@ namespace fbcpp::impl
4545
class StatusWrapper : public fb::IStatusImpl<StatusWrapper, StatusWrapper>
4646
{
4747
public:
48-
explicit StatusWrapper(Client& client, IStatus* status)
48+
explicit StatusWrapper(Client& client, IStatus* status = nullptr)
4949
: client{&client},
5050
status{status}
5151
{
5252
}
5353

54+
StatusWrapper(StatusWrapper&& o) noexcept
55+
: client{o.client},
56+
status{o.status},
57+
statusOwner{o.statusOwner},
58+
dirty{o.dirty}
59+
{
60+
o.status = nullptr;
61+
o.statusOwner = false;
62+
o.dirty = false;
63+
}
64+
65+
StatusWrapper& operator=(StatusWrapper&& o) noexcept
66+
{
67+
if (this != &o)
68+
{
69+
if (statusOwner && status)
70+
status->dispose();
71+
72+
client = o.client;
73+
status = o.status;
74+
statusOwner = o.statusOwner;
75+
dirty = o.dirty;
76+
77+
o.status = nullptr;
78+
o.statusOwner = false;
79+
o.dirty = false;
80+
}
81+
82+
return *this;
83+
}
84+
85+
StatusWrapper(const StatusWrapper&) = delete;
86+
StatusWrapper& operator=(const StatusWrapper&) = delete;
87+
88+
~StatusWrapper()
89+
{
90+
if (statusOwner && status)
91+
status->dispose();
92+
}
93+
5494
public:
5595
static void checkException(StatusWrapper* status);
5696

@@ -66,7 +106,7 @@ namespace fbcpp::impl
66106
if (dirty)
67107
{
68108
dirty = false;
69-
status->init();
109+
getStatus()->init();
70110
}
71111
}
72112

@@ -105,8 +145,11 @@ namespace fbcpp::impl
105145
void dispose() noexcept override
106146
{
107147
// Disposes only the delegated status. Let the user destroy this instance.
108-
status->dispose();
148+
if (status)
149+
status->dispose();
150+
109151
status = nullptr;
152+
statusOwner = false;
110153
}
111154

112155
void init() noexcept override
@@ -116,53 +159,56 @@ namespace fbcpp::impl
116159

117160
unsigned getState() const noexcept override
118161
{
119-
return dirty ? status->getState() : 0;
162+
return dirty ? getStatus()->getState() : 0;
120163
}
121164

122165
void setErrors2(unsigned length, const intptr_t* value) noexcept override
123166
{
124167
dirty = true;
125-
status->setErrors2(length, value);
168+
getStatus()->setErrors2(length, value);
126169
}
127170

128171
void setWarnings2(unsigned length, const intptr_t* value) noexcept override
129172
{
130173
dirty = true;
131-
status->setWarnings2(length, value);
174+
getStatus()->setWarnings2(length, value);
132175
}
133176

134177
void setErrors(const intptr_t* value) noexcept override
135178
{
136179
dirty = true;
137-
status->setErrors(value);
180+
getStatus()->setErrors(value);
138181
}
139182

140183
void setWarnings(const intptr_t* value) noexcept override
141184
{
142185
dirty = true;
143-
status->setWarnings(value);
186+
getStatus()->setWarnings(value);
144187
}
145188

146189
const intptr_t* getErrors() const noexcept override
147190
{
148-
return dirty ? status->getErrors() : cleanStatus();
191+
return dirty ? getStatus()->getErrors() : cleanStatus();
149192
}
150193

151194
const intptr_t* getWarnings() const noexcept override
152195
{
153-
return dirty ? status->getWarnings() : cleanStatus();
196+
return dirty ? getStatus()->getWarnings() : cleanStatus();
154197
}
155198

156199
IStatus* clone() const noexcept override
157200
{
158-
return status->clone();
201+
return getStatus()->clone();
159202
}
160203

161204
protected:
162205
Client* client;
163-
IStatus* status;
206+
mutable IStatus* status;
207+
mutable bool statusOwner = false;
164208
bool dirty = false;
165209

210+
IStatus* getStatus() const;
211+
166212
static const intptr_t* cleanStatus() noexcept
167213
{
168214
static intptr_t clean[3] = {1, 0, 0};

0 commit comments

Comments
 (0)