/* * Copyright (c) 2017 Jaroslav Jindrak * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBCPP_UTILITY #define LIBCPP_UTILITY #include namespace std { /** * 20.2.1, operators: */ namespace rel_ops { template bool operator!=(const T& lhs, const T& rhs) { return !(lhs == rhs); } template bool operator>(const T& lhs, const T& rhs) { return (rhs < lhs); } template bool operator<=(const T& lhs, const T& rhs) { return !(rhs < lhs); } template bool operator>=(const T& lhs, const T& rhs) { return !(lhs < rhs); } } /** * 20.2.4, forward/move helpers: */ template inline constexpr T&& forward(remove_reference_t& t) noexcept { return static_cast(t); } template inline constexpr T&& forward(remove_reference_t&& t) noexcept { // TODO: check if t is lvalue reference, if it is, the program // is ill-formed according to the standard return static_cast(t); } template inline constexpr remove_reference_t&& move(T&& t) noexcept { return static_cast&&>(t); } /** * 20.2.2, swap: */ template void swap(T& x, T& y) /* noexcept(is_nothrow_move_constructible::value && */ /* is_nothrow_move_assignable::value) */ { T tmp{move(x)}; x = move(y); y = move(tmp); } template void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))) { // TODO: Use swap_ranges(a, a + N, b); when implemented. } /** * 20.2.3, exchange: */ template T exchange(T& obj, U&& new_val) { T old_val = move(obj); obj = forward(new_val); return old_val; } /** * 20.2.5, function template declval: * Note: This function only needs declaration, not * implementation. */ template add_rvalue_reference_t declval() noexcept; /** * 20.3, pairs: */ struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; template struct pair { using first_type = T1; using second_type = T2; T1 first; T2 second; pair(const pair&) = default; pair(pair&&) = default; constexpr pair() : first{}, second{} { /* DUMMY BODY */ } constexpr pair(const T1& x, const T2& y) : first{x}, second{y} { /* DUMMY BODY */ } template constexpr pair(U&& x, V&& y) : first(x), second(y) { /* DUMMY BODY */ } template constexpr pair(const pair& other) : first(other.first), second(other.second) { /* DUMMY BODY */ } template constexpr pair(pair&& other) : first(forward(other.first)), second(forward(other.second)) { /* DUMMY BODY */ } /* TODO: need tuple, piecewise_construct_t template pair(piecewise_construct_t, tuple first_args, tuple second_args) { // TODO: } */ pair& operator=(const pair& other) { first = other.first; second = other.second; return *this; } template pair& operator=(const pair& other) { first = other.first; second = other.second; return *this; } pair& operator=(pair&& other) noexcept { first = forward(other.first); second = forward(other.second); return *this; } }; } #endif