From ae77da19e1e45ab20b69b03ec41101cf197aa84a Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 22 Jul 2014 09:33:13 +0900 Subject: [PATCH] add shrink_to_fit, unmove --- sprout/assert.hpp | 6 +- sprout/complex/complex.hpp | 14 +++- sprout/container/container_range_traits.hpp | 1 + sprout/container/functions.hpp | 1 + sprout/container/shrink_to_fit.hpp | 89 +++++++++++++++++++++ sprout/optional/io.hpp | 4 +- sprout/utility/operation.hpp | 1 + sprout/utility/unmove.hpp | 22 +++++ testspr/assert.hpp | 4 +- testspr/iterator.hpp | 18 ++--- testspr/print.hpp | 61 +++++++++----- testspr/typeinfo.hpp | 16 ++-- 12 files changed, 192 insertions(+), 45 deletions(-) create mode 100644 sprout/container/shrink_to_fit.hpp create mode 100644 sprout/utility/unmove.hpp diff --git a/sprout/assert.hpp b/sprout/assert.hpp index ebe69a1e..cbea0e02 100644 --- a/sprout/assert.hpp +++ b/sprout/assert.hpp @@ -117,7 +117,7 @@ namespace sprout { namespace sprout { namespace detail { - inline bool + inline SPROUT_NON_CONSTEXPR bool assertion_failed_msg(char const* formatted, char const* msg) { return (std::cerr << formatted << ": " << msg << std::endl), std::abort(), false; } @@ -184,7 +184,7 @@ namespace sprout { namespace sprout { namespace detail { - inline bool + inline SPROUT_NON_CONSTEXPR bool assertion_failed(bool cond, char const* formatted, char const* expr, char const* function, char const* file, long line) { return cond ? true : ((void)sprout::assertion_failed(sprout::assertion_info(expr, function, file, line)), false) @@ -210,7 +210,7 @@ namespace sprout { namespace sprout { namespace detail { - inline bool + inline SPROUT_NON_CONSTEXPR bool assertion_failed(char const* formatted) { return (std::cerr << formatted << std::endl), std::abort(), false; } diff --git a/sprout/complex/complex.hpp b/sprout/complex/complex.hpp index b00cd845..0d3edd1f 100644 --- a/sprout/complex/complex.hpp +++ b/sprout/complex/complex.hpp @@ -8,6 +8,7 @@ #ifndef SPROUT_COMPLEX_COMPLEX_HPP #define SPROUT_COMPLEX_COMPLEX_HPP +#include #include #include @@ -50,8 +51,12 @@ namespace sprout { : elems_{{re, im}} {} SPROUT_CXX14_CONSTEXPR complex(complex const&) = default; - template - SPROUT_CONSTEXPR complex(complex const& other) SPROUT_NOEXCEPT + template + SPROUT_CONSTEXPR complex(complex const& other) SPROUT_NOEXCEPT + : elems_{{other.real(), other.imag()}} + {} + template + SPROUT_CONSTEXPR complex(std::complex const& other) SPROUT_NOEXCEPT : elems_{{other.real(), other.imag()}} {} SPROUT_CONSTEXPR T const& real() const SPROUT_NOEXCEPT { @@ -218,6 +223,11 @@ namespace sprout { SPROUT_CONSTEXPR const_pointer c_array() const SPROUT_NOEXCEPT { return elems_.c_array(); } + + template + SPROUT_EXPLICIT_CONVERSION SPROUT_CONSTEXPR operator std::complex() const SPROUT_NOEXCEPT { + return std::complex(real(), imag()); + } }; template SPROUT_CONSTEXPR_OR_CONST typename sprout::complex::size_type sprout::complex::static_size; diff --git a/sprout/container/container_range_traits.hpp b/sprout/container/container_range_traits.hpp index 96511ef5..72749063 100644 --- a/sprout/container/container_range_traits.hpp +++ b/sprout/container/container_range_traits.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/container/functions.hpp b/sprout/container/functions.hpp index 5c7fc4cf..2709ed96 100644 --- a/sprout/container/functions.hpp +++ b/sprout/container/functions.hpp @@ -14,5 +14,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_CONTAINER_FUNCTIONS_HPP diff --git a/sprout/container/shrink_to_fit.hpp b/sprout/container/shrink_to_fit.hpp new file mode 100644 index 00000000..9adacb84 --- /dev/null +++ b/sprout/container/shrink_to_fit.hpp @@ -0,0 +1,89 @@ +/*============================================================================= + Copyright (c) 2011-2014 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under 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) +=============================================================================*/ +#ifndef SPROUT_CONTAINER_SHRINK_TO_FIT_HPP +#define SPROUT_CONTAINER_SHRINK_TO_FIT_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout_adl { + sprout::not_found_via_adl container_shrink_to_fit(...); +} // namespace sprout_adl + +namespace sprout { + namespace detail { + template + struct has_mem_shrink_to_fit_test { + public: + template< + typename U = T, + typename = typename sprout::identity().shrink_to_fit())>::type + > + static sprout::true_type test(int); + static sprout::false_type test(...); + }; +#if defined(_MSC_VER) + template::test(0))>::type> + struct has_mem_shrink_to_fit + : public Base_ + {}; +#else + template + struct has_mem_shrink_to_fit + : public sprout::identity::test(0))>::type + {}; +#endif + + template + inline SPROUT_CXX14_CONSTEXPR typename std::enable_if< + sprout::detail::has_mem_shrink_to_fit::value + >::type + container_shrink_to_fit_default(Container&& cont) { + return SPROUT_FORWARD(Container, cont).shrink_to_fit(); + } + template + inline SPROUT_CXX14_CONSTEXPR typename std::enable_if< + !sprout::detail::has_mem_shrink_to_fit::value + >::type + container_shrink_to_fit_default(Container&&) {} + } // namespace detail + + namespace container_detail { + template + inline SPROUT_CXX14_CONSTEXPR void + container_shrink_to_fit(Container&& cont) { + return sprout::detail::container_shrink_to_fit_default(SPROUT_FORWARD(Container, cont)); + } + } // namespace container_detail + + // + // shrink_to_fit + // + // effect: + // ADL callable container_shrink_to_fit(cont) -> container_shrink_to_fit(cont) + // [default] + // callable cont.shrink_to_fit() -> cont.shrink_to_fit() + // otherwise -> no effects + // + template + inline SPROUT_CXX14_CONSTEXPR void + shrink_to_fit(Container&& cont) { + using sprout::container_detail::container_shrink_to_fit; + using sprout_adl::container_shrink_to_fit; + return container_shrink_to_fit(SPROUT_FORWARD(Container, cont)); + } +} // namespace sprout + +#include + +#endif // #ifndef SPROUT_CONTAINER_SHRINK_TO_FIT_HPP diff --git a/sprout/optional/io.hpp b/sprout/optional/io.hpp index f1d0c6a2..5323cf22 100644 --- a/sprout/optional/io.hpp +++ b/sprout/optional/io.hpp @@ -19,7 +19,7 @@ namespace sprout { // operator>> // template - inline std::basic_istream& + inline SPROUT_NON_CONSTEXPR std::basic_istream& operator>>(std::basic_istream& lhs, sprout::optional& rhs) { if (lhs.good()) { int d = lhs.get(); @@ -44,7 +44,7 @@ namespace sprout { // operator<< // template - inline std::basic_ostream& + inline SPROUT_NON_CONSTEXPR std::basic_ostream& operator<<(std::basic_ostream& lhs, sprout::optional const& rhs) { if (lhs.good()) { if (!rhs) { diff --git a/sprout/utility/operation.hpp b/sprout/utility/operation.hpp index e8bb7190..44261a3a 100644 --- a/sprout/utility/operation.hpp +++ b/sprout/utility/operation.hpp @@ -14,5 +14,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_UTILITY_OPERATION_HPP diff --git a/sprout/utility/unmove.hpp b/sprout/utility/unmove.hpp new file mode 100644 index 00000000..0fa20b8d --- /dev/null +++ b/sprout/utility/unmove.hpp @@ -0,0 +1,22 @@ +/*============================================================================= + Copyright (c) 2011-2014 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under 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) +=============================================================================*/ +#ifndef SPROUT_UTILITY_UNMOVE_HPP +#define SPROUT_UTILITY_UNMOVE_HPP + +#include +#include + +namespace sprout { + template + inline SPROUT_CONSTEXPR typename std::remove_reference::type& + unmove(T&& x) SPROUT_NOEXCEPT { + return static_cast::type&>(x); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_UNMOVE_HPP diff --git a/testspr/assert.hpp b/testspr/assert.hpp index d4d38ce8..4eb13e95 100644 --- a/testspr/assert.hpp +++ b/testspr/assert.hpp @@ -23,10 +23,10 @@ namespace testspr { : public std::runtime_error { public: - explicit assertion_failed(std::string const& msg) + explicit SPROUT_NON_CONSTEXPR assertion_failed(std::string const& msg) : std::runtime_error(msg) {} - explicit assertion_failed(char const* msg) + explicit SPROUT_NON_CONSTEXPR assertion_failed(char const* msg) : std::runtime_error(msg) {} }; diff --git a/testspr/iterator.hpp b/testspr/iterator.hpp index dd828ed2..43f5d9c4 100644 --- a/testspr/iterator.hpp +++ b/testspr/iterator.hpp @@ -54,7 +54,7 @@ namespace testspr { : current(it.base()) {} template::value>::type = sprout::enabler> - reduct_iterator& operator=(reduct_iterator const& it) { + SPROUT_CXX14_CONSTEXPR reduct_iterator& operator=(reduct_iterator const& it) { reduct_iterator temp(it); temp.swap(*this); return *this; @@ -68,20 +68,20 @@ namespace testspr { SPROUT_CONSTEXPR pointer operator->() const { return &*current; } - reduct_iterator& operator++() { + SPROUT_CXX14_CONSTEXPR reduct_iterator& operator++() { ++current; return *this; } - reduct_iterator operator++(int) { + SPROUT_CXX14_CONSTEXPR reduct_iterator operator++(int) { reduct_iterator result(*this); ++current; return result; } - reduct_iterator& operator--() { + SPROUT_CXX14_CONSTEXPR reduct_iterator& operator--() { --current; return *this; } - reduct_iterator operator--(int) { + SPROUT_CXX14_CONSTEXPR reduct_iterator operator--(int) { reduct_iterator temp(*this); --current; return temp; @@ -92,12 +92,12 @@ namespace testspr { SPROUT_CONSTEXPR reduct_iterator operator-(difference_type n) const { return reduct_iterator(current - n); } - reduct_iterator& operator+=(difference_type n) { + SPROUT_CXX14_CONSTEXPR reduct_iterator& operator+=(difference_type n) { reduct_iterator temp(current + n); temp.swap(*this); return *this; } - reduct_iterator& operator-=(difference_type n) { + SPROUT_CXX14_CONSTEXPR reduct_iterator& operator-=(difference_type n) { reduct_iterator temp(current - n); temp.swap(*this); return *this; @@ -111,7 +111,7 @@ namespace testspr { SPROUT_CONSTEXPR reduct_iterator prev() const { return reduct_iterator(sprout::prev(current)); } - void swap(reduct_iterator& other) + SPROUT_CXX14_CONSTEXPR void swap(reduct_iterator& other) SPROUT_NOEXCEPT_EXPR( SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) ) @@ -211,7 +211,7 @@ namespace testspr { // swap // template - inline void + inline SPROUT_CXX14_CONSTEXPR void swap(testspr::reduct_iterator& lhs, testspr::reduct_iterator& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { diff --git a/testspr/print.hpp b/testspr/print.hpp index b3204038..d8eb61a9 100644 --- a/testspr/print.hpp +++ b/testspr/print.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,9 +23,11 @@ namespace testspr { // // print // - void print() {} + inline SPROUT_NON_CONSTEXPR void + print() {} template - void print(Head const& head, Tail const&... tail) { + inline SPROUT_NON_CONSTEXPR void + print(Head const& head, Tail const&... tail) { std::cout << head; testspr::print(tail...); } @@ -32,11 +35,13 @@ namespace testspr { // // print_ln // - void print_ln() { + inline SPROUT_NON_CONSTEXPR void + print_ln() { std::cout << std::endl; } template - void print_ln(Args const&... args) { + inline SPROUT_NON_CONSTEXPR void + print_ln(Args const&... args) { sprout::detail::io::ios_all_saver saver(std::cout); testspr::print(args...); std::cout << std::endl; @@ -45,11 +50,13 @@ namespace testspr { // // print_tokens // - void print_tokens() { + inline SPROUT_NON_CONSTEXPR void + print_tokens() { testspr::print_ln(); } template - void print_tokens(Head const& head, Tail const&... tail) { + inline SPROUT_NON_CONSTEXPR void + print_tokens(Head const& head, Tail const&... tail) { sprout::detail::io::ios_all_saver saver(std::cout); testspr::print(head, ' '); testspr::print_tokens(tail...); @@ -58,11 +65,13 @@ namespace testspr { // // print_quotes // - void print_quotes() { + inline SPROUT_NON_CONSTEXPR void + print_quotes() { testspr::print_ln(); } template - void print_quotes(Head const& head, Tail const&... tail) { + inline SPROUT_NON_CONSTEXPR void + print_quotes(Head const& head, Tail const&... tail) { sprout::detail::io::ios_all_saver saver(std::cout); testspr::print('\"', head, "\" "); testspr::print_quotes(tail...); @@ -72,7 +81,8 @@ namespace testspr { // print_range // template - void print_range(InputIterator first, InputIterator last) { + inline SPROUT_NON_CONSTEXPR void + print_range(InputIterator first, InputIterator last) { sprout::detail::io::ios_all_saver saver(std::cout); for (; first != last; ++first) { std::cout << *first << ' '; @@ -80,7 +90,8 @@ namespace testspr { std::cout << std::endl; } template - void print_range(InputRange const& range) { + inline SPROUT_NON_CONSTEXPR void + print_range(InputRange const& range) { testspr::print_range(sprout::begin(range), sprout::end(range)); } @@ -88,7 +99,8 @@ namespace testspr { // print_bits // template - void print_bits(T const& t) { + inline SPROUT_NON_CONSTEXPR void + print_bits(T const& t) { testspr::print_ln(std::bitset(t).template to_string()); } @@ -96,7 +108,8 @@ namespace testspr { // print_typename // template - void print_typename() { + inline SPROUT_NON_CONSTEXPR void + print_typename() { testspr::print_ln(testspr::typename_of()); } @@ -104,14 +117,16 @@ namespace testspr { // print_type // template - void print_type() { + inline SPROUT_NON_CONSTEXPR void + print_type() { testspr::print_typename >(); } // // print_hl // - void print_hl() { + inline SPROUT_NON_CONSTEXPR void + print_hl() { testspr::print_ln("--------------------------------------------------------------------------------"); } @@ -125,40 +140,42 @@ namespace testspr { private: value_type m_; public: - manip_holder(value_type const& m) + SPROUT_CONSTEXPR manip_holder(value_type const& m) : m_(m) {} - value_type const& get() const { + SPROUT_CONSTEXPR value_type const& get() const { return m_; } }; template - std::basic_ostream& operator<<(std::basic_ostream& lhs, testspr::manip_holder const& rhs) { + inline SPROUT_NON_CONSTEXPR std::basic_ostream& + operator<<(std::basic_ostream& lhs, testspr::manip_holder const& rhs) { return lhs << rhs.get(); } template - std::basic_istream& operator>>(std::basic_istream& lhs, testspr::manip_holder const& rhs) { + inline SPROUT_NON_CONSTEXPR std::basic_istream& + operator>>(std::basic_istream& lhs, testspr::manip_holder const& rhs) { return lhs >> rhs.get(); } // // manip // template - T&& + inline SPROUT_NON_CONSTEXPR T&& manip(T&& t) { return std::forward(t); } template - testspr::manip_holder& (*)(std::basic_ostream&)> + inline SPROUT_NON_CONSTEXPR testspr::manip_holder& (*)(std::basic_ostream&)> manip(std::basic_ostream& (*pf)(std::basic_ostream&)) { return pf; } template - testspr::manip_holder& (*)(std::basic_ios&)> + inline SPROUT_NON_CONSTEXPR testspr::manip_holder& (*)(std::basic_ios&)> manip(std::basic_ios& (*pf)(std::basic_ios&)) { return pf; } - testspr::manip_holder + inline SPROUT_NON_CONSTEXPR testspr::manip_holder manip(std::ios_base& (*pf)(std::ios_base&)) { return pf; } diff --git a/testspr/typeinfo.hpp b/testspr/typeinfo.hpp index b32ca91f..1544f764 100644 --- a/testspr/typeinfo.hpp +++ b/testspr/typeinfo.hpp @@ -26,6 +26,7 @@ # include # include #endif +#include namespace testspr { // @@ -42,7 +43,8 @@ namespace testspr { // #ifdef TESTSPR_HAS_CXXABI_H namespace detail { - std::string cxa_demangle(char const* mangled) { + inline SPROUT_NON_CONSTEXPR std::string + cxa_demangle(char const* mangled) { int status; char* demangled = abi::__cxa_demangle(mangled, 0, 0, &status); std::string result(demangled); @@ -51,20 +53,24 @@ namespace testspr { } } // namespace detail template - inline std::string typename_of() { + inline SPROUT_NON_CONSTEXPR std::string + typename_of() { return testspr::detail::cxa_demangle(typeid(T).name()); } template - inline std::string typename_of(T&& t) { + inline SPROUT_NON_CONSTEXPR std::string + typename_of(T&& t) { return testspr::detail::cxa_demangle(typeid(std::forward(t)).name()); } #else template - inline std::string typename_of() { + inline SPROUT_NON_CONSTEXPR std::string + typename_of() { return std::string(typeid(T).name()); } template - inline std::string typename_of(T&& t) { + inline SPROUT_NON_CONSTEXPR std::string + typename_of(T&& t) { return std::string(typeid(std::forward(t)).name()); } #endif