From 46755ba9d3af726012eec81471cf6be82d707152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pedro=20Bol=C3=ADvar=20Puente?= Date: Tue, 12 May 2020 13:23:18 +0200 Subject: [PATCH] Add placeholders for documentation of new modules --- README.rst | 22 ++++++++++------------ doc/cursor.rst | 7 +++++++ doc/cursors.rst | 12 ++++++++++-- doc/doxygen.config | 1 + doc/event_loop.rst | 11 +++++++++++ doc/index.rst | 4 ++++ doc/lens.rst | 11 +++++++++++ doc/lenses.rst | 18 ++++++++++++++++++ doc/views.rst | 10 ++++------ lager/constant.hpp | 5 +++++ lager/cursor.hpp | 7 +++++-- lager/lens.hpp | 29 +++++++++++++++++++++-------- lager/lenses.hpp | 30 +++++++++++++++++++++++------- lager/lenses/at.hpp | 5 +++++ lager/lenses/attr.hpp | 10 ++++++++-- lager/lenses/optional.hpp | 5 +++++ lager/lenses/unbox.hpp | 11 +++++++---- lager/lenses/variant.hpp | 15 +++++++++++---- lager/reader.hpp | 7 +++++-- lager/sensor.hpp | 5 +++++ lager/state.hpp | 5 +++++ lager/with.hpp | 10 ++++++++++ lager/writer.hpp | 7 +++++-- 23 files changed, 196 insertions(+), 51 deletions(-) create mode 100644 doc/cursor.rst create mode 100644 doc/lens.rst create mode 100644 doc/lenses.rst diff --git a/README.rst b/README.rst index 98c39aec..23f4bcd5 100644 --- a/README.rst +++ b/README.rst @@ -32,9 +32,12 @@ via pure functions. And you get time-travel for free! * **Documentation** (Contents_) * **Code** (GitHub_) +* **CppRussia-Piter 2019 Talk**: *Squaring the circle* (`YouTube + `_, `Slides + `_) * **CppCon 2018 Talk**: *The most valuable values* (`YouTube `_, `Slides - `_) + `_) * **C++ on Sea 2019 Talk**: *Postmodern immutable data-structures* (`YouTube `_, `Slides `_) @@ -116,29 +119,24 @@ This library is written in **C++17** and a compliant compiler and standard library necessary. It is `continuously tested`_ with GCC 7, but it might work with other compilers and versions. -It also depends on `Boost Hana`_. Some optional extensions and modules +It also depends on `Zug`_ and `Boost Hana`_. Some optional extensions and modules may have other dependencies documented in their respective sections. +.. _Zug: https://github.com/arximboldi/zug/ .. _Boost Hana: https://boostorg.github.io/hana .. _continuously tested: https://travis-ci.org/arximboldi/immer Usage ----- -This is a **header only** library but to be configured correctly you need -to run `CMake`_ first:: - - mkdir -p build && cd build - cmake .. -D lager_BUILD_DEBUGGER=OFF -D lager_BUILD_TESTS=OFF -D lager_BUILD_EXAMPLES=OFF -D lager_BUILD_DOCS=OFF - -Now you can just copy the ``lager`` -subfolder somewhere in your *include path*. +This is a **header only** you can just copy the ``lager`` subfolder +somewhere in your *include path*. Some components, like the time-travelling debugger, also require the installation of extra files. -You can use `CMake`_ to install the library in your -system once you have manually cloned the repository:: +You can use `CMake`_ to install the library in your system once you +have manually cloned the repository:: mkdir -p build && cd build cmake .. && sudo make install diff --git a/doc/cursor.rst b/doc/cursor.rst new file mode 100644 index 00000000..228e8f16 --- /dev/null +++ b/doc/cursor.rst @@ -0,0 +1,7 @@ + +cursor +====== + +.. doxygengroup:: cursors + :project: lager + :content-only: diff --git a/doc/cursors.rst b/doc/cursors.rst index 24613672..4be5fb6f 100644 --- a/doc/cursors.rst +++ b/doc/cursors.rst @@ -1,10 +1,18 @@ - .. _cursors: Cursors ======= -.. admonition:: TODO +.. admonition:: Work in progress :class: danger This section of the documentation has not been written yet. + + Meanwhile, you can watch the **C++ Russia 2019 Talk**: `Squaring + the circle: value oriented design in an object oriented system + `_ (`slides`_). + +.. _slides: https://sinusoid.es/talks/cpprussia19-piter + +.. image:: http://orvex.org.p11.hostingprod.com/images/under_construction.gif + :align: center diff --git a/doc/doxygen.config b/doc/doxygen.config index 69fad1ab..8b690f70 100644 --- a/doc/doxygen.config +++ b/doc/doxygen.config @@ -8,6 +8,7 @@ GENERATE_XML = YES INPUT = \ ../lager \ ../lager/event_loop \ + ../lager/lenses \ ../lager/debug INCLUDE_PATH = .. QUIET = YES diff --git a/doc/event_loop.rst b/doc/event_loop.rst index bc6dee21..5c8956f5 100644 --- a/doc/event_loop.rst +++ b/doc/event_loop.rst @@ -25,3 +25,14 @@ sdl .. doxygenstruct:: lager::sdl_event_loop .. doxygenstruct:: lager::with_sdl_event_loop + +qt +---- + +.. doxygenstruct:: lager::with_qt_event_loop + +qml +---- + +.. doxygenclass:: lager::event_loop_quick_item +.. doxygenstruct:: lager::with_qml_event_loop diff --git a/doc/index.rst b/doc/index.rst index ffa3a96e..f0fb30f1 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -17,6 +17,8 @@ Contents effects views modularity + cursors + lenses time-travel .. toctree:: @@ -24,9 +26,11 @@ Contents :maxdepth: 3 context + cursor debug deps event_loop + lens store util diff --git a/doc/lens.rst b/doc/lens.rst new file mode 100644 index 00000000..dd43be1e --- /dev/null +++ b/doc/lens.rst @@ -0,0 +1,11 @@ + +lens +==== + +.. doxygengroup:: lenses-api + :project: lager + :content-only: + +.. doxygengroup:: lenses + :project: lager + :content-only: diff --git a/doc/lenses.rst b/doc/lenses.rst new file mode 100644 index 00000000..3589d5b8 --- /dev/null +++ b/doc/lenses.rst @@ -0,0 +1,18 @@ +.. _lenses: + +Lenses +====== + +.. admonition:: Work in progress + :class: danger + + This section of the documentation has not been written yet. + + Meanwhile, you can watch the **C++ Russia 2019 Talk**: `Squaring + the circle: value oriented design in an object oriented system + `_ (`slides`_). + +.. _slides: https://sinusoid.es/talks/cpprussia19-piter + +.. image:: http://orvex.org.p11.hostingprod.com/images/under_construction.gif + :align: center diff --git a/doc/views.rst b/doc/views.rst index 93c2b9ca..8c49d148 100644 --- a/doc/views.rst +++ b/doc/views.rst @@ -124,12 +124,10 @@ with a widget tree UI, by breaking the circle as follows: .. admonition:: Library support This diffing mechanism can be a bit cumbersome, and sometimes error - prone. At `Sinusoidal Engineering`_ we are developing a new library - to aid this particular use-case. It will be first presented at the - `C++ Russia Piter`_ and `Meeting C++`_ conferences in Autumn 2019. - -.. _C++ Russia Piter: https://cppconf-piter.ru/en/ -.. _Meeting C++: http://meetingcpp.com/ + prone. :ref:`cursors` can do it for you automatically. They can + also do much more, and are an invaluable tool when `interfacing a + value-oriented data model with an object-oriented + UI`. Observables ----------- diff --git a/lager/constant.hpp b/lager/constant.hpp index bd440223..0b985a07 100644 --- a/lager/constant.hpp +++ b/lager/constant.hpp @@ -38,6 +38,9 @@ auto make_constant_node(T&& v) } // namespace detail +//! @defgroup cursors +//! @{ + template class constant : public reader_base> { @@ -61,4 +64,6 @@ auto make_constant(T&& v) -> constant> return std::forward(v); } +//! @} + } // namespace lager diff --git a/lager/cursor.hpp b/lager/cursor.hpp index 50b7f7ca..a5a9ac55 100644 --- a/lager/cursor.hpp +++ b/lager/cursor.hpp @@ -22,6 +22,9 @@ namespace lager { +//! @defgroup cursors +//! @{ + template struct cursor_mixin : writer_mixin @@ -64,8 +67,6 @@ class cursor_base /*! * Provides access to reading and writing values of type `T`. - * Model of `cursor_value`. - * @see `cursor_value` */ template class cursor : public cursor_base> @@ -76,4 +77,6 @@ class cursor : public cursor_base> using base_t::base_t; }; +//! @} + } // namespace lager diff --git a/lager/lens.hpp b/lager/lens.hpp index b0f1914b..fc2d0423 100644 --- a/lager/lens.hpp +++ b/lager/lens.hpp @@ -9,29 +9,38 @@ namespace lager { namespace detail { template -struct lens_i { +struct lens_i +{ virtual Part view(Whole const&) const = 0; virtual Whole set(Whole const&, Part const&) const = 0; }; template -struct lens_holder : public lens_i { +struct lens_holder : public lens_i +{ Lens value; template - lens_holder(T&& other) : value{std::forward(other)} {} + lens_holder(T&& other) + : value{std::forward(other)} + {} Part view(Whole const& w) const override { return ::lager::view(value, w); } - Whole set(Whole const& w, Part const& p) const override { + Whole set(Whole const& w, Part const& p) const override + { return ::lager::set(value, w, p); } }; } // namespace detail +//! @defgroup lenses-api +//! @{ + template -class lens : zug::detail::pipeable { +class lens : zug::detail::pipeable +{ std::shared_ptr const> holder_; public: @@ -41,18 +50,22 @@ class lens : zug::detail::pipeable { int>::type = 0> lens(Lens&& lens) : holder_{new detail::lens_holder, Whole, Part>{ - std::forward(lens)}} {} + std::forward(lens)}} + {} template - auto operator()(F &&f) const { + auto operator()(F&& f) const + { return [this, f = std::forward(f)](auto&& p) { return f(holder_->view(std::forward(p)))( [&](auto&& x) { return holder_->set(std::forward(p), - std::forward(x)); + std::forward(x)); }); }; } }; +//! @} + } // namespace lager diff --git a/lager/lenses.hpp b/lager/lenses.hpp index 95fca2f0..1f8db7c6 100644 --- a/lager/lenses.hpp +++ b/lager/lenses.hpp @@ -12,8 +12,8 @@ #pragma once -#include #include +#include #include #include @@ -25,16 +25,19 @@ template struct const_functor; template -auto make_const_functor(T&& x) -> const_functor { +auto make_const_functor(T&& x) -> const_functor +{ return {std::forward(x)}; } template -struct const_functor { +struct const_functor +{ T value; template - const_functor operator()(Fn&&) && { + const_functor operator()(Fn&&) && + { return std::move(*this); } }; @@ -43,22 +46,28 @@ template struct identity_functor; template -auto make_identity_functor(T&& x) -> identity_functor { +auto make_identity_functor(T&& x) -> identity_functor +{ return {std::forward(x)}; } template -struct identity_functor { +struct identity_functor +{ T value; template - auto operator()(Fn&& f) && { + auto operator()(Fn&& f) && + { return make_identity_functor( std::forward(f)(std::forward(value))); } }; } // namespace detail +//! @defgroup lenses-api +//! @{ + template decltype(auto) view(LensT&& lens, T&& x) { @@ -86,8 +95,13 @@ decltype(auto) over(LensT&& lens, T&& x, Fn&& fn) .value; } +//! @} + namespace lenses { +//! @defgroup lenses +//! @{ + template auto getset(Getter&& getter, Setter&& setter) { @@ -103,4 +117,6 @@ auto getset(Getter&& getter, Setter&& setter) } // namespace lenses +//! @} + } // namespace lager diff --git a/lager/lenses/at.hpp b/lager/lenses/at.hpp index 22ea0307..0295fc30 100644 --- a/lager/lenses/at.hpp +++ b/lager/lenses/at.hpp @@ -55,6 +55,9 @@ std::decay_t at_setter_impl(Whole&& whole, Part&& part, Key&& key) } // namespace detail +//! @defgroup lenses +//! @{ + /*! * `Key -> Lens<{X}, [X]>` */ @@ -78,5 +81,7 @@ auto at(Key key) }); } +//! @} + } // namespace lenses } // namespace lager diff --git a/lager/lenses/attr.hpp b/lager/lenses/attr.hpp index 018038f6..19629e54 100644 --- a/lager/lenses/attr.hpp +++ b/lager/lenses/attr.hpp @@ -2,17 +2,21 @@ #include -#include #include +#include namespace lager { namespace lenses { +//! @defgroup lenses +//! @{ + /*! * `(Part Whole::*) -> Lens` */ template -auto attr(Member member) { +auto attr(Member member) +{ return zug::comp([member](auto&& f) { return [&, f = LAGER_FWD(f)](auto&& p) { return f(LAGER_FWD(p).*member)([&](auto&& x) { @@ -24,5 +28,7 @@ auto attr(Member member) { }); } +//! @} + } // namespace lenses } // namespace lager diff --git a/lager/lenses/optional.hpp b/lager/lenses/optional.hpp index 0b75b8d8..d93235e1 100644 --- a/lager/lenses/optional.hpp +++ b/lager/lenses/optional.hpp @@ -71,6 +71,9 @@ struct add_opt } // namespace detail +//! @defgroup lenses +//! @{ + /*! * `Lens -> Lens<[W], [P]>` */ @@ -142,5 +145,7 @@ ZUG_INLINE_CONSTEXPR auto force_opt = zug::comp([](auto&& f) { }; }); +//! @} + } // namespace lenses } // namespace lager diff --git a/lager/lenses/unbox.hpp b/lager/lenses/unbox.hpp index ee24cfdf..1da5737c 100644 --- a/lager/lenses/unbox.hpp +++ b/lager/lenses/unbox.hpp @@ -2,23 +2,26 @@ #include -#include #include +#include namespace lager { namespace lenses { +//! @defgroup lenses +//! @{ + /*! * `Lens, T>` */ ZUG_INLINE_CONSTEXPR auto unbox = zug::comp([](auto&& f) { return [f](auto&& p) { - return f(LAGER_FWD(p).get())([&](auto&& x) { - return std::decay_t{LAGER_FWD(x)}; - }); + return f(LAGER_FWD(p).get())( + [&](auto&& x) { return std::decay_t{LAGER_FWD(x)}; }); }; }); +//! @} } // namespace lenses } // namespace lager diff --git a/lager/lenses/variant.hpp b/lager/lenses/variant.hpp index 71fc3281..0eb5fce3 100644 --- a/lager/lenses/variant.hpp +++ b/lager/lenses/variant.hpp @@ -1,11 +1,11 @@ #pragma once +#include #include #include -#include -#include #include +#include namespace lager { namespace lenses { @@ -14,10 +14,12 @@ namespace detail { // due to some obscure behavior on MSVC, this has to be implemented in a // manually defined function object template -struct alternative_t : zug::detail::pipeable { +struct alternative_t : zug::detail::pipeable +{ using Part = std::optional; template - auto operator()(F&& f) const { + auto operator()(F&& f) const + { return [f = std::forward(f)](auto&& p) { using Whole = std::decay_t; return f([&]() -> Part { @@ -38,8 +40,13 @@ struct alternative_t : zug::detail::pipeable { }; } // namespace detail +//! @defgroup lenses +//! @{ + template auto alternative = detail::alternative_t{}; +//! @} + } // namespace lenses } // namespace lager diff --git a/lager/reader.hpp b/lager/reader.hpp index 3c3d2cdc..4b820edf 100644 --- a/lager/reader.hpp +++ b/lager/reader.hpp @@ -26,6 +26,9 @@ namespace lager { template class cursor_base; +//! @defgroup cursors +//! @{ + template struct reader_mixin { @@ -100,8 +103,6 @@ class reader_base /*! * Provides access to reading values of type `T`. - * Model of `Reader_value`. - * @see `Reader_value` */ template class reader : public reader_base> @@ -112,4 +113,6 @@ class reader : public reader_base> using base_t::base_t; }; +//! @} + } // namespace lager diff --git a/lager/sensor.hpp b/lager/sensor.hpp index 42602b10..7e79a4e8 100644 --- a/lager/sensor.hpp +++ b/lager/sensor.hpp @@ -56,6 +56,9 @@ auto make_sensor_node(SensorFnT&& fn) } // namespace detail +//! @defgroup cursors +//! @{ + template class sensor : public reader_base> { @@ -85,4 +88,6 @@ auto make_sensor(SensorFnT&& fn) return std::forward(fn); } +//! @} + } // namespace lager diff --git a/lager/state.hpp b/lager/state.hpp index 9c2dbdcc..b8976717 100644 --- a/lager/state.hpp +++ b/lager/state.hpp @@ -64,6 +64,9 @@ auto make_state_node(T&& value) } // namespace detail +//! @defgroup cursors +//! @{ + template class state : public cursor_base> { @@ -102,4 +105,6 @@ state make_state(T value, TagT) return value; } +//! @} + } // namespace lager diff --git a/lager/with.hpp b/lager/with.hpp index 84cf11ca..7038d018 100644 --- a/lager/with.hpp +++ b/lager/with.hpp @@ -41,6 +41,9 @@ struct cursor_mixin; template struct reader_mixin; +//! @defgroup cursors +//! @{ + /*! * Returns a transducer for updating the parent values via a up-node. It * processes the input with the function `updater`, passing to it a value or @@ -61,6 +64,8 @@ auto update(UpdateT&& updater) }; } +//! @} + namespace detail { template