diff --git a/cmake/macros/group_sources.cmake b/cmake/macros/group_sources.cmake index c0de7df..9c2bebf 100644 --- a/cmake/macros/group_sources.cmake +++ b/cmake/macros/group_sources.cmake @@ -20,39 +20,41 @@ # SOFTWARE. set(WITH_SOURCE_TREE "hierarchical") -macro(group_sources dir) +macro(group_sources) # Skip this if WITH_SOURCE_TREE is not set (empty string). if (NOT ${WITH_SOURCE_TREE} STREQUAL "") - # Include all header and c files - file(GLOB_RECURSE elements RELATIVE ${dir} *.h *.hpp *.inl *.inc *.c *.cpp *.cc) + foreach(dir ${ARGN}) + # Include all header and c files + file(GLOB_RECURSE elements RELATIVE ${dir} ${dir}/*) - foreach(element ${elements}) - # Extract filename and directory - get_filename_component(element_name ${element} NAME) - get_filename_component(element_dir ${element} DIRECTORY) + foreach(element ${elements}) + # Extract filename and directory + get_filename_component(element_name ${element} NAME) + get_filename_component(element_dir ${element} DIRECTORY) - if (NOT ${element_dir} STREQUAL "") - # If the file is in a subdirectory use it as source group. - if (${WITH_SOURCE_TREE} STREQUAL "flat") - # Build flat structure by using only the first subdirectory. - string(FIND ${element_dir} "/" delemiter_pos) - if (NOT ${delemiter_pos} EQUAL -1) - string(SUBSTRING ${element_dir} 0 ${delemiter_pos} group_name) - source_group("${group_name}" FILES ${dir}/${element}) + if (NOT ${element_dir} STREQUAL "") + # If the file is in a subdirectory use it as source group. + if (${WITH_SOURCE_TREE} STREQUAL "flat") + # Build flat structure by using only the first subdirectory. + string(FIND ${element_dir} "/" delemiter_pos) + if (NOT ${delemiter_pos} EQUAL -1) + string(SUBSTRING ${element_dir} 0 ${delemiter_pos} group_name) + source_group("${group_name}" FILES ${dir}/${element}) + else() + # Build hierarchical structure. + # File is in root directory. + source_group("${element_dir}" FILES ${dir}/${element}) + endif() else() - # Build hierarchical structure. - # File is in root directory. - source_group("${element_dir}" FILES ${dir}/${element}) + # Use the full hierarchical structure to build source_groups. + string(REPLACE "/" "\\" group_name ${element_dir}) + source_group("${group_name}" FILES ${dir}/${element}) endif() else() - # Use the full hierarchical structure to build source_groups. - string(REPLACE "/" "\\" group_name ${element_dir}) - source_group("${group_name}" FILES ${dir}/${element}) + # If the file is in the root directory, place it in the root source_group. + source_group("\\" FILES ${dir}/${element}) endif() - else() - # If the file is in the root directory, place it in the root source_group. - source_group("\\" FILES ${dir}/${element}) - endif() + endforeach() endforeach() endif() endmacro() diff --git a/include/continuable/continuable-operations.hpp b/include/continuable/continuable-operations.hpp new file mode 100644 index 0000000..17ea49f --- /dev/null +++ b/include/continuable/continuable-operations.hpp @@ -0,0 +1,40 @@ + +/* + + /~` _ _ _|_. _ _ |_ | _ + \_,(_)| | | || ||_|(_||_)|(/_ + + https://github.com/Naios/continuable + v4.0.0 + + Copyright(c) 2015 - 2019 Denis Blank + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files(the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and / or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +**/ + +#ifndef CONTINUABLE_OPERATIONS_HPP_INCLUDED +#define CONTINUABLE_OPERATIONS_HPP_INCLUDED + +/// \defgroup Operations Operations +/// provides functions to work with asynchronous control flows. + +#include +#include + +#endif // CONTINUABLE_OPERATIONS_HPP_INCLUDED diff --git a/include/continuable/continuable.hpp b/include/continuable/continuable.hpp index 214b220..cbbc43a 100644 --- a/include/continuable/continuable.hpp +++ b/include/continuable/continuable.hpp @@ -48,6 +48,7 @@ namespace cti {} #include #include #include +#include #include #include #include diff --git a/include/continuable/detail/operations/async.hpp b/include/continuable/detail/operations/async.hpp new file mode 100644 index 0000000..71e1fd1 --- /dev/null +++ b/include/continuable/detail/operations/async.hpp @@ -0,0 +1,47 @@ + +/* + + /~` _ _ _|_. _ _ |_ | _ + \_,(_)| | | || ||_|(_||_)|(/_ + + https://github.com/Naios/continuable + v4.0.0 + + Copyright(c) 2015 - 2019 Denis Blank + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files(the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and / or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +**/ + +#ifndef CONTINUABLE_DETAIL_OPERATIONS_ASYNC_HPP_INCLUDED +#define CONTINUABLE_DETAIL_OPERATIONS_ASYNC_HPP_INCLUDED + +#include + +namespace cti { +namespace detail { +namespace operations { +template +auto async(Callable&& callable, Args&&... args) { +} +} // namespace operations + +} // namespace detail +} // namespace cti + +#endif // CONTINUABLE_DETAIL_OPERATIONS_ASYNC_HPP_INCLUDED diff --git a/include/continuable/detail/operations/loop.hpp b/include/continuable/detail/operations/loop.hpp new file mode 100644 index 0000000..6088f0f --- /dev/null +++ b/include/continuable/detail/operations/loop.hpp @@ -0,0 +1,126 @@ + +/* + + /~` _ _ _|_. _ _ |_ | _ + \_,(_)| | | || ||_|(_||_)|(/_ + + https://github.com/Naios/continuable + v4.0.0 + + Copyright(c) 2015 - 2019 Denis Blank + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files(the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and / or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +**/ + +#ifndef CONTINUABLE_DETAIL_OPERATIONS_LOOP_HPP_INCLUDED +#define CONTINUABLE_DETAIL_OPERATIONS_LOOP_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace cti { +namespace detail { +template +struct loop_trait { + static_assert(!std::is_same::value, + "The callable passed to cti::loop must always return a " + "cti::continuable_base which resolves to a cti::result."); +}; + +template +struct loop_trait>>> { + template + static auto make(Callable&& callable) { + return make_continuable(std::forward(callable)); + } +}; +template +struct loop_trait>>> { + template + static auto make(Callable&& callable) { + return make_continuable(std::forward(callable)); + } +}; + +namespace operations { +template +class loop_frame : public std::enable_shared_from_this< + loop_frame> { + Promise promise_; + Callable callable_; + ArgsTuple args_; + +public: + void loop() { + traits::unpack( + [&callable_](auto&&... args) { + util::invoke(callable_, std::forward(args)...) + .then([me = this->shared_from_this()](auto&& result) { + if (result.is_empty()) { + me->loop(); + } else if (result.is_value()) { + traits::unpack(std::move(promise_), result); + } else { + assert(result.is_exception()); + traits::unpack(std::move(promise_), exception_arg_t{}, + result.get_exception()); + } + }); + }, + args_); + } +}; + +template +auto make_loop_frame(Promise&& promise, Callable&& callable, + ArgsTuple&& args_tuple) { + using frame_t = + loop_frame, traits::unrefcv_t, + traits::unrefcv_t>; + + return std::make_shared(std::forward(promise), + std::forward(callable), + std::forward(args_tuple)); +} + +template +auto loop(Callable&& callable, Args&&... args) { + using invocation_result_t = + decltype(util::invoke(callable, args...).finish()); + using trait_t = loop_trait; + return trait_t::make([callable = std::forward(callable), + args = std::make_tuple(std::forward( + args)...)](auto&& promise) mutable { + // Do the actual looping + auto frame = make_loop_frame(std::forward(promise)); + frame->loop(); + }); +} +} // namespace operations +} // namespace detail +} // namespace cti + +#endif // CONTINUABLE_DETAIL_OPERATIONS_LOOP_HPP_INCLUDED diff --git a/include/continuable/operations/async.hpp b/include/continuable/operations/async.hpp new file mode 100644 index 0000000..02320c7 --- /dev/null +++ b/include/continuable/operations/async.hpp @@ -0,0 +1,49 @@ + +/* + + /~` _ _ _|_. _ _ |_ | _ + \_,(_)| | | || ||_|(_||_)|(/_ + + https://github.com/Naios/continuable + v4.0.0 + + Copyright(c) 2015 - 2019 Denis Blank + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files(the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and / or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +**/ + +#ifndef CONTINUABLE_OPERATIONS_ASYNC_HPP_INCLUDED +#define CONTINUABLE_OPERATIONS_ASYNC_HPP_INCLUDED + +#include +#include + +namespace cti { +/// \ingroup Operations +/// \{ + +template +auto async(Callable&& callable, Args&&... args) { + return detail::operations::async(std::forward(callable), + std::forward(args)...); +} +/// \} +} // namespace cti + +#endif // CONTINUABLE_OPERATIONS_ASYNC_HPP_INCLUDED diff --git a/include/continuable/operations/loop.hpp b/include/continuable/operations/loop.hpp new file mode 100644 index 0000000..649287b --- /dev/null +++ b/include/continuable/operations/loop.hpp @@ -0,0 +1,49 @@ + +/* + + /~` _ _ _|_. _ _ |_ | _ + \_,(_)| | | || ||_|(_||_)|(/_ + + https://github.com/Naios/continuable + v4.0.0 + + Copyright(c) 2015 - 2019 Denis Blank + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files(the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and / or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +**/ + +#ifndef CONTINUABLE_OPERATIONS_LOOP_HPP_INCLUDED +#define CONTINUABLE_OPERATIONS_LOOP_HPP_INCLUDED + +#include +#include + +namespace cti { +/// \ingroup Operations +/// \{ + +template +auto loop(Callable&& callable, Args&&... args) { + return detail::operations::loop(std::forward(callable), + std::forward(args)...); +} +/// \} +} // namespace cti + +#endif // CONTINUABLE_OPERATIONS_LOOP_HPP_INCLUDED diff --git a/test/playground/CMakeLists.txt b/test/playground/CMakeLists.txt index 027b3ed..0109f99 100644 --- a/test/playground/CMakeLists.txt +++ b/test/playground/CMakeLists.txt @@ -1,34 +1,16 @@ -set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include/continuable) +set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) -file(GLOB LIB_SOURCES CONFIGURE_DEPENDS ${INCLUDE_DIR}/*.hpp) -file(GLOB LIB_SOURCES_DETAIL CONFIGURE_DEPENDS ${INCLUDE_DIR}/detail/*.hpp) -file(GLOB LIB_SOURCES_DETAIL_CONNECTIONS CONFIGURE_DEPENDS ${INCLUDE_DIR}/detail/connection/*.hpp) -file(GLOB LIB_SOURCES_DETAIL_CORE CONFIGURE_DEPENDS ${INCLUDE_DIR}/detail/core/*.hpp) -file(GLOB LIB_SOURCES_DETAIL_OTHER CONFIGURE_DEPENDS ${INCLUDE_DIR}/detail/other/*.hpp) -file(GLOB LIB_SOURCES_DETAIL_TRAVERSAL CONFIGURE_DEPENDS ${INCLUDE_DIR}/detail/traversal/*.hpp) -file(GLOB LIB_SOURCES_DETAIL_UTILITY CONFIGURE_DEPENDS ${INCLUDE_DIR}/detail/utility/*.hpp) +file(GLOB_RECURSE LIB_SOURCES CONFIGURE_DEPENDS ${INCLUDE_DIR}/*.hpp) set(TEST ${CMAKE_CURRENT_LIST_DIR}/test-playground.cpp) add_executable(test-playground ${LIB_SOURCES} - ${LIB_SOURCES_DETAIL} - ${LIB_SOURCES_DETAIL_CONNECTIONS} - ${LIB_SOURCES_DETAIL_CORE} - ${LIB_SOURCES_DETAIL_OTHER} - ${LIB_SOURCES_DETAIL_TRAVERSAL} - ${LIB_SOURCES_DETAIL_UTILITY} ${TEST}) -source_group(continuable FILES ${LIB_SOURCES}) -source_group(continuable\\detail FILES ${LIB_SOURCES_DETAIL}) -source_group(continuable\\detail\\connections FILES ${LIB_SOURCES_DETAIL_CONNECTIONS}) -source_group(continuable\\detail\\core FILES ${LIB_SOURCES_DETAIL_CORE}) -source_group(continuable\\detail\\other FILES ${LIB_SOURCES_DETAIL_OTHER}) -source_group(continuable\\detail\\traversal FILES ${LIB_SOURCES_DETAIL_TRAVERSAL}) -source_group(continuable\\detail\\utility FILES ${LIB_SOURCES_DETAIL_UTILITY}) -source_group(test FILES ${TEST}) +group_sources(${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_SOURCE_DIR}/include/) target_link_libraries(test-playground PRIVATE