TEST(Type, OptCouldBe) { for (auto& x : optionals) EXPECT_TRUE(x.couldBe(unopt(x))); auto true_cases = std::initializer_list<std::pair<Type,Type>> { { opt(sval(s_test.get())), TStr }, { opt(sval(s_test.get())), TInitNull }, { opt(sval(s_test.get())), TSStr }, { opt(sval(s_test.get())), sval(s_test.get()) }, { opt(ival(2)), TInt }, { opt(ival(2)), TInitNull }, { opt(ival(2)), ival(2) }, { opt(dval(2.0)), TDbl }, { opt(dval(2.0)), TInitNull }, { opt(dval(2.0)), dval(2) }, { opt(TFalse), TBool }, { opt(TFalse), TFalse }, { opt(TTrue), TBool }, { opt(TTrue), TTrue }, }; auto false_cases = std::initializer_list<std::pair<Type,Type>> { { opt(sval(s_test.get())), TCStr }, { opt(ival(2)), TDbl }, { opt(dval(2.0)), TInt }, { opt(TFalse), TTrue }, { opt(TTrue), TFalse }, }; for (auto kv : true_cases) { EXPECT_TRUE(kv.first.couldBe(kv.second)) << show(kv.first) << " couldBe " << show(kv.second) << " should be true"; } for (auto kv : false_cases) { EXPECT_TRUE(!kv.first.couldBe(kv.second)) << show(kv.first) << " couldBe " << show(kv.second) << " should be false"; } for (auto kv : boost::join(true_cases, false_cases)) { EXPECT_EQ(kv.first.couldBe(kv.second), kv.second.couldBe(kv.first)) << show(kv.first) << " couldBe " << show(kv.second) << " wasn't reflexive"; } for (auto& x : optionals) { EXPECT_TRUE(x.couldBe(unopt(x))); EXPECT_TRUE(x.couldBe(TInitNull)); EXPECT_TRUE(!x.couldBe(TUninit)); for (auto& y : optionals) { EXPECT_TRUE(x.couldBe(y)); } } }
bool could_have_magic_bool_conversion(Type t) { if (!t.couldBe(TObj)) return false; if (t.strictSubtypeOf(TObj)) { return has_magic_bool_conversion(dobj_of(t).cls); } if (is_opt(t) && unopt(t).strictSubtypeOf(TObj)) { return has_magic_bool_conversion(dobj_of(t).cls); } return true; }
TEST(Type, Option) { EXPECT_TRUE(TTrue.subtypeOf(TOptTrue)); EXPECT_TRUE(TInitNull.subtypeOf(TOptTrue)); EXPECT_TRUE(!TUninit.subtypeOf(TOptTrue)); EXPECT_TRUE(TFalse.subtypeOf(TOptFalse)); EXPECT_TRUE(TInitNull.subtypeOf(TOptFalse)); EXPECT_TRUE(!TUninit.subtypeOf(TOptFalse)); EXPECT_TRUE(TFalse.subtypeOf(TOptBool)); EXPECT_TRUE(TTrue.subtypeOf(TOptBool)); EXPECT_TRUE(TInitNull.subtypeOf(TOptBool)); EXPECT_TRUE(!TUninit.subtypeOf(TOptBool)); EXPECT_TRUE(ival(3).subtypeOf(TOptInt)); EXPECT_TRUE(TInt.subtypeOf(TOptInt)); EXPECT_TRUE(TInitNull.subtypeOf(TOptInt)); EXPECT_TRUE(!TUninit.subtypeOf(TOptInt)); EXPECT_TRUE(TDbl.subtypeOf(TOptDbl)); EXPECT_TRUE(TInitNull.subtypeOf(TOptDbl)); EXPECT_TRUE(!TUninit.subtypeOf(TOptDbl)); EXPECT_TRUE(dval(3.0).subtypeOf(TOptDbl)); EXPECT_TRUE(sval(s_test.get()).subtypeOf(TOptSStr)); EXPECT_TRUE(TSStr.subtypeOf(TOptSStr)); EXPECT_TRUE(TInitNull.subtypeOf(TOptSStr)); EXPECT_TRUE(!TUninit.subtypeOf(TOptSStr)); EXPECT_TRUE(!TStr.subtypeOf(TOptSStr)); EXPECT_TRUE(TStr.couldBe(TOptSStr)); EXPECT_TRUE(TCStr.subtypeOf(TOptStr)); EXPECT_TRUE(TCArr.subtypeOf(TOptArr)); EXPECT_TRUE(TStr.subtypeOf(TOptStr)); EXPECT_TRUE(TSStr.subtypeOf(TOptStr)); EXPECT_TRUE(sval(s_test.get()).subtypeOf(TOptStr)); EXPECT_TRUE(TInitNull.subtypeOf(TOptStr)); EXPECT_TRUE(!TUninit.subtypeOf(TOptStr)); EXPECT_TRUE(TSArr.subtypeOf(TOptSArr)); EXPECT_TRUE(!TArr.subtypeOf(TOptSArr)); EXPECT_TRUE(TInitNull.subtypeOf(TOptSArr)); EXPECT_TRUE(!TUninit.subtypeOf(TOptSArr)); EXPECT_TRUE(TArr.subtypeOf(TOptArr)); EXPECT_TRUE(TInitNull.subtypeOf(TOptArr)); EXPECT_TRUE(!TUninit.subtypeOf(TOptArr)); EXPECT_TRUE(TObj.subtypeOf(TOptObj)); EXPECT_TRUE(TInitNull.subtypeOf(TOptObj)); EXPECT_TRUE(!TUninit.subtypeOf(TOptObj)); EXPECT_TRUE(TRes.subtypeOf(TOptRes)); EXPECT_TRUE(TInitNull.subtypeOf(TOptRes)); EXPECT_TRUE(!TUninit.subtypeOf(TOptRes)); for (auto& t : optionals) EXPECT_EQ(t, opt(unopt(t))); for (auto& t : optionals) EXPECT_TRUE(is_opt(t)); for (auto& t : all) { auto const found = std::find(begin(optionals), end(optionals), t) != end(optionals); EXPECT_EQ(found, is_opt(t)); } EXPECT_TRUE(is_opt(opt(sval(s_test.get())))); EXPECT_TRUE(is_opt(opt(ival(2)))); EXPECT_TRUE(is_opt(opt(dval(2.0)))); EXPECT_FALSE(is_opt(sval(s_test.get()))); EXPECT_FALSE(is_opt(ival(2))); EXPECT_FALSE(is_opt(dval(2.0))); }
unit_t operator()(Ts&&... xs) { m_fun(unopt(std::forward<Ts>(xs))...); return unit; }
typename detail::get_callable_trait<F>::result_type operator()(Ts&&... xs) { return m_fun(unopt(std::forward<Ts>(xs))...); }