add type tuple algorithms and C++17 type traits

This commit is contained in:
bolero-MURAKAMI 2017-09-15 19:08:49 +09:00
parent c79553a652
commit 2614c4e3f9
19 changed files with 883 additions and 205 deletions

View file

@ -9,6 +9,14 @@
#define SPROUT_TYPE_ALGORITHM_HPP #define SPROUT_TYPE_ALGORITHM_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type/algorithm/all_of.hpp>
#include <sprout/type/algorithm/all_of_same.hpp>
#include <sprout/type/algorithm/any_of.hpp>
#include <sprout/type/algorithm/any_of_same.hpp>
#include <sprout/type/algorithm/none_of.hpp>
#include <sprout/type/algorithm/none_of_same.hpp>
#include <sprout/type/algorithm/one_of.hpp>
#include <sprout/type/algorithm/one_of_same.hpp>
#include <sprout/type/algorithm/find_index.hpp> #include <sprout/type/algorithm/find_index.hpp>
#include <sprout/type/algorithm/find_index_if.hpp> #include <sprout/type/algorithm/find_index_if.hpp>
#include <sprout/type/algorithm/count.hpp> #include <sprout/type/algorithm/count.hpp>

View file

@ -0,0 +1,80 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_ALL_OF_HPP
#define SPROUT_TYPE_ALGORITHM_ALL_OF_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/apply.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct all_of_impl;
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct all_of_impl<Tuple, Predicate, First, Last, Pivot, true>
: public sprout::bool_constant<
sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct all_of_impl<Tuple, Predicate, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::all_of_impl<
Tuple, Predicate, First, First + Pivot,
Pivot / 2
>::value
&& sprout::types::detail::all_of_impl<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename Predicate, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct all_of
: public sprout::types::detail::all_of_impl<Tuple, Predicate, 0, Size, Size / 2>
{};
template<typename Tuple, typename Predicate>
struct all_of<Tuple, Predicate, 0>
: public sprout::true_type
{};
} // namespace detail
//
// all_of
//
template<typename Tuple, typename Predicate>
struct all_of
: public sprout::types::detail::all_of<Tuple, Predicate>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename Predicate>
using all_of_t = typename sprout::types::all_of<Tuple, Predicate>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename Predicate>
SPROUT_STATIC_CONSTEXPR bool all_of_v = sprout::types::all_of<Tuple, Predicate>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_ALL_OF_HPP

View file

@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_ALL_OF_SAME_HPP
#define SPROUT_TYPE_ALGORITHM_ALL_OF_SAME_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct all_of_same_impl;
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct all_of_same_impl<Tuple, T, First, Last, Pivot, true>
: public sprout::bool_constant<
std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct all_of_same_impl<Tuple, T, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::all_of_same_impl<
Tuple, T, First, First + Pivot,
Pivot / 2
>::value
&& sprout::types::detail::all_of_same_impl<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename T, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct all_of_same
: public sprout::types::detail::all_of_same_impl<Tuple, T, 0, Size, Size / 2>
{};
template<typename Tuple, typename T>
struct all_of_same<Tuple, T, 0>
: public sprout::true_type
{};
} // namespace detail
//
// all_of_same
//
template<typename Tuple, typename T>
struct all_of_same
: public sprout::types::detail::all_of_same<Tuple, T>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename T>
using all_of_same_t = typename sprout::types::all_of_same<Tuple, T>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename T>
SPROUT_STATIC_CONSTEXPR bool all_of_same_v = sprout::types::all_of_same<Tuple, T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_ALL_OF_SAME_HPP

View file

@ -0,0 +1,80 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_ANY_OF_HPP
#define SPROUT_TYPE_ALGORITHM_ANY_OF_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/apply.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct any_of_impl;
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct any_of_impl<Tuple, Predicate, First, Last, Pivot, true>
: public sprout::bool_constant<
sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct any_of_impl<Tuple, Predicate, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::any_of_impl<
Tuple, Predicate, First, First + Pivot,
Pivot / 2
>::value
|| sprout::types::detail::any_of_impl<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename Predicate, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct any_of
: public sprout::types::detail::any_of_impl<Tuple, Predicate, 0, Size, Size / 2>
{};
template<typename Tuple, typename Predicate>
struct any_of<Tuple, Predicate, 0>
: public sprout::false_type
{};
} // namespace detail
//
// any_of
//
template<typename Tuple, typename Predicate>
struct any_of
: public sprout::types::detail::any_of<Tuple, Predicate>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename Predicate>
using any_of_t = typename sprout::types::any_of<Tuple, Predicate>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename Predicate>
SPROUT_STATIC_CONSTEXPR bool any_of_v = sprout::types::any_of<Tuple, Predicate>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_ANY_OF_HPP

View file

@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_ANY_OF_SAME_HPP
#define SPROUT_TYPE_ALGORITHM_ANY_OF_SAME_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct any_of_same_impl;
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct any_of_same_impl<Tuple, T, First, Last, Pivot, true>
: public sprout::bool_constant<
std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct any_of_same_impl<Tuple, T, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::any_of_same_impl<
Tuple, T, First, First + Pivot,
Pivot / 2
>::value
|| sprout::types::detail::any_of_same_impl<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename T, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct any_of_same
: public sprout::types::detail::any_of_same_impl<Tuple, T, 0, Size, Size / 2>
{};
template<typename Tuple, typename T>
struct any_of_same<Tuple, T, 0>
: public sprout::false_type
{};
} // namespace detail
//
// any_of_same
//
template<typename Tuple, typename T>
struct any_of_same
: public sprout::types::detail::any_of_same<Tuple, T>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename T>
using any_of_same_t = typename sprout::types::any_of_same<Tuple, T>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename T>
SPROUT_STATIC_CONSTEXPR bool any_of_same_v = sprout::types::any_of_same<Tuple, T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_ANY_OF_SAME_HPP

View file

@ -10,7 +10,7 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type/tuple.hpp> #include <sprout/type/tuple.hpp>
#include <sprout/type/algorithm/find_index.hpp> #include <sprout/type/algorithm/any_of_same.hpp>
namespace sprout { namespace sprout {
namespace types { namespace types {
@ -19,7 +19,7 @@ namespace sprout {
// //
template<typename Tuple, typename T> template<typename Tuple, typename T>
struct contains struct contains
: public sprout::types::find_index<Tuple, T>::is_found : public sprout::types::any_of_same<Tuple, T>
{}; {};
#if SPROUT_USE_TEMPLATE_ALIASES #if SPROUT_USE_TEMPLATE_ALIASES

View file

@ -10,7 +10,7 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type/tuple.hpp> #include <sprout/type/tuple.hpp>
#include <sprout/type/algorithm/find_index_if.hpp> #include <sprout/type/algorithm/any_of.hpp>
namespace sprout { namespace sprout {
namespace types { namespace types {
@ -19,7 +19,7 @@ namespace sprout {
// //
template<typename Tuple, typename Predicate> template<typename Tuple, typename Predicate>
struct contains_if struct contains_if
: public sprout::types::find_index_if<Tuple, Predicate>::is_found : public sprout::types::any_of<Tuple, Predicate>
{}; {};
#if SPROUT_USE_TEMPLATE_ALIASES #if SPROUT_USE_TEMPLATE_ALIASES

View file

@ -0,0 +1,80 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_NONE_OF_HPP
#define SPROUT_TYPE_ALGORITHM_NONE_OF_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/apply.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct none_of_impl;
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct none_of_impl<Tuple, Predicate, First, Last, Pivot, true>
: public sprout::bool_constant<
!sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct none_of_impl<Tuple, Predicate, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::none_of_impl<
Tuple, Predicate, First, First + Pivot,
Pivot / 2
>::value
&& sprout::types::detail::none_of_impl<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename Predicate, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct none_of
: public sprout::types::detail::none_of_impl<Tuple, Predicate, 0, Size, Size / 2>
{};
template<typename Tuple, typename Predicate>
struct none_of<Tuple, Predicate, 0>
: public sprout::true_type
{};
} // namespace detail
//
// none_of
//
template<typename Tuple, typename Predicate>
struct none_of
: public sprout::types::detail::none_of<Tuple, Predicate>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename Predicate>
using none_of_t = typename sprout::types::none_of<Tuple, Predicate>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename Predicate>
SPROUT_STATIC_CONSTEXPR bool none_of_v = sprout::types::none_of<Tuple, Predicate>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_NONE_OF_HPP

View file

@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_NONE_OF_SAME_HPP
#define SPROUT_TYPE_ALGORITHM_NONE_OF_SAME_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct none_of_same_impl;
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct none_of_same_impl<Tuple, T, First, Last, Pivot, true>
: public sprout::bool_constant<
!std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct none_of_same_impl<Tuple, T, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::none_of_same_impl<
Tuple, T, First, First + Pivot,
Pivot / 2
>::value
&& sprout::types::detail::none_of_same_impl<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename T, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct none_of_same
: public sprout::types::detail::none_of_same_impl<Tuple, T, 0, Size, Size / 2>
{};
template<typename Tuple, typename T>
struct none_of_same<Tuple, T, 0>
: public sprout::true_type
{};
} // namespace detail
//
// none_of_same
//
template<typename Tuple, typename T>
struct none_of_same
: public sprout::types::detail::none_of_same<Tuple, T>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename T>
using none_of_same_t = typename sprout::types::none_of_same<Tuple, T>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename T>
SPROUT_STATIC_CONSTEXPR bool none_of_same_v = sprout::types::none_of_same<Tuple, T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_NONE_OF_SAME_HPP

View file

@ -0,0 +1,115 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_ONE_OF_HPP
#define SPROUT_TYPE_ALGORITHM_ONE_OF_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/apply.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct one_of_impl_1;
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_impl_1<Tuple, Predicate, First, Last, Pivot, true>
: public sprout::bool_constant<
!sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_impl_1<Tuple, Predicate, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::one_of_impl_1<
Tuple, Predicate, First, First + Pivot,
Pivot / 2
>::value
&& sprout::types::detail::one_of_impl_1<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct one_of_impl;
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_impl<Tuple, Predicate, First, Last, Pivot, true>
: public sprout::bool_constant<
sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value
>
{};
template<
typename Tuple, typename Predicate, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_impl<Tuple, Predicate, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::one_of_impl<
Tuple, Predicate, First, First + Pivot,
Pivot / 2
>::value
? sprout::types::detail::one_of_impl_1<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
: sprout::types::detail::one_of_impl<
Tuple, Predicate, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename Predicate, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct one_of
: public sprout::types::detail::one_of_impl<Tuple, Predicate, 0, Size, Size / 2>
{};
template<typename Tuple, typename Predicate>
struct one_of<Tuple, Predicate, 0>
: public sprout::true_type
{};
} // namespace detail
//
// one_of
//
template<typename Tuple, typename Predicate>
struct one_of
: public sprout::types::detail::one_of<Tuple, Predicate>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename Predicate>
using one_of_t = typename sprout::types::one_of<Tuple, Predicate>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename Predicate>
SPROUT_STATIC_CONSTEXPR bool one_of_v = sprout::types::one_of<Tuple, Predicate>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_ONE_OF_HPP

View file

@ -0,0 +1,114 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_ALGORITHM_ONE_OF_SAME_HPP
#define SPROUT_TYPE_ALGORITHM_ONE_OF_SAME_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type/tuple.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct one_of_same_impl_1;
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_same_impl_1<Tuple, T, First, Last, Pivot, true>
: public sprout::bool_constant<
!std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_same_impl_1<Tuple, T, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::one_of_same_impl_1<
Tuple, T, First, First + Pivot,
Pivot / 2
>::value
&& sprout::types::detail::one_of_same_impl_1<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot,
bool C1 = (Pivot == 0)
>
struct one_of_same_impl;
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_same_impl<Tuple, T, First, Last, Pivot, true>
: public sprout::bool_constant<
std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value
>
{};
template<
typename Tuple, typename T, std::size_t First, std::size_t Last,
std::size_t Pivot
>
struct one_of_same_impl<Tuple, T, First, Last, Pivot, false>
: public sprout::bool_constant<
sprout::types::detail::one_of_same_impl<
Tuple, T, First, First + Pivot,
Pivot / 2
>::value
? sprout::types::detail::one_of_same_impl_1<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
: sprout::types::detail::one_of_same_impl<
Tuple, T, First + Pivot, Last,
(Last - First - Pivot) / 2
>::value
>
{};
template<typename Tuple, typename T, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct one_of_same
: public sprout::types::detail::one_of_same_impl<Tuple, T, 0, Size, Size / 2>
{};
template<typename Tuple, typename T>
struct one_of_same<Tuple, T, 0>
: public sprout::true_type
{};
} // namespace detail
//
// one_of_same
//
template<typename Tuple, typename T>
struct one_of_same
: public sprout::types::detail::one_of_same<Tuple, T>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename T>
using one_of_same_t = typename sprout::types::one_of_same<Tuple, T>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename T>
SPROUT_STATIC_CONSTEXPR bool one_of_same_v = sprout::types::one_of_same<Tuple, T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_ONE_OF_SAME_HPP

View file

@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATIONS_HPP
#define SPROUT_TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATIONS_HPP
#include <sprout/config.hpp>
#include <sprout/detail/predef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type_traits/remove_cv.hpp>
#include <sprout/type_traits/remove_all_extents.hpp>
namespace sprout {
//
// has_unique_object_representations
//
#if SPROUT_CLANG_HAS_FUTURE(has_unique_object_representations) || SPROUT_GCC_OR_LATER(7, 0, 0)
template<typename T>
struct has_unique_object_representations
: public sprout::bool_constant<
__has_unique_object_representations(typename sprout::remove_cv<typename sprout::remove_all_extents<T>::type>::type)
>
{};
#else // #if SPROUT_CLANG_HAS_FUTURE(has_unique_object_representations) || SPROUT_GCC_OR_LATER(7, 0, 0)
template<typename T>
struct has_unique_object_representations
: public sprout::false_type
{};
#endif // #if SPROUT_CLANG_HAS_FUTURE(has_unique_object_representations) || SPROUT_GCC_OR_LATER(7, 0, 0)
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool has_unique_object_representations_v = sprout::has_unique_object_representations<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATIONS_HPP

View file

@ -0,0 +1,29 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_TRAITS_INVOKE_RESULT_HPP
#define SPROUT_TYPE_TRAITS_INVOKE_RESULT_HPP
#include <sprout/config.hpp>
#include <sprout/type_traits/result_of.hpp>
namespace sprout {
//
// invoke_result
//
template<typename F, typename... Args>
struct invoke_result
: public sprout::detail::invoke_result<void, F, Args...>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename F, typename... Args>
using invoke_result_t = typename sprout::invoke_result<F, Args...>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_TRAITS_INVOKE_RESULT_HPP

View file

@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2011-2017 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_TYPE_TRAITS_IS_AGGREGATE_HPP
#define SPROUT_TYPE_TRAITS_IS_AGGREGATE_HPP
#include <sprout/config.hpp>
#include <sprout/detail/predef.hpp>
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type_traits/remove_cv.hpp>
#include <sprout/type_traits/remove_all_extents.hpp>
namespace sprout {
//
// is_aggregate
//
#if SPROUT_CLANG_HAS_FUTURE(is_aggregate) || SPROUT_GCC_OR_LATER(7, 0, 0)
template<typename T>
struct is_aggregate
: public sprout::bool_constant<
__is_aggregate(typename sprout::remove_cv<typename sprout::remove_all_extents<T>::type>::type)
>
{};
#else // #if SPROUT_CLANG_HAS_FUTURE(is_aggregate) || SPROUT_GCC_OR_LATER(7, 0, 0)
template<typename T>
struct is_aggregate
: public sprout::false_type
{};
#endif // #if SPROUT_CLANG_HAS_FUTURE(is_aggregate) || SPROUT_GCC_OR_LATER(7, 0, 0)
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_aggregate_v = sprout::is_aggregate<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_TRAITS_IS_AGGREGATE_HPP

View file

@ -17,10 +17,12 @@
#include <sprout/type_traits/is_standard_layout.hpp> #include <sprout/type_traits/is_standard_layout.hpp>
#include <sprout/type_traits/is_pod.hpp> #include <sprout/type_traits/is_pod.hpp>
#include <sprout/type_traits/is_literal_type.hpp> #include <sprout/type_traits/is_literal_type.hpp>
#include <sprout/type_traits/has_unique_object_representations.hpp>
#include <sprout/type_traits/is_empty.hpp> #include <sprout/type_traits/is_empty.hpp>
#include <sprout/type_traits/is_polymorphic.hpp> #include <sprout/type_traits/is_polymorphic.hpp>
#include <sprout/type_traits/is_abstract.hpp> #include <sprout/type_traits/is_abstract.hpp>
#include <sprout/type_traits/is_final.hpp> #include <sprout/type_traits/is_final.hpp>
#include <sprout/type_traits/is_aggregate.hpp>
#include <sprout/type_traits/is_signed.hpp> #include <sprout/type_traits/is_signed.hpp>
#include <sprout/type_traits/is_unsigned.hpp> #include <sprout/type_traits/is_unsigned.hpp>
#include <sprout/type_traits/is_constructible.hpp> #include <sprout/type_traits/is_constructible.hpp>

View file

@ -8,215 +8,55 @@
#ifndef SPROUT_TYPE_TRAITS_RESULT_OF_HPP #ifndef SPROUT_TYPE_TRAITS_RESULT_OF_HPP
#define SPROUT_TYPE_TRAITS_RESULT_OF_HPP #define SPROUT_TYPE_TRAITS_RESULT_OF_HPP
#if defined(_MSC_VER) && (_MSC_VER <= 1900)
# include <functional>
#endif
#include <utility> #include <utility>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/identity.hpp> #include <sprout/type_traits/identity.hpp>
#include <sprout/detail/nil_base.hpp>
#include <sprout/type/type_tuple.hpp>
namespace sprout { namespace sprout {
#if defined(_MSC_VER) && (_MSC_VER <= 1900)
//
// result_of
//
using std::result_of;
#else
//
// result_of
//
namespace detail { namespace detail {
struct result_of_memfun_ref_helper {
public:
template<typename F, typename T, typename... Args>
static sprout::identity<decltype((std::declval<T>().*std::declval<F>())(std::declval<Args>()...))> test(sprout::types::type_tuple<Args...>);
template<typename...>
static sprout::detail::nil_base test(...);
};
#if defined(_MSC_VER) && (_MSC_VER > 1900)
template<
typename MemPtr, typename Arg, typename Args,
typename Base_ = typename sprout::identity<decltype(sprout::detail::result_of_memfun_ref_helper::test<MemPtr, Arg>(Args()))>::type
>
struct result_of_memfun_ref_impl
: public Base_
{};
template<typename MemPtr, typename Arg, typename... Args>
struct result_of_memfun_ref
: public sprout::detail::result_of_memfun_ref_impl<MemPtr, Arg, sprout::types::type_tuple<Args...> >
{};
#else
template<typename MemPtr, typename Arg, typename... Args>
struct result_of_memfun_ref
: public sprout::identity<decltype(sprout::detail::result_of_memfun_ref_helper::test<MemPtr, Arg, Args...>(sprout::types::type_tuple<Args...>()))>::type
{};
#endif
struct result_of_memfun_deref_helper {
public:
template<typename F, typename T, typename... Args>
static sprout::identity<decltype(((*std::declval<T>()).*std::declval<F>())(std::declval<Args>()...))> test(sprout::types::type_tuple<Args...>);
template<typename...>
static sprout::detail::nil_base test(...);
};
#if defined(_MSC_VER) && (_MSC_VER > 1900)
template<
typename MemPtr, typename Arg, typename Args,
typename Base_ = typename sprout::identity<decltype(sprout::detail::result_of_memfun_deref_helper::test<MemPtr, Arg>(Args()))>::type
>
struct result_of_memfun_deref_impl
: public Base_
{};
template<typename MemPtr, typename Arg, typename... Args>
struct result_of_memfun_deref
: public sprout::detail::result_of_memfun_deref_impl<MemPtr, Arg, sprout::types::type_tuple<Args...> >
{};
#else
template<typename MemPtr, typename Arg, typename... Args>
struct result_of_memfun_deref
: public sprout::identity<decltype(sprout::detail::result_of_memfun_deref_helper::test<MemPtr, Arg, Args...>(sprout::types::type_tuple<Args...>()))>::type
{};
#endif
struct result_of_memobj_ref_helper {
public:
template<typename F, typename T>
static sprout::identity<decltype(std::declval<T>().*std::declval<F>())> test(int);
template<typename, typename>
static sprout::detail::nil_base test(...);
};
#if defined(_MSC_VER) && (_MSC_VER > 1900)
template<
typename MemPtr, typename Arg,
typename Base_ = typename sprout::identity<decltype(sprout::detail::result_of_memobj_ref_helper::test<MemPtr, Arg>(0))>::type
>
struct result_of_memobj_ref
: public Base_
{};
#else
template<typename MemPtr, typename Arg>
struct result_of_memobj_ref
: public sprout::identity<decltype(sprout::detail::result_of_memobj_ref_helper::test<MemPtr, Arg>(0))>::type
{};
#endif
struct result_of_memobj_deref_helper {
public:
template<typename F, typename T>
static sprout::identity<decltype((*std::declval<T>()).*std::declval<F>())> test(int);
template<typename, typename>
static sprout::detail::nil_base test(...);
};
#if defined(_MSC_VER) && (_MSC_VER > 1900)
template<
typename MemPtr, typename Arg,
typename Base_ = typename sprout::identity<decltype(sprout::detail::result_of_memobj_deref_helper::test<MemPtr, Arg>(0))>::type
>
struct result_of_memobj_deref
: public Base_
{};
#else
template<typename MemPtr, typename Arg>
struct result_of_memobj_deref
: public sprout::identity<decltype(sprout::detail::result_of_memobj_deref_helper::test<MemPtr, Arg>(0))>::type
{};
#endif
template<typename MemPtr, typename Arg>
struct result_of_memobj_impl;
template<typename R, typename Class, typename Arg>
struct result_of_memobj_impl<R Class::*, Arg> {
public:
typedef typename std::remove_cv<typename std::remove_reference<Arg>::type>::type argval_type;
typedef R Class::* mem_ptr_type;
typedef typename std::conditional<
std::is_same<argval_type, Class>::value || std::is_base_of<Class, argval_type>::value,
sprout::detail::result_of_memobj_ref<mem_ptr_type, Arg>,
sprout::detail::result_of_memobj_deref<mem_ptr_type, Arg>
>::type type;
};
template<typename MemPtr, typename Arg>
struct result_of_memobj
: public sprout::detail::result_of_memobj_impl<MemPtr, Arg>::type
{};
template<typename MemPtr, typename Arg, typename... Args>
struct result_of_memfun_impl;
template<typename R, typename Class, typename Arg, typename... Args>
struct result_of_memfun_impl<R Class::*, Arg, Args...> {
public:
typedef typename std::remove_cv<typename std::remove_reference<Arg>::type>::type argval_type;
typedef R Class::* mem_ptr_type;
typedef typename std::conditional<
std::is_same<argval_type, Class>::value || std::is_base_of<Class, argval_type>::value,
result_of_memfun_ref<mem_ptr_type, Arg, Args...>,
result_of_memfun_deref<mem_ptr_type, Arg, Args...>
>::type type;
};
template<typename MemPtr, typename Arg, typename... Args>
struct result_of_memfun
: public sprout::detail::result_of_memfun_impl<MemPtr, Arg, Args...>::type
{};
struct result_of_other_impl {
public:
template<typename F, typename... Args> template<typename F, typename... Args>
static sprout::identity<decltype(std::declval<F>()(std::declval<Args>()...))> test(int); inline SPROUT_CONSTEXPR decltype(std::declval<F>()(std::declval<Args>()...))
template<typename, typename...> invoke(F&&, Args&&...);
static sprout::detail::nil_base test(...);
};
#if defined(_MSC_VER)
template<typename Functor, typename... Args>
struct result_of_other_base {
public:
typedef typename sprout::identity<decltype(sprout::detail::result_of_other_impl::test<Functor, Args...>(0))>::type type;
};
template<typename Functor, typename... Args>
struct result_of_other
: public sprout::detail::result_of_other_base<Functor, Args...>::type
{};
#else
template<typename Functor, typename... Args>
struct result_of_other
: public sprout::identity<decltype(sprout::detail::result_of_other_impl::test<Functor, Args...>(0))>::type
{};
#endif
template<bool, bool, typename Functor, typename... Args> template<typename Base, typename T, typename Derived>
struct result_of_impl inline SPROUT_CONSTEXPR decltype(std::declval<Derived>().*(std::declval<T Base::*>()))
: public sprout::identity<sprout::detail::nil_base>::type invoke(T Base::*, Derived&&);
{};
template<typename MemPtr, typename Arg> template<typename PMD, typename Pointer>
struct result_of_impl<true, false, MemPtr, Arg> inline SPROUT_CONSTEXPR decltype((*std::declval<Pointer>()).*(std::declval<PMD>()))
: public sprout::detail::result_of_memobj<typename std::decay<MemPtr>::type, Arg> invoke(PMD&&, Pointer&&);
{};
template<typename MemPtr, typename Arg, typename... Args> template<typename Base, typename T, typename Derived, typename... Args>
struct result_of_impl<false, true, MemPtr, Arg, Args...> inline SPROUT_CONSTEXPR decltype((std::declval<Derived>().*(std::declval<T Base::*>()))(std::declval<Args>()...))
: public sprout::detail::result_of_memfun<typename std::decay<MemPtr>::type, Arg, Args...> invoke(T Base::*, Derived&&, Args&&...);
{};
template<typename Functor, typename... Args> template<typename PMF, typename Pointer, typename... Args>
struct result_of_impl<false, false, Functor, Args...> inline SPROUT_CONSTEXPR decltype(((*std::declval<Pointer>()).*(std::declval<PMF>()))(std::declval<Args>()...))
: public sprout::detail::result_of_other<Functor, Args...> invoke(PMF&& pmf, Pointer&& ptr, Args&&... args);
} // namespace detail
namespace detail {
template<typename Void, typename, typename...>
struct invoke_result {};
template<typename F, typename...Args>
struct invoke_result<decltype(void(sprout::detail::invoke(std::declval<F>(), std::declval<Args>()...))), F, Args...>
: public sprout::identity<decltype(sprout::detail::invoke(std::declval<F>(), std::declval<Args>()...))>
{}; {};
} // namespace detail } // namespace detail
template<typename Signature>
//
// result_of
//
template<typename>
struct result_of; struct result_of;
template<typename Functor, typename... Args> template<typename F, typename... Args>
struct result_of<Functor(Args...)> struct result_of<F(Args...)>
: public sprout::detail::result_of_impl< : public sprout::detail::invoke_result<void, F, Args...>
std::is_member_object_pointer<typename std::remove_reference<Functor>::type>::value,
std::is_member_function_pointer<typename std::remove_reference<Functor>::type>::value,
Functor, Args...
>
{}; {};
#endif
#if SPROUT_USE_TEMPLATE_ALIASES #if SPROUT_USE_TEMPLATE_ALIASES
template<typename F, typename... ArgTypes> template<typename T>
using result_of_t = typename sprout::result_of<F(ArgTypes...)>::type; using result_of_t = typename sprout::result_of<T>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES #endif // #if SPROUT_USE_TEMPLATE_ALIASES
} // namespace sprout } // namespace sprout

View file

@ -18,6 +18,7 @@
#include <sprout/type_traits/common_type.hpp> #include <sprout/type_traits/common_type.hpp>
#include <sprout/type_traits/underlying_type.hpp> #include <sprout/type_traits/underlying_type.hpp>
#include <sprout/type_traits/result_of.hpp> #include <sprout/type_traits/result_of.hpp>
#include <sprout/type_traits/invoke_result.hpp>
#include <sprout/type_traits/identity.hpp> #include <sprout/type_traits/identity.hpp>
#include <sprout/type_traits/common_decay.hpp> #include <sprout/type_traits/common_decay.hpp>

View file

@ -34,6 +34,11 @@ use_help=0
darkcult_cpp=$(cd $(dirname $0); pwd)/darkcult.cpp darkcult_cpp=$(cd $(dirname $0); pwd)/darkcult.cpp
darkcult_py=$(cd $(dirname $0); pwd)/darkcult.py darkcult_py=$(cd $(dirname $0); pwd)/darkcult.py
get_used_mem() {
local mem_info=(`free -m | sed -n "/^Mem:/s/^Mem:[ \t]*//p"`)
echo -n "${mem_info[1]}"
}
args=`getopt -o s:S:o:C:w:h:W:H:l:t:r:b:O:D:I:P:fc -l source:,stagedir:,output:,compiler:,width:,height:,tile-width:,tile-height:,left:,top:,right:,bottom:,option:,define:,include:,max-procs:,force,continuable,runtime,version,help -- "$@"` args=`getopt -o s:S:o:C:w:h:W:H:l:t:r:b:O:D:I:P:fc -l source:,stagedir:,output:,compiler:,width:,height:,tile-width:,tile-height:,left:,top:,right:,bottom:,option:,define:,include:,max-procs:,force,continuable,runtime,version,help -- "$@"`
if [ "$?" -ne 0 ]; then if [ "$?" -ne 0 ]; then
echo >&2 "error: options parse error. See 'darkcult.sh --help'" echo >&2 "error: options parse error. See 'darkcult.sh --help'"
@ -202,6 +207,7 @@ for ((y=0; y<height; y+=tile_height)); do
done done
echo "rendering:" echo "rendering:"
is_uncompleted=0
start=${SECONDS} start=${SECONDS}
if [ -z "${max_procs}" ]; then if [ -z "${max_procs}" ]; then
@ -227,6 +233,7 @@ if [ -z "${max_procs}" ]; then
echo >&2 " error: compile(${y}/${x}) failed." echo >&2 " error: compile(${y}/${x}) failed."
exit 1 exit 1
fi fi
done done
echo "" echo ""
@ -252,6 +259,7 @@ else
echo "" echo ""
if [ ${result} -eq 2 ]; then if [ ${result} -eq 2 ]; then
echo " compile terminated." echo " compile terminated."
is_terminated=1
exit 0 exit 0
elif [ ${result} -ne 0 ]; then elif [ ${result} -ne 0 ]; then
echo >&2 " error: compile failed." echo >&2 " error: compile failed."
@ -262,6 +270,7 @@ fi
let elapsed=${SECONDS}-${start} let elapsed=${SECONDS}-${start}
echo " elapsed(total) = ${elapsed}s" echo " elapsed(total) = ${elapsed}s"
if [ ${is_uncompleted} -eq 0 ]; then
for ((y=0; y<height; y+=tile_height)); do for ((y=0; y<height; y+=tile_height)); do
pushd ${stagedir}/${y}/ > /dev/null pushd ${stagedir}/${y}/ > /dev/null
pnmcat -lr $(ls *.ppm | sort -n) > ../${y}.ppm pnmcat -lr $(ls *.ppm | sort -n) > ../${y}.ppm
@ -270,5 +279,6 @@ done
pushd ${stagedir} > /dev/null pushd ${stagedir} > /dev/null
pnmcat -tb $(ls *.ppm | sort -n) > ${output} pnmcat -tb $(ls *.ppm | sort -n) > ${output}
popd > /dev/null popd > /dev/null
fi
echo "finished." echo "finished."