Skip to content

Commit 055ad2d

Browse files
committed
feat: Add option_t
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent 709d554 commit 055ad2d

File tree

5 files changed

+84
-4
lines changed

5 files changed

+84
-4
lines changed

include/cmcpp/lift.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ namespace cmcpp
4545
template <Variant T>
4646
inline T lift_flat(const CallContext &cx, const CoreValueIter &vi);
4747

48+
template <Option T>
49+
inline T lift_flat(const CallContext &cx, const CoreValueIter &vi);
50+
4851
}
4952

5053
#endif

include/cmcpp/lower.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ namespace cmcpp
6161
template <Variant T>
6262
inline WasmValVector lower_flat(CallContext &cx, const T &v);
6363

64+
template <Option T>
65+
inline WasmValVector lower_flat(CallContext &cx, const T &v);
6466
}
6567

6668
#endif

include/cmcpp/traits.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ namespace cmcpp
148148
{
149149
static_assert(false, "T is not a valid type for ValTrait. Type: ");
150150
static constexpr ValType type = ValType::UNKNOWN;
151-
using inner_type = void;
151+
using inner_type = std::monostate;
152152
static constexpr uint32_t size = 0;
153153
static constexpr uint32_t alignment = 0;
154154
static constexpr std::array<WasmValType, 0> flat_types = {};
@@ -675,7 +675,20 @@ namespace cmcpp
675675
template <typename T>
676676
concept Variant = ValTrait<T>::type == ValType::Variant;
677677

678-
// Other --------------------------------------------------------------------
678+
// Option --------------------------------------------------------------------
679+
template <Field T>
680+
using option_t = std::optional<T>;
681+
template <Field T>
682+
struct ValTrait<option_t<T>>
683+
{
684+
static constexpr ValType type = ValType::Option;
685+
using inner_type = T;
686+
static constexpr uint32_t size = ValTrait<variant_t<bool_t, T>>::size;
687+
static constexpr uint32_t alignment = ValTrait<variant_t<bool_t, T>>::size;
688+
static constexpr auto flat_types = ValTrait<variant_t<bool_t, T>>::flat_types;
689+
};
690+
template <typename T>
691+
concept Option = ValTrait<T>::type == ValType::Option;
679692

680693
// --------------------------------------------------------------------
681694

include/cmcpp/variant.hpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace cmcpp
8787
};
8888

8989
template <Variant T>
90-
WasmValVector lower_flat_variant(CallContext &cx, const T &v)
90+
WasmValVector lower_flat(CallContext &cx, const T &v)
9191
{
9292
auto case_index = v.index();
9393
WasmValTypeVector flat_types(ValTrait<T>::flat_types.begin(), ValTrait<T>::flat_types.end());
@@ -180,7 +180,22 @@ namespace cmcpp
180180
template <Variant T>
181181
inline WasmValVector lower_flat(CallContext &cx, const T &v)
182182
{
183-
return variant::lower_flat_variant(cx, v);
183+
return variant::lower_flat(cx, v);
184+
}
185+
186+
template <Option T>
187+
inline WasmValVector lower_flat(CallContext &cx, const T &v)
188+
{
189+
using V = variant_t<bool_t, typename ValTrait<T>::inner_type>;
190+
if (v.has_value())
191+
{
192+
V v2 = v.value();
193+
return variant::lower_flat(cx, v2);
194+
}
195+
else
196+
{
197+
return variant::lower_flat<V>(cx, false);
198+
}
184199
}
185200

186201
template <Variant T>
@@ -195,6 +210,19 @@ namespace cmcpp
195210
return variant::lift_flat<T>(cx, vi);
196211
}
197212

213+
template <Option T>
214+
inline T lift_flat(const CallContext &cx, const CoreValueIter &vi)
215+
{
216+
T retVal;
217+
using V = variant_t<bool_t, typename ValTrait<T>::inner_type>;
218+
auto v = variant::lift_flat<V>(cx, vi);
219+
if (v.index() == 1)
220+
{
221+
retVal = std::get<1>(v);
222+
}
223+
return retVal;
224+
}
225+
198226
}
199227

200228
#endif

test/main.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,12 @@ TEST_CASE("Variant")
491491
Heap heap(1024 * 1024);
492492
auto cx = createCallContext(&heap, Encoding::Utf8);
493493

494+
using Vb = variant_t<bool_t, uint32_t>;
495+
Vb vb = static_cast<uint32_t>(42);
496+
auto vvb = lower_flat(*cx, vb);
497+
auto vbb = lift_flat<Vb>(*cx, vvb);
498+
CHECK(vb == vbb);
499+
494500
using V0 = variant_t<uint16_t, uint32_t>;
495501
auto x = ValTrait<ValTrait<V0>::discriminant_type>::size;
496502
V0 v0 = static_cast<uint32_t>(42);
@@ -559,3 +565,31 @@ TEST_CASE("Variant")
559565
auto v88 = lift_flat<VariantList4>(*cx, vv8);
560566
CHECK(variants4 == v88);
561567
}
568+
569+
TEST_CASE("Option")
570+
{
571+
Heap heap(1024 * 1024);
572+
auto cx = createCallContext(&heap, Encoding::Utf8);
573+
574+
using O0 = option_t<uint32_t>;
575+
O0 o0 = 42;
576+
auto vv0 = lower_flat(*cx, o0);
577+
auto v00 = lift_flat<O0>(*cx, vv0);
578+
CHECK(o0 == v00);
579+
580+
O0 o1;
581+
auto vv1 = lower_flat(*cx, o1);
582+
auto v01 = lift_flat<O0>(*cx, vv1);
583+
CHECK(o1 == v01);
584+
585+
using O1 = option_t<string_t>;
586+
O1 o2 = "Hello";
587+
auto vv2 = lower_flat(*cx, o2);
588+
auto v02 = lift_flat<O1>(*cx, vv2);
589+
CHECK(o2 == v02);
590+
591+
O1 o3;
592+
auto vv3 = lower_flat(*cx, o3);
593+
auto v03 = lift_flat<O1>(*cx, vv3);
594+
CHECK(o3 == v03);
595+
}

0 commit comments

Comments
 (0)