forked from boostorg/optional
Merge branch 'develop'
This commit is contained in:
@ -2,7 +2,7 @@
|
|||||||
[quickbook 1.4]
|
[quickbook 1.4]
|
||||||
[authors [Cacciola Carballal, Fernando Luis]]
|
[authors [Cacciola Carballal, Fernando Luis]]
|
||||||
[copyright 2003-2007 Fernando Luis Cacciola Carballal]
|
[copyright 2003-2007 Fernando Luis Cacciola Carballal]
|
||||||
[copyright 2014-2021 Andrzej Krzemieński]
|
[copyright 2014-2022 Andrzej Krzemieński]
|
||||||
[category miscellaneous]
|
[category miscellaneous]
|
||||||
[id optional]
|
[id optional]
|
||||||
[dirname optional]
|
[dirname optional]
|
||||||
|
@ -26,11 +26,11 @@ template <class CharType, class CharTrait, class T>
|
|||||||
template <class CharType, class CharTrait>
|
template <class CharType, class CharTrait>
|
||||||
std::basic_ostream<CharType, CharTrait>&
|
std::basic_ostream<CharType, CharTrait>&
|
||||||
operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t const&); ``[link reference_operator_ostream_none __GO_TO__]``
|
operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t const&); ``[link reference_operator_ostream_none __GO_TO__]``
|
||||||
|
|
||||||
template<class CharType, class CharTrait, class T>
|
template<class CharType, class CharTrait, class T>
|
||||||
std::basic_istream<CharType, CharTrait>&
|
std::basic_istream<CharType, CharTrait>&
|
||||||
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v); ``[link reference_operator_istream __GO_TO__]``
|
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v); ``[link reference_operator_istream __GO_TO__]``
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -43,8 +43,8 @@ template<class CharType, class CharTrait, class T>
|
|||||||
|
|
||||||
|
|
||||||
`template <class CharType, class CharTrait, class T>` [br]
|
`template <class CharType, class CharTrait, class T>` [br]
|
||||||
\u00A0\u00A0\u00A0\u00A0`std::basic_ostream<CharType, CharTrait>&` [br]
|
std::basic_ostream<CharType, CharTrait>&` [br]
|
||||||
\u00A0\u00A0\u00A0\u00A0`operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v);`
|
operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v);`
|
||||||
|
|
||||||
* [*Effect:] Outputs an implementation-defined string. The output contains the information about whether the optional object contains a value or not. If `v` contains a value, the output contains result of calling `out << *v`.
|
* [*Effect:] Outputs an implementation-defined string. The output contains the information about whether the optional object contains a value or not. If `v` contains a value, the output contains result of calling `out << *v`.
|
||||||
* [*Returns:] `out`.
|
* [*Returns:] `out`.
|
||||||
@ -53,8 +53,8 @@ __SPACE__
|
|||||||
[#reference_operator_ostream_none]
|
[#reference_operator_ostream_none]
|
||||||
|
|
||||||
`template <class CharType, class CharTrait, class T>` [br]
|
`template <class CharType, class CharTrait, class T>` [br]
|
||||||
\u00A0\u00A0\u00A0\u00A0`std::basic_ostream<CharType, CharTrait>&` [br]
|
std::basic_ostream<CharType, CharTrait>&` [br]
|
||||||
\u00A0\u00A0\u00A0\u00A0`operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t);`
|
operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t);`
|
||||||
|
|
||||||
* [*Effect:] Outputs an implementation-defined string.
|
* [*Effect:] Outputs an implementation-defined string.
|
||||||
* [*Returns:] `out`.
|
* [*Returns:] `out`.
|
||||||
@ -63,11 +63,11 @@ __SPACE__
|
|||||||
[#reference_operator_istream]
|
[#reference_operator_istream]
|
||||||
|
|
||||||
`template <class CharType, class CharTrait, class T>` [br]
|
`template <class CharType, class CharTrait, class T>` [br]
|
||||||
\u00A0\u00A0\u00A0\u00A0`std::basic_ostream<CharType, CharTrait>&` [br]
|
std::basic_ostream<CharType, CharTrait>&` [br]
|
||||||
\u00A0\u00A0\u00A0\u00A0`operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v);`
|
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v);`
|
||||||
|
|
||||||
* [*Requires:] `T` is __SGI_DEFAULT_CONSTRUCTIBLE__ and __MOVE_CONSTRUCTIBLE__.
|
* [*Requires:] `T` is __SGI_DEFAULT_CONSTRUCTIBLE__ and __MOVE_CONSTRUCTIBLE__.
|
||||||
* [*Effect:] Reads the value of optional object from `in`. If the string representation indicates that the optional object should contain a value, `v` contains a value and its contained value is obtained as if by default-constructing an object `o` of type `T` and then calling `in >> o`; otherwise `v` does not contain a value, and the previously contained value (if any) has been destroyed.
|
* [*Effect:] Reads the value of optional object from `in`. If the string representation indicates that the optional object should contain a value, `v` contains a value and its contained value is obtained as if by default-constructing an object `o` of type `T` and then calling `in >> o`; otherwise `v` does not contain a value, and the previously contained value (if any) has been destroyed.
|
||||||
* [*Returns:] `out`.
|
* [*Returns:] `out`.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@ -73,6 +73,16 @@
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct hash<boost::optional<T> > ; ``[link reference_std_hash_spec __GO_TO__]``
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct hash<boost::optional<T&> > ; ``[link reference_std_hash_spec __GO_TO__]``
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@ -1408,3 +1408,37 @@ assert (addressof(*opt0) == addressof(y));
|
|||||||
``
|
``
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
|
[section Detailed Semantics - std::hash Specializations]
|
||||||
|
|
||||||
|
__SPACE__
|
||||||
|
[#reference_std_hash_spec]
|
||||||
|
|
||||||
|
``
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct hash<boost::optional<T> > ;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct hash<boost::optional<T&> > ;
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
``
|
||||||
|
|
||||||
|
The specialization `hash<optional<T>>` is enabled if and only if
|
||||||
|
`hash<remove_const_t<T>>` is enabled. When enabled, for an object `o`
|
||||||
|
of type `optional<T>`, if `o.has_value() == true`, then `hash<optional<T>>()(o)`
|
||||||
|
evaluates to the same value as `hash<remove_const_t<T>>()(*o)`; otherwise it
|
||||||
|
evaluates to an unspecified value.
|
||||||
|
The member functions are not guaranteed to be `noexcept`.
|
||||||
|
|
||||||
|
[caution
|
||||||
|
You may get compiler errors when your program provides specializations for
|
||||||
|
`std::hash<boost::optional<T>>`. If this happens, define macro
|
||||||
|
`BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH` to suppress the specializations
|
||||||
|
of `std::hash` in this library.
|
||||||
|
]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[/
|
[/
|
||||||
Boost.Optional
|
Boost.Optional
|
||||||
|
|
||||||
Copyright (c) 2015 - 2021 Andrzej Krzemienski
|
Copyright (c) 2015 - 2022 Andrzej Krzemienski
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
(See accompanying file LICENSE_1_0.txt or copy at
|
(See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
[section:relnotes Release Notes]
|
[section:relnotes Release Notes]
|
||||||
|
|
||||||
|
[heading Boost Release 1.80]
|
||||||
|
|
||||||
|
* [*Breaking change:] Added specializations for `std::hash<boost::opitonal<T>>`. This fixes [@https://github.com/boostorg/optional/issues/55 issue #55]. You may get compiler errors when your program provides specializations for `std::hash<boost::optional<T>>`. If this happens, define macro `BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH` to suppress the specializations of `std::hash` in this library.
|
||||||
|
|
||||||
[heading Boost Release 1.79]
|
[heading Boost Release 1.79]
|
||||||
|
|
||||||
* Fixed [@https://github.com/boostorg/optional/issues/98 issue #98].
|
* Fixed [@https://github.com/boostorg/optional/issues/98 issue #98].
|
||||||
|
49
include/boost/optional/detail/optional_hash.hpp
Normal file
49
include/boost/optional/detail/optional_hash.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (C) 2022 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/libs/optional for documentation.
|
||||||
|
//
|
||||||
|
// You are welcome to contact the author at:
|
||||||
|
// akrzemi1@gmail.com
|
||||||
|
|
||||||
|
#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_HASH_AJK_20MAY2022_HPP
|
||||||
|
#define BOOST_OPTIONAL_DETAIL_OPTIONAL_HASH_AJK_20MAY2022_HPP
|
||||||
|
|
||||||
|
#include <boost/optional/optional_fwd.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct hash<boost::optional<T> >
|
||||||
|
{
|
||||||
|
typedef std::size_t result_type;
|
||||||
|
typedef boost::optional<T> argument_type;
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR result_type operator()(const argument_type& arg) const {
|
||||||
|
return arg ? std::hash<T>()(*arg) : result_type();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct hash<boost::optional<T&> >
|
||||||
|
{
|
||||||
|
typedef std::size_t result_type;
|
||||||
|
typedef boost::optional<T&> argument_type;
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR result_type operator()(const argument_type& arg) const {
|
||||||
|
return arg ? std::hash<T>()(*arg) : result_type();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
|
||||||
|
|
||||||
|
#endif // header guard
|
@ -65,6 +65,7 @@
|
|||||||
#include <boost/optional/detail/optional_config.hpp>
|
#include <boost/optional/detail/optional_config.hpp>
|
||||||
#include <boost/optional/detail/optional_factory_support.hpp>
|
#include <boost/optional/detail/optional_factory_support.hpp>
|
||||||
#include <boost/optional/detail/optional_aligned_storage.hpp>
|
#include <boost/optional/detail/optional_aligned_storage.hpp>
|
||||||
|
#include <boost/optional/detail/optional_hash.hpp>
|
||||||
|
|
||||||
namespace boost { namespace optional_detail {
|
namespace boost { namespace optional_detail {
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import testing ;
|
|||||||
[ run optional_test_empty_braces.cpp ]
|
[ run optional_test_empty_braces.cpp ]
|
||||||
[ run optional_test_make_optional.cpp ]
|
[ run optional_test_make_optional.cpp ]
|
||||||
[ run optional_test_flat_map.cpp ]
|
[ run optional_test_flat_map.cpp ]
|
||||||
|
[ run optional_test_hash.cpp ]
|
||||||
[ run optional_test_map.cpp ]
|
[ run optional_test_map.cpp ]
|
||||||
[ run optional_test_tie.cpp ]
|
[ run optional_test_tie.cpp ]
|
||||||
[ run optional_test_ref_assign_portable_minimum.cpp ]
|
[ run optional_test_ref_assign_portable_minimum.cpp ]
|
||||||
|
64
test/optional_test_hash.cpp
Normal file
64
test/optional_test_hash.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (C) 2014 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"
|
||||||
|
#include "boost/config.hpp"
|
||||||
|
#include "boost/core/lightweight_test.hpp"
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH)
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
void test_unordered_map()
|
||||||
|
{
|
||||||
|
std::unordered_set<boost::optional<int> > set;
|
||||||
|
set.insert(boost::optional<int>(1));
|
||||||
|
set.insert(boost::optional<int>(1));
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_TEST(set.size() == 1u);
|
||||||
|
BOOST_TEST(set.find(boost::optional<int>(1)) != set.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void test_unordered_map()
|
||||||
|
{}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
|
||||||
|
|
||||||
|
void tets_hash()
|
||||||
|
{
|
||||||
|
std::hash<boost::optional<int> > hash_int;
|
||||||
|
boost::optional<int> oN;
|
||||||
|
boost::optional<int> o1(1);
|
||||||
|
|
||||||
|
BOOST_TEST(hash_int(oN) == hash_int(oN));
|
||||||
|
BOOST_TEST(hash_int(o1) == hash_int(o1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void tets_hash()
|
||||||
|
{}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_unordered_map();
|
||||||
|
tets_hash();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user