From feac3f52c785deb0e5e6cd70c8b4960095b064be Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 28 May 2015 13:11:39 +0900 Subject: [PATCH] add example: compile-time lifegame --- example/lifegame/main.cpp | 222 +++++++++++++++++++++++++++++++++ sprout/stateful.hpp | 1 + sprout/stateful/type_index.hpp | 95 ++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 example/lifegame/main.cpp create mode 100644 sprout/stateful/type_index.hpp diff --git a/example/lifegame/main.cpp b/example/lifegame/main.cpp new file mode 100644 index 00000000..36be5aad --- /dev/null +++ b/example/lifegame/main.cpp @@ -0,0 +1,222 @@ +/*============================================================================= + Copyright (c) 2011-2015 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) +=============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include + +// +// next_cell +// +template +inline SPROUT_CONSTEXPR Value +next_cell(Value const& val, Size n) { + return val ? n == 2 || n == 3 : n == 3; +} +template +inline SPROUT_CONSTEXPR typename sprout::container_traits::value_type>::value_type +next_cell(Container const& cont, Difference1 i, Difference2 j) { + return i == 0 + // +---- + // | o x + // | x x + ? j == 0 + ? ::next_cell( + cont[i][j], + 0 + + cont[i][j + 1] + + cont[i + 1][j] + cont[i + 1][j + 1] + ) + // ----+ + // x o | + // x x | + : j == static_cast(sprout::size(cont[i]) - 1) + ? ::next_cell( + cont[i][j], + 0 + + cont[i][j - 1] + + cont[i + 1][j - 1] + cont[i + 1][j] + ) + // ----- + // x o x + // x x x + : ::next_cell( + cont[i][j], + 0 + + cont[i][j - 1] + cont[i][j + 1] + + cont[i + 1][j - 1] + cont[i + 1][j] + cont[i + 1][j + 1] + ) + : i == static_cast(sprout::size(cont) - 1) + // | x x + // | o x + // +---- + ? j == 0 + ? ::next_cell( + cont[i][j], + 0 + + cont[i - 1][j] + cont[i - 1][j + 1] + + cont[i][j + 1] + ) + // x x | + // x o | + // ----+ + : j == static_cast(sprout::size(cont[i]) - 1) + ? ::next_cell( + cont[i][j], + 0 + + cont[i - 1][j - 1] + cont[i - 1][j] + + cont[i][j - 1] + ) + // x x x + // x o x + // ----- + : ::next_cell( + cont[i][j], + 0 + + cont[i - 1][j - 1] + cont[i - 1][j] + cont[i - 1][j + 1] + + cont[i][j - 1] + cont[i][j + 1] + ) + // | x x + // | o x + // | x x + : j == 0 + ? ::next_cell( + cont[i][j], + 0 + + cont[i - 1][j] + cont[i - 1][j + 1] + + cont[i][j + 1] + + cont[i + 1][j] + cont[i + 1][j + 1]) + // x x | + // x o | + // x x | + : j == static_cast(sprout::size(cont[i]) - 1) + ? ::next_cell( + cont[i][j], + 0 + + cont[i - 1][j - 1] + cont[i - 1][j] + + cont[i][j - 1] + + cont[i + 1][j - 1] + cont[i + 1][j] + ) + // x x x + // x o x + // x x x + : ::next_cell( + cont[i][j], + 0 + + cont[i - 1][j - 1] + cont[i - 1][j] + cont[i - 1][j + 1] + + cont[i][j - 1] + cont[i][j + 1] + + cont[i + 1][j - 1] + cont[i + 1][j] + cont[i + 1][j + 1] + ) + ; +} + +namespace detail { + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::value_type + next_cells_2(Container const& cont, sprout::index_t i, sprout::index_tuple) { + return sprout::remake::value_type>( + cont[i], sprout::size(cont[i]), + ::next_cell(cont, i, Js)... + ); + } + template + inline SPROUT_CONSTEXPR Container + next_cells_1(Container const& cont, sprout::index_tuple) { + return sprout::remake( + cont, sprout::size(cont), + detail::next_cells_2(cont, Is, sprout::container_indexes::value_type>::make())... + ); + } +} // namespace detail +// +// next_cells +// +template +inline SPROUT_CONSTEXPR Container +next_cells(Container const& cont) { + return detail::next_cells_1(cont, sprout::container_indexes::make()); +} + +namespace detail { + struct gen_next_cells { + public: + template + SPROUT_CONSTEXPR sprout::pair + operator()(Container const& cont) const { + return sprout::pair(cont, ::next_cells(cont)); + } + }; +} // namespace detail +// +// next_cells +// +template +inline SPROUT_CONSTEXPR sprout::array +next_cells(Container const& cont) { + return sprout::fixed::unfold >(detail::gen_next_cells(), cont); +} + +#include +#include + +#define BOARD_WIDTH 16 +#define BOARD_HEIGHT 16 +#define BOARD_COUNT 16 + +template +void SPROUT_NON_CONSTEXPR print_board(Container const& board) { + testspr::print_hl(); + for (auto&& line : board) { + for (auto&& cell : line) { + testspr::print(cell ? "■" : "□", ' '); + } + testspr::print_ln(); + } +} + +int main() { + typedef sprout::array, BOARD_HEIGHT> board_type; + + // セルの初期配置 +#define _ 0 +#define X 1 + SPROUT_STATIC_CONSTEXPR board_type board0 + {{ + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, X, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, X, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, X, X, _, _, X, X, X, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}}, + {{_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}} + }}; +#undef _ +#undef X + + // ライフゲームの実行 + SPROUT_STATIC_CONSTEXPR auto boards = ::next_cells(board0); + + // 表示 + for (auto&& board : boards) { + ::print_board(board); + } +} + diff --git a/sprout/stateful.hpp b/sprout/stateful.hpp index 2974168e..ac768336 100644 --- a/sprout/stateful.hpp +++ b/sprout/stateful.hpp @@ -15,5 +15,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_STATEFUL_HPP diff --git a/sprout/stateful/type_index.hpp b/sprout/stateful/type_index.hpp new file mode 100644 index 00000000..f58793a9 --- /dev/null +++ b/sprout/stateful/type_index.hpp @@ -0,0 +1,95 @@ +/*============================================================================= + Copyright (c) 2011-2015 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_STATEFUL_TYPE_INDEX_HPP +#define SPROUT_STATEFUL_TYPE_INDEX_HPP + +#include +#include +#include +#include +#include + +namespace sprout { +#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR + + class type_index { + private: + int id_; + public: + template + explicit SPROUT_CONSTEXPR type_index(sprout::typed_id) SPROUT_NOEXCEPT + : id_(sprout::typed_id::value) + {} + explicit SPROUT_CONSTEXPR type_index(int id) SPROUT_NOEXCEPT + : id_(id) + {} + SPROUT_CONSTEXPR bool + operator==(sprout::type_index const& rhs) const SPROUT_NOEXCEPT { + return id_ == rhs.id_; + } + SPROUT_CONSTEXPR bool + operator!=(sprout::type_index const& rhs) const SPROUT_NOEXCEPT { + return !(*this == rhs); + } + SPROUT_CONSTEXPR bool + operator<(sprout::type_index const& rhs) const SPROUT_NOEXCEPT { + return id_ < rhs.id_; + } + SPROUT_CONSTEXPR bool + operator<=(sprout::type_index const& rhs) const SPROUT_NOEXCEPT { + return !(rhs < *this); + } + SPROUT_CONSTEXPR bool + operator>(sprout::type_index const& rhs) const SPROUT_NOEXCEPT { + return rhs < *this; + } + SPROUT_CONSTEXPR bool + operator>=(sprout::type_index const& rhs) const SPROUT_NOEXCEPT { + return !(*this < rhs); + } + SPROUT_CONSTEXPR std::size_t + hash_code() const SPROUT_NOEXCEPT { + return sprout::hash_value(id_); + } + } ; + +#endif +} // namespace sprout + +#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR + +namespace sprout { + // + // hash_value + // + inline SPROUT_CONSTEXPR std::size_t + hash_value(sprout::type_index const& v) { + return v.hash_code(); + } +} // namespace sprout + +namespace std { +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + // + // hash + // + template<> + struct hash + : public sprout::hash + {}; +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +} // namespace std + +#endif + +#endif // #ifndef SPROUT_STATEFUL_TYPE_INDEX_HPP