mirror of
https://github.com/boostorg/optional.git
synced 2025-07-14 12:56:35 +02:00
161 lines
3.4 KiB
C++
161 lines
3.4 KiB
C++
![]() |
// Copyright (C) 2018 Andrzej Krzemienski.
|
||
|
//
|
||
|
// Use, modification, and distribution is subject to the Boost Software
|
||
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||
|
//
|
||
|
// See http://www.boost.org/lib/optional for documentation.
|
||
|
//
|
||
|
// You are welcome to contact the author at:
|
||
|
// akrzemi1@gmail.com
|
||
|
|
||
|
#include "boost/optional/optional.hpp"
|
||
|
|
||
|
#ifdef __BORLANDC__
|
||
|
#pragma hdrstop
|
||
|
#endif
|
||
|
|
||
|
#include "boost/core/ignore_unused.hpp"
|
||
|
#include "boost/core/is_same.hpp"
|
||
|
#include "boost/core/lightweight_test.hpp"
|
||
|
#include "boost/core/lightweight_test_trait.hpp"
|
||
|
|
||
|
|
||
|
using boost::optional;
|
||
|
using boost::make_optional;
|
||
|
using boost::core::is_same;
|
||
|
|
||
|
template <typename Expected, typename Deduced>
|
||
|
void verify_type(Deduced)
|
||
|
{
|
||
|
BOOST_TEST_TRAIT_TRUE(( is_same<Expected, Deduced> ));
|
||
|
}
|
||
|
|
||
|
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||
|
struct MoveOnly
|
||
|
{
|
||
|
int value;
|
||
|
explicit MoveOnly(int i) : value(i) {}
|
||
|
MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; }
|
||
|
MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; }
|
||
|
|
||
|
private:
|
||
|
MoveOnly(MoveOnly const&);
|
||
|
void operator=(MoveOnly const&);
|
||
|
};
|
||
|
|
||
|
MoveOnly makeMoveOnly(int i)
|
||
|
{
|
||
|
return MoveOnly(i);
|
||
|
}
|
||
|
|
||
|
optional<MoveOnly> makeOptMoveOnly(int i)
|
||
|
{
|
||
|
return optional<MoveOnly>(MoveOnly(i));
|
||
|
}
|
||
|
|
||
|
int get_val(MoveOnly m)
|
||
|
{
|
||
|
return m.value;
|
||
|
}
|
||
|
|
||
|
void test_map_move_only()
|
||
|
{
|
||
|
optional<MoveOnly> om (makeMoveOnly(7)), om2 (makeMoveOnly(8));
|
||
|
verify_type<optional<int>>(boost::move(om).map(get_val));
|
||
|
optional<int> oi = boost::move(om2).map(get_val);
|
||
|
BOOST_TEST(bool(oi));
|
||
|
BOOST_TEST_EQ(8, *oi);
|
||
|
|
||
|
optional<int> oj = makeOptMoveOnly(4).map(get_val);
|
||
|
BOOST_TEST(bool(oj));
|
||
|
BOOST_TEST_EQ(4, *oj);
|
||
|
|
||
|
optional<MoveOnly> o_;
|
||
|
optional<int> oi_ = boost::move(o_).map(get_val);
|
||
|
BOOST_TEST(!oi_);
|
||
|
}
|
||
|
|
||
|
#endif // no rvalue refs
|
||
|
|
||
|
struct Int
|
||
|
{
|
||
|
int i;
|
||
|
explicit Int(int i_) : i(i_) {}
|
||
|
};
|
||
|
|
||
|
struct convert_t
|
||
|
{
|
||
|
Int operator()(int i) { return Int(i); }
|
||
|
};
|
||
|
|
||
|
int& get_int_ref(Int& i)
|
||
|
{
|
||
|
return i.i;
|
||
|
}
|
||
|
|
||
|
struct get_ref
|
||
|
{
|
||
|
int& operator()(int& i) { return i; }
|
||
|
};
|
||
|
|
||
|
void test_map()
|
||
|
{
|
||
|
optional<int> oi (1);
|
||
|
verify_type<optional<Int>>(oi.map(convert_t()));
|
||
|
optional<Int> oI = oi.map(convert_t());
|
||
|
BOOST_TEST(bool(oI));
|
||
|
BOOST_TEST_EQ(1, oI->i);
|
||
|
}
|
||
|
|
||
|
void test_map_with_lambda()
|
||
|
{
|
||
|
#ifndef BOOST_NO_CXX11_LAMBDAS
|
||
|
optional<int> oi (1), oj(2);
|
||
|
verify_type<optional<bool>>(oi.map([](int i){ return i == 1; }));
|
||
|
optional<bool> ob = oi.map([](int i){ return i == 1; });
|
||
|
optional<bool> oc = oj.map([](int i){ return i == 1; });
|
||
|
BOOST_TEST(bool(ob));
|
||
|
BOOST_TEST_EQ(true, *ob);
|
||
|
BOOST_TEST(bool(oc));
|
||
|
BOOST_TEST_EQ(false, *oc);
|
||
|
#endif // lambdas
|
||
|
}
|
||
|
|
||
|
void test_map_to_ref()
|
||
|
{
|
||
|
optional<int> oi (2);
|
||
|
verify_type<optional<int&>>(oi.map(get_ref()));
|
||
|
optional<int&> ori = oi.map(get_ref());
|
||
|
BOOST_TEST(bool(ori));
|
||
|
*ori = 3;
|
||
|
BOOST_TEST(bool(oi));
|
||
|
BOOST_TEST_EQ(3, *oi);
|
||
|
BOOST_TEST_EQ(3, *ori);
|
||
|
}
|
||
|
|
||
|
void test_map_optional_ref()
|
||
|
{
|
||
|
Int I (5);
|
||
|
optional<Int&> ori (I);
|
||
|
verify_type<optional<int&>>(ori.map(get_int_ref));
|
||
|
optional<int&> orii = ori.map(get_int_ref);
|
||
|
BOOST_TEST(bool(orii));
|
||
|
BOOST_TEST_EQ(5, *orii);
|
||
|
*orii = 6;
|
||
|
BOOST_TEST_EQ(6, I.i);
|
||
|
}
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||
|
test_map_move_only();
|
||
|
#endif
|
||
|
test_map_with_lambda();
|
||
|
test_map();
|
||
|
test_map_to_ref();
|
||
|
test_map_optional_ref();
|
||
|
|
||
|
return boost::report_errors();
|
||
|
}
|