66#include < aws/crt/Variant.h>
77#include < aws/testing/aws_test_harness.h>
88
9+ #if defined(_WIN32)
10+ # define AWS_VARIANTTEST_WINDOWS_API __declspec (dllexport)
11+ #else
12+ # define AWS_VARIANTTEST_WINDOWS_API
13+ #endif
14+
915const char *s_variant_test_str = " This is a string, that should be long enough to avoid small string optimizations" ;
1016
1117static int s_VariantBasicOperandsCompile (struct aws_allocator *allocator, void *ctx)
@@ -170,7 +176,7 @@ static int s_VariantConstructor(struct aws_allocator *allocator, void *ctx)
170176
171177AWS_TEST_CASE (VariantConstructor, s_VariantConstructor)
172178
173- static int s_VariantOperatorEquals (struct aws_allocator *allocator, void *ctx)
179+ static int s_VariantAssignmentOperator (struct aws_allocator *allocator, void *ctx)
174180{
175181 (void )ctx;
176182 {
@@ -214,7 +220,192 @@ static int s_VariantOperatorEquals(struct aws_allocator *allocator, void *ctx)
214220 return AWS_OP_SUCCESS;
215221}
216222
217- AWS_TEST_CASE (VariantOperatorEquals, s_VariantOperatorEquals)
223+ AWS_TEST_CASE (VariantAssignmentOperator, s_VariantAssignmentOperator)
224+
225+ // Test Variant with move-only underlying type.
226+ // If it compiles, it's considered success.
227+ static int s_VariantWithMoveOnlyUnderlyingType(struct aws_allocator *allocator, void *ctx)
228+ {
229+ (void )ctx;
230+
231+ Aws::Crt::ApiHandle apiHandle (allocator);
232+
233+ struct MoveOnlyTestType
234+ {
235+ MoveOnlyTestType () = default ;
236+
237+ MoveOnlyTestType (MoveOnlyTestType &&) = default ;
238+ MoveOnlyTestType &operator =(MoveOnlyTestType &&) = default ;
239+
240+ MoveOnlyTestType (const MoveOnlyTestType &) = delete ;
241+ MoveOnlyTestType &operator =(const MoveOnlyTestType &) = delete ;
242+ };
243+
244+ using MoveOnlyVariant = Aws::Crt::Variant<MoveOnlyTestType>;
245+
246+ /* Regression test.
247+ * The __declspec(dllexport) directive exports class member function on Windows platform. We enable it when
248+ * building shared libraries. In the past, this directive caused msvc to generate special copy members for classes
249+ * containing Crt::Variant with move-only underlying types, which led to compile-time errors. */
250+ struct AWS_VARIANTTEST_WINDOWS_API MoveOnlyVariantTestResult
251+ {
252+ MoveOnlyVariant m_result;
253+ };
254+
255+ return AWS_OP_SUCCESS;
256+ }
257+
258+ AWS_TEST_CASE (VariantWithMoveOnlyUnderlyingType, s_VariantWithMoveOnlyUnderlyingType)
259+
260+ // Test Variant with copy-only underlying type.
261+ // If it compiles, it's considered success.
262+ static int s_VariantWithCopyOnlyUnderlyingType(struct aws_allocator *allocator, void *ctx)
263+ {
264+ (void )ctx;
265+
266+ Aws::Crt::ApiHandle apiHandle (allocator);
267+
268+ struct CopyOnlyTestType
269+ {
270+ CopyOnlyTestType () = default ;
271+
272+ CopyOnlyTestType (CopyOnlyTestType &&) = default ;
273+ CopyOnlyTestType &operator =(CopyOnlyTestType &&) = default ;
274+
275+ CopyOnlyTestType (const CopyOnlyTestType &) = delete ;
276+ CopyOnlyTestType &operator =(const CopyOnlyTestType &) = delete ;
277+ };
278+
279+ using CopyOnlyVariant = Aws::Crt::Variant<CopyOnlyTestType>;
280+
281+ /* Regression test.
282+ * The __declspec(dllexport) directive exports class member function on Windows platform. We enable it when
283+ * building shared libraries. In the past, this directive caused msvc to generate special copy members for classes
284+ * containing Crt::Variant with copy-only underlying types, which led to compile-time errors. */
285+ struct AWS_VARIANTTEST_WINDOWS_API CopyOnlyVariantTestResult
286+ {
287+ CopyOnlyVariant m_result;
288+ };
289+
290+ return AWS_OP_SUCCESS;
291+ }
292+
293+ AWS_TEST_CASE (VariantWithCopyOnlyUnderlyingType, s_VariantWithCopyOnlyUnderlyingType)
294+
295+ // Test Variant with underlying type without default constructor.
296+ // If it compiles, it's considered success.
297+ static int s_VariantWithNoDefaultConstructibleUnderlyingType(struct aws_allocator *allocator, void *ctx)
298+ {
299+ (void )ctx;
300+
301+ Aws::Crt::ApiHandle apiHandle (allocator);
302+
303+ struct NoDefaultConstructibleTestType
304+ {
305+ explicit NoDefaultConstructibleTestType (int ) {}
306+ NoDefaultConstructibleTestType () = delete ;
307+ };
308+
309+ using NoDefaultConstructibleVariant = Aws::Crt::Variant<NoDefaultConstructibleTestType>;
310+
311+ struct AWS_VARIANTTEST_WINDOWS_API NoDefaultConstructibleVariantTestResult
312+ {
313+ NoDefaultConstructibleVariant m_result;
314+ };
315+
316+ NoDefaultConstructibleTestType testType (1 );
317+ NoDefaultConstructibleVariant variant (testType);
318+ NoDefaultConstructibleVariantTestResult testResult{variant};
319+
320+ return AWS_OP_SUCCESS;
321+ }
322+
323+ AWS_TEST_CASE (VariantWithNoDefaultConstructibleUnderlyingType, s_VariantWithNoDefaultConstructibleUnderlyingType)
324+
325+ static int s_VariantExceptionSafety_DefaultConstructor(struct aws_allocator *allocator, void *ctx)
326+ {
327+ (void )ctx;
328+
329+ Aws::Crt::ApiHandle apiHandle (allocator);
330+
331+ struct NothrowDefaultConstructibleTestType
332+ {
333+ NothrowDefaultConstructibleTestType () noexcept {}
334+ NothrowDefaultConstructibleTestType (const NothrowDefaultConstructibleTestType &) noexcept (false ) {}
335+ NothrowDefaultConstructibleTestType (NothrowDefaultConstructibleTestType &&) noexcept (false ) {}
336+ };
337+
338+ using NothrowDefaultConstructibleVariant = Aws::Crt::Variant<NothrowDefaultConstructibleTestType>;
339+
340+ ASSERT_TRUE (std::is_nothrow_constructible<NothrowDefaultConstructibleVariant>::value);
341+ ASSERT_FALSE ((
342+ std::is_nothrow_constructible<NothrowDefaultConstructibleVariant, const NothrowDefaultConstructibleTestType &>::
343+ value));
344+ ASSERT_FALSE (
345+ (std::is_nothrow_constructible<NothrowDefaultConstructibleVariant, NothrowDefaultConstructibleTestType &&>::
346+ value));
347+
348+ return AWS_OP_SUCCESS;
349+ }
350+
351+ AWS_TEST_CASE (VariantExceptionSafety_DefaultConstructor, s_VariantExceptionSafety_DefaultConstructor)
352+
353+ static int s_VariantExceptionSafety_MoveConstructor(struct aws_allocator *allocator, void *ctx)
354+ {
355+ (void )ctx;
356+
357+ Aws::Crt::ApiHandle apiHandle (allocator);
358+
359+ struct NothrowMoveConstructibleTestType
360+ {
361+ NothrowMoveConstructibleTestType (NothrowMoveConstructibleTestType &&) noexcept {}
362+
363+ NothrowMoveConstructibleTestType () noexcept (false ) {}
364+ NothrowMoveConstructibleTestType (const NothrowMoveConstructibleTestType &) noexcept (false ) {}
365+ };
366+
367+ using NothrowMoveConstructibleVariant = Aws::Crt::Variant<NothrowMoveConstructibleTestType>;
368+
369+ ASSERT_TRUE (
370+ (std::is_nothrow_constructible<NothrowMoveConstructibleVariant, NothrowMoveConstructibleTestType &&>::value));
371+ ASSERT_FALSE (std::is_nothrow_constructible<NothrowMoveConstructibleVariant>::value);
372+ ASSERT_FALSE (
373+ (std::is_nothrow_constructible<NothrowMoveConstructibleVariant, const NothrowMoveConstructibleTestType &>::
374+ value));
375+
376+ return AWS_OP_SUCCESS;
377+ }
378+
379+ AWS_TEST_CASE (VariantExceptionSafety_MoveConstructor, s_VariantExceptionSafety_MoveConstructor)
380+
381+ static int s_VariantExceptionSafety_CopyConstructor(struct aws_allocator *allocator, void *ctx)
382+ {
383+ (void )ctx;
384+
385+ Aws::Crt::ApiHandle apiHandle (allocator);
386+
387+ struct NothrowCopyConstructibleTestType
388+ {
389+ NothrowCopyConstructibleTestType (const NothrowCopyConstructibleTestType &) noexcept {}
390+
391+ NothrowCopyConstructibleTestType () noexcept (false ) {}
392+ NothrowCopyConstructibleTestType (NothrowCopyConstructibleTestType &&) noexcept (false ) {}
393+ };
394+
395+ using NothrowCopyConstructibleVariant = Aws::Crt::Variant<NothrowCopyConstructibleTestType>;
396+
397+ ASSERT_TRUE (
398+ (std::is_nothrow_constructible<NothrowCopyConstructibleVariant, const NothrowCopyConstructibleTestType &>::
399+ value));
400+
401+ ASSERT_FALSE (std::is_nothrow_constructible<NothrowCopyConstructibleVariant>::value);
402+ ASSERT_FALSE (
403+ (std::is_nothrow_constructible<NothrowCopyConstructibleVariant, NothrowCopyConstructibleTestType &&>::value));
404+
405+ return AWS_OP_SUCCESS;
406+ }
407+
408+ AWS_TEST_CASE (VariantExceptionSafety_CopyConstructor, s_VariantExceptionSafety_CopyConstructor)
218409
219410struct TestStringOnlyVisitor
220411{
@@ -364,4 +555,4 @@ static int s_VariantVisitor(struct aws_allocator *allocator, void *ctx)
364555 return AWS_OP_SUCCESS;
365556}
366557
367- AWS_TEST_CASE (VariantVisitor, s_VariantVisitor)
558+ AWS_TEST_CASE (VariantVisitor, s_VariantVisitor)
0 commit comments