forked from boostorg/core
Implement empty_value
This commit is contained in:
113
include/boost/core/empty_value.hpp
Normal file
113
include/boost/core/empty_value.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Glen Joseph Fernandes
|
||||||
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
(http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_CORE_EMPTY_VALUE_HPP
|
||||||
|
#define BOOST_CORE_EMPTY_VALUE_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#include <utility>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700)
|
||||||
|
#define BOOST_DETAIL_EMPTY_VALUE_BASE
|
||||||
|
#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800)
|
||||||
|
#define BOOST_DETAIL_EMPTY_VALUE_BASE
|
||||||
|
#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800)
|
||||||
|
#define BOOST_DETAIL_EMPTY_VALUE_BASE
|
||||||
|
#elif defined(BOOST_CLANG) && !defined(__CUDACC__)
|
||||||
|
#if __has_feature(is_empty) && __has_feature(is_final)
|
||||||
|
#define BOOST_DETAIL_EMPTY_VALUE_BASE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct use_empty_value_base {
|
||||||
|
enum {
|
||||||
|
#if defined(BOOST_DETAIL_EMPTY_VALUE_BASE)
|
||||||
|
value = __is_empty(T) && !__is_final(T)
|
||||||
|
#else
|
||||||
|
value = false
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct empty_init_t { };
|
||||||
|
|
||||||
|
template<class T, unsigned = 0, bool = use_empty_value_base<T>::value>
|
||||||
|
class empty_value {
|
||||||
|
public:
|
||||||
|
empty_value()
|
||||||
|
: value_() { }
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class... Args>
|
||||||
|
empty_value(empty_init_t, Args&&... args)
|
||||||
|
: value_(std::forward<Args>(args)...) { }
|
||||||
|
#else
|
||||||
|
template<class U>
|
||||||
|
empty_value(empty_init_t, U&& value)
|
||||||
|
: value_(std::forward<U>(value)) { }
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template<class U>
|
||||||
|
empty_value(empty_init_t, const U& value)
|
||||||
|
: value_(value) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const T& get() const BOOST_NOEXCEPT {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& get() BOOST_NOEXCEPT {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
template<class T, unsigned N>
|
||||||
|
class empty_value<T, N, true>
|
||||||
|
: T {
|
||||||
|
public:
|
||||||
|
empty_value()
|
||||||
|
: T() { }
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<class... Args>
|
||||||
|
empty_value(empty_init_t, Args&&... args)
|
||||||
|
: T(std::forward<Args>(args)...) { }
|
||||||
|
#else
|
||||||
|
template<class U>
|
||||||
|
empty_value(empty_init_t, U&& value)
|
||||||
|
: T(std::forward<U>(value)) { }
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template<class U>
|
||||||
|
empty_value(empty_init_t, const U& value)
|
||||||
|
: T(value) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const T& get() const BOOST_NOEXCEPT {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& get() BOOST_NOEXCEPT {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} /* boost */
|
||||||
|
|
||||||
|
#endif
|
@ -123,5 +123,8 @@ run to_address_test.cpp ;
|
|||||||
run exchange_test.cpp ;
|
run exchange_test.cpp ;
|
||||||
run exchange_move_test.cpp ;
|
run exchange_move_test.cpp ;
|
||||||
|
|
||||||
|
run empty_value_test.cpp ;
|
||||||
|
run empty_value_size_test.cpp ;
|
||||||
|
|
||||||
use-project /boost/core/swap : ./swap ;
|
use-project /boost/core/swap : ./swap ;
|
||||||
build-project ./swap ;
|
build-project ./swap ;
|
||||||
|
60
test/empty_value_size_test.cpp
Normal file
60
test/empty_value_size_test.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Glen Joseph Fernandes
|
||||||
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
(http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
#include <boost/core/empty_value.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
struct T1 { };
|
||||||
|
|
||||||
|
struct S1
|
||||||
|
: boost::empty_value<T1, 0, true> { };
|
||||||
|
|
||||||
|
struct T2 {
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2
|
||||||
|
: boost::empty_value<T1, 0, true>
|
||||||
|
, boost::empty_value<T2, 1, true> { };
|
||||||
|
|
||||||
|
struct S3
|
||||||
|
: boost::empty_value<T1, 0, false>
|
||||||
|
, boost::empty_value<T2, 1, true> { };
|
||||||
|
|
||||||
|
struct T3 { };
|
||||||
|
|
||||||
|
struct S4
|
||||||
|
: boost::empty_value<T1, 0, true>
|
||||||
|
, boost::empty_value<T3, 1, true> { };
|
||||||
|
|
||||||
|
struct S5
|
||||||
|
: boost::empty_value<T1, 0, false>
|
||||||
|
, boost::empty_value<T3, 1, false> { };
|
||||||
|
|
||||||
|
struct S6
|
||||||
|
: boost::empty_value<T1, 0, true>
|
||||||
|
, boost::empty_value<T2, 1, true>
|
||||||
|
, boost::empty_value<T3, 2, true> { };
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST(sizeof(S1) == sizeof(T1));
|
||||||
|
BOOST_TEST(sizeof(S2) == sizeof(T2));
|
||||||
|
BOOST_TEST(sizeof(S3) > sizeof(T2));
|
||||||
|
BOOST_TEST(sizeof(S4) == sizeof(T1));
|
||||||
|
BOOST_TEST(sizeof(S5) > sizeof(T1));
|
||||||
|
BOOST_TEST(sizeof(S6) == sizeof(T2));
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
76
test/empty_value_test.cpp
Normal file
76
test/empty_value_test.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Glen Joseph Fernandes
|
||||||
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
(http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/core/empty_value.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
struct empty {
|
||||||
|
operator bool() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
operator bool() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
type()
|
||||||
|
: value_(false) { }
|
||||||
|
explicit type(bool value)
|
||||||
|
: value_(value) { }
|
||||||
|
operator bool() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_bool()
|
||||||
|
{
|
||||||
|
const boost::empty_value<bool> v1(boost::empty_init_t(), true);
|
||||||
|
BOOST_TEST(v1.get());
|
||||||
|
boost::empty_value<bool> v2;
|
||||||
|
BOOST_TEST(!v2.get());
|
||||||
|
v2 = v1;
|
||||||
|
BOOST_TEST(v2.get());
|
||||||
|
v2.get() = false;
|
||||||
|
BOOST_TEST(!v2.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_empty()
|
||||||
|
{
|
||||||
|
empty e;
|
||||||
|
const boost::empty_value<empty> v1(boost::empty_init_t(), e);
|
||||||
|
BOOST_TEST(!v1.get());
|
||||||
|
boost::empty_value<empty> v2;
|
||||||
|
BOOST_TEST(v2.get());
|
||||||
|
v2 = v1;
|
||||||
|
BOOST_TEST(v2.get());
|
||||||
|
v2.get() = empty();
|
||||||
|
BOOST_TEST(v2.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_type()
|
||||||
|
{
|
||||||
|
const boost::empty_value<type> v1(boost::empty_init_t(), true);
|
||||||
|
BOOST_TEST(v1.get());
|
||||||
|
boost::empty_value<type> v2;
|
||||||
|
BOOST_TEST(!v2.get());
|
||||||
|
v2 = v1;
|
||||||
|
BOOST_TEST(v2.get());
|
||||||
|
v2.get() = type();
|
||||||
|
BOOST_TEST(!v2.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_bool();
|
||||||
|
test_empty();
|
||||||
|
test_type();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user