From 0be868143d53bd582a6ade485b58ed6bb6f38518 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sat, 11 Dec 2021 01:11:17 -0500 Subject: [PATCH] Add identity function object --- identity.html | 45 ++++++++++++++++ include/boost/functional/identity.hpp | 41 +++++++++++++++ index.html | 6 +++ test/Jamfile.v2 | 2 + test/identity_rvalue_test.cpp | 75 +++++++++++++++++++++++++++ test/identity_test.cpp | 72 +++++++++++++++++++++++++ 6 files changed, 241 insertions(+) create mode 100644 identity.html create mode 100644 include/boost/functional/identity.hpp create mode 100644 test/identity_rvalue_test.cpp create mode 100644 test/identity_test.cpp diff --git a/identity.html b/identity.html new file mode 100644 index 0000000..ee5b208 --- /dev/null +++ b/identity.html @@ -0,0 +1,45 @@ + + + + +Boost Function Object Adapter Library + + +

Identity

+

The header +<boost/functional/identity.hpp> provides the function object +boost::identity whose operator() returns its +argument. It is an implementation of C++20's std::identity +that supports C++03 and above.

+

Example

+

It is commonly used as the default projection in constrained algorithms.

+
+template<class Range, class Projection = boost::identity>
+void print(Range&& range, Projection projection = {});
+
+

Reference

+
+namespace boost {
+
+struct identity {
+    using is_transparent = unspecified;
+
+    template<class T>
+    T&& operator()(T&& value) const noexcept;
+};
+
+} // boost
+
+

Operators

+
+
template<class T> +T&& operator()(T&& value) const noexcept;
+
Returns std::forward<T>(value)
+
+
+

Copyright 2021 Glen Joseph Fernandes.

+

Distributed under the +Boost Software License, +Version 1.0.

+ + diff --git a/include/boost/functional/identity.hpp b/include/boost/functional/identity.hpp new file mode 100644 index 0000000..a4929a9 --- /dev/null +++ b/include/boost/functional/identity.hpp @@ -0,0 +1,41 @@ +/* +Copyright 2021 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_FUNCTIONAL_IDENTITY_HPP +#define BOOST_FUNCTIONAL_IDENTITY_HPP + +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#endif + +namespace boost { + +struct identity { + typedef void is_transparent; + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + template + BOOST_CONSTEXPR T&& operator()(T&& value) const BOOST_NOEXCEPT { + return std::forward(value); + } +#else + template + BOOST_CONSTEXPR const T& operator()(const T& value) const BOOST_NOEXCEPT { + return value; + } + + template + BOOST_CONSTEXPR T& operator()(T& value) const BOOST_NOEXCEPT { + return value; + } +#endif +}; + +} // boost + +#endif diff --git a/index.html b/index.html index f4315a0..6511667 100644 --- a/index.html +++ b/index.html @@ -121,6 +121,12 @@ Based on section 20.3.8 of the standard. + + + Identity + identity + [func.identity] in ISO/IEC 14882:2020 +

Usage

diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dbe379c..71de379 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -6,4 +6,6 @@ import testing ; test-suite functional : [ run function_test.cpp ] + [ run identity_test.cpp ] + [ run identity_rvalue_test.cpp ] ; diff --git a/test/identity_rvalue_test.cpp b/test/identity_rvalue_test.cpp new file mode 100644 index 0000000..d4af64d --- /dev/null +++ b/test/identity_rvalue_test.cpp @@ -0,0 +1,75 @@ +/* +Copyright 2021 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#include +#include +#include +#include +#include + +enum kind { + rvalue, + crvalue, + other +}; + +kind result(std::string&&) +{ + return rvalue; +} + +kind result(const std::string&&) +{ + return crvalue; +} + +template +kind result(T&&) +{ + return other; +} + +void simple_test() +{ + typedef std::string string; + BOOST_TEST(boost::identity()(string("a")) == string("a")); + BOOST_TEST(result(boost::identity()(string("a"))) == rvalue); + typedef const std::string cstring; + BOOST_TEST(boost::identity()(cstring("a")) == cstring("a")); + BOOST_TEST(result(boost::identity()(cstring("a"))) == crvalue); +} + +void algorithm_test() +{ + std::vector v1; + v1.push_back(std::string("a")); + v1.push_back(std::string("b")); + v1.push_back(std::string("c")); + std::vector v2(v1); + std::vector v3; + std::transform(std::make_move_iterator(v2.begin()), + std::make_move_iterator(v2.end()), + std::back_inserter(v3), + boost::identity()); + BOOST_TEST(v3 == v1); +} + +int main() +{ + simple_test(); + algorithm_test(); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/test/identity_test.cpp b/test/identity_test.cpp new file mode 100644 index 0000000..81dc239 --- /dev/null +++ b/test/identity_test.cpp @@ -0,0 +1,72 @@ +/* +Copyright 2021 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include +#include +#include +#include + +enum kind { + ref, + cref, + other +}; + +kind result(std::string&) +{ + return ref; +} + +kind result(const std::string&) +{ + return cref; +} + +template +kind result(T&) +{ + return other; +} + +template +kind result(const T&) +{ + return other; +} + +void simple_test() +{ + std::string s1("a"); + BOOST_TEST(boost::identity()(s1) == s1); + BOOST_TEST(&boost::identity()(s1) == &s1); + BOOST_TEST(result(boost::identity()(s1)) == ref); + const std::string s2("a"); + BOOST_TEST(boost::identity()(s2) == s2); + BOOST_TEST(&boost::identity()(s2) == &s2); + BOOST_TEST(result(boost::identity()(s2)) == cref); +} + +void algorithm_test() +{ + std::vector v1; + v1.push_back(std::string("a")); + v1.push_back(std::string("b")); + v1.push_back(std::string("c")); + std::vector v2; + std::transform(v1.begin(), v1.end(), std::back_inserter(v2), + boost::identity()); + BOOST_TEST(v2 == v1); +} + +int main() +{ + simple_test(); + algorithm_test(); + return boost::report_errors(); +}