diff --git a/include/boost/optional/detail/optional_hash.hpp b/include/boost/optional/detail/optional_hash.hpp new file mode 100644 index 0000000..fad5ce0 --- /dev/null +++ b/include/boost/optional/detail/optional_hash.hpp @@ -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 +#include + +#if !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +#include + +namespace std +{ + template + struct hash > + { + typedef typename hash::result_type result_type; + typedef boost::optional argument_type; + + BOOST_CONSTEXPR result_type operator()(const argument_type& arg) const { + return arg ? std::hash()(*arg) : result_type(); + } + }; + + template + struct hash > + { + typedef typename hash::result_type result_type; + typedef boost::optional argument_type; + + BOOST_CONSTEXPR result_type operator()(const argument_type& arg) const { + return arg ? std::hash()(*arg) : result_type(); + } + }; +} + +#endif // !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +#endif // header guard diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index a04ac86..4134a7e 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -65,6 +65,7 @@ #include #include #include +#include namespace boost { namespace optional_detail { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 477f4df..c965863 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -26,6 +26,7 @@ import testing ; [ run optional_test_empty_braces.cpp ] [ run optional_test_make_optional.cpp ] [ run optional_test_flat_map.cpp ] + [ run optional_test_hash.cpp ] [ run optional_test_map.cpp ] [ run optional_test_tie.cpp ] [ run optional_test_ref_assign_portable_minimum.cpp ] diff --git a/test/optional_test_hash.cpp b/test/optional_test_hash.cpp new file mode 100644 index 0000000..8a631a2 --- /dev/null +++ b/test/optional_test_hash.cpp @@ -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 + +void test_unordered_map() +{ + std::unordered_set > set; + set.insert(boost::optional(1)); + set.insert(boost::optional(1)); + + + BOOST_TEST(set.size() == 1u); + BOOST_TEST(set.find(boost::optional(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 > hash_int; + boost::optional oN; + boost::optional 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(); +}